Redis开发最佳实践

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis开发最佳实践


缓存在我们日常开发中占据着举足轻重的地位,通过缓存组件可以让我们的系统有着多方位的提升空间。而Redis就一个代表性的缓存组件。正巧最近使用Redis比较频繁,所以打算通过文章记录一下在Redis开发中遇到的问题和一些开发规范。文章已发布在Github,将会持续保持更新,欢迎star和补充

Key的设计

易于管理

即能通过名称大概知道所涉及业务。通常我们会以service:characteristics来进行命名,如pubg_chat:uid:room_id的形式,这样可以尽可能避免冲突(当然,不同业务使用不同的Redis是更好的)

尽量简洁

Redis本质上是一个内存数据库,而内存的大小是远小于硬盘的。如果Key过大的话,会导致Redis所能存储的内容变少。所以在日常中推荐Key能够尽可能的简介明了,用缩写来代替完整的单词

避免特殊字符

如逗号、换行、空格和引号等转义字符都是不应该使用的

设置生命周期

  • Redis不应当成为一个永久存储的组件,为每一个Key都设置他的过期时间
  • 如果确实需要Redis永久存储某类内容,那么因当采用异步“续命”的方式来进行,而不应该在一开始就为其设置永久的生命周期,避免后续需要变更时带来的维护灾难

Value的使用

规避大Key!

  • Redis单线程的,它会在执行完一个命令后才会执行其他命令
  • 首先大Key在传输键值对时,会对网络造成压力(带宽问题),并且有的proxy会将大内容分片传输,进而再次增加了网络传输时间
  • 其次,如list、hash这类结构,如果使用O(n)的指令或者使用del命令,那么会造成严重的阻塞
  • 所以通常而言,string 类型控制在 10KB 以内,hash、list、set、zset 元素个数不要超过 5000
  • ps:通常可采用hash的方式分割大key

value的压缩

可考虑使用protobuf、MessagePack等方式进行序列化,这样一可以提升redis的利用率,二提高了序列化的效率,三是能提供value跨语言的能力

命令使用

避免频繁对string做append

可以考虑使用list进行替代

集合类操作

  • O(n)指令应注意。对于set,zset,list,hash等集合类,应注意O(n)命令对于性能的影响。通常应该避免直接使用O(n)指令,可用HSCAN,SSCAN,ZSCAN进行渐进操作,防止命令的阻塞
  • 渐进式删除。不应该直接使用del,而应该自己写脚本一点点的删除

禁用危险命令

keys、flushall、flushdb......这种不用多说,一来直接Redis就懵圈了,人也楞了

合理利用Pipeline模式

  • 在mget大量数据时,proxy会拆包和解包,会导致proxy层的压力增加,而pipeline模式会直接转发。所以在批量获取的情况下,pipeline的效率一般都会优于mget
  • 同时应该注意两点:
  • mget是原子操作,pipeline不是。所以业务上不可盲目采用
  • pipeline是可以发送不同命令的,当然使用lua也可以实现这一点

避免不必要的指令

如部分Redis Client会有TestOnBorrow之类的探测指令,在没有特殊要求的情况下应当避免此类指令,以减小redis负载和网络压力

对Lua应当做特殊要求

  • 所有key都应该由KEYS数组来传递
  • 所有value都应该由ARGS数组来传递
  • 所有key,必须在1个slot上

性能查询指令

  • slowlog get,查询慢命令
  • info commandstats,查询执行过的命令信息,包含用时和次数等
  • client list,查询引起阻塞的命令

客户端使用

避免混用实例

不同的业务线应该做到实例的拆分,避免混用导致的连锁问题:如key重合、命令阻塞等

使用连接池

每次使用都新建连接会有几个问题:

  • 造成redis的负担增加
  • 浪费网络资源
  • 影响执行效率
  • 难以维护

熔断

Redis本质也是一个“服务”,所以熔断机制不可少

鉴权

避免无关服务的滥用或导致数据出错

避免作为消息队列

Redis其实还能够支持消息队列的应用,但其读写效率是不及其他MQ如Kafka、RabbitMQ等。且由于其结构的设置,不太能够支撑MQ的一些主要特性,所以应当避免使用。

其他

淘汰策略

根据⾃⾝业务类型,选好maxmemory-policy(最⼤内存淘汰策略),设置好过期时间 默认策略是volatile-lru,即超过最⼤内存后,在过期键中使⽤lru算法进⾏key的剔除,保证不过期数据不被 删除,但是可能会出现OOM问题

  • allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出⾜够空间为⽌
  • allkeys-random:随机删除所有键,直到腾出⾜够空间为⽌。
  • volatile-random:随机删除过期键,直到腾出⾜够空间为⽌
  • volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略
  • noeviction:不会剔除任何数据,拒绝所有写⼊操作并返回客⼾端错误信息"(error) OOM command not allowed when used memory",此时Redis只响应读操作
  • 4.0后推出的allkey-lfu和volatile-lfu
  • 可以认为这是对于lru算法的进一步改进
  • allkey-lfu:从所有键中驱逐使用频率最少的键
  • volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键

不滥用Redis事务

Redis事务不像DB的事务这么“安全”,也不支持回滚,所以不应当过多的使用。因为这块我没怎么使用过,详见官方文档

参考资料




相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
存储 缓存 Java
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
|
6月前
|
存储 NoSQL 安全
Redis最佳实践
Redis键值设计 优雅的key结构 Redis的Key虽然可以自定义,但最好遵循下面的几个最佳实践约定: 遵循基本格式:[业务名称]:[数据名]:[id] 长度不超过44字节 不包含特殊字符 例如:我们的登录业务,保存用户信息,其key可以设计成如下格式: 这样设计的好处: 可读性强 避免key冲突 方便管理 更节省内存: key是string类型,(value)底层编码包含int、embstr和raw三种。 key是数值的情况下,使用int编码,把字符串直接当作一个数字去存储,较小存储空间 embstr在小于44字节使用,采用连续内存空间,内存占用更小。 当字节数大于44
62 0
|
7月前
|
存储 缓存 NoSQL
Java开发面试--Redis专区(二)
Java开发面试--Redis专区
138 0
|
9月前
|
消息中间件 缓存 NoSQL
手把手教你云相册项目简易开发 day1 Kafka+IDEA+Springboot+Redis+MySQL+libvips 简单运行和使用
手把手教你云相册项目简易开发 day1 Kafka+IDEA+Springboot+Redis+MySQL+libvips 简单运行和使用
137 0
|
2天前
|
缓存 NoSQL 安全
Redis 最佳实践 [后端必看]
Redis 最佳实践 [后端必看]
16 0
|
9天前
|
人工智能 前端开发 Java
Java语言开发的AI智慧导诊系统源码springboot+redis 3D互联网智导诊系统源码
智慧导诊解决盲目就诊问题,减轻分诊工作压力。降低挂错号比例,优化就诊流程,有效提高线上线下医疗机构接诊效率。可通过人体画像选择症状部位,了解对应病症信息和推荐就医科室。
151 10
|
15天前
|
NoSQL 关系型数据库 MySQL
开发者福音:用IDEA和Iedis2加速Redis开发与调试
开发者福音:用IDEA和Iedis2加速Redis开发与调试
32 0
开发者福音:用IDEA和Iedis2加速Redis开发与调试
|
16天前
|
运维 NoSQL 算法
Java开发-深入理解Redis Cluster的工作原理
综上所述,Redis Cluster通过数据分片、节点发现、主从复制、数据迁移、故障检测和客户端路由等机制,实现了一个分布式的、高可用的Redis解决方案。它允许数据分布在多个节点上,提供了自动故障转移和读写分离的功能,适用于需要大规模、高性能、高可用性的应用场景。
16 0
|
2月前
|
缓存 监控 NoSQL
|
7月前
|
JSON NoSQL Java
126.【Redis - 快速开发使用版】(二)
126.【Redis - 快速开发使用版】
53 1

热门文章

最新文章