Redis最佳实践
1.Redis键值设计
1.1优雅的Key结构
Redis的Key虽然可以自定义,但是最好遵循下面的几个最佳实践约定:
- 遵循基本格式:[业务名称]:[数据名称]:[id]
- 长度不超过44字节(String的
embstr
编码,申请内存时只需要调用一次内存分配函数,效率更高,因为Redis中内存是统一jemalloc
控制分配的,通常是是2、4、8、16、32、64等,64-16-3-1=44,其中16代表redisObject的长度,3表示sdshdr8的头部长度,1表示字符数组中末尾的\0
标识符)
- 不包含特殊字符(防止出现意外的Bug)
这么做Key的可读性强,方便管理,也能有效避免Key冲突问题。
1.2拒绝BigKey
什么是BigKey
BigKey通常以Key的大小和Key中成员的数量来总和判定:
- Key本身的数据量过大:一个String类型的Key,它的值为5MB
- Key中的成员数过多:一个ZSet类型的Key,它的成员数量为10000个
- Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1000个,但是这些成员的Value总大小为100MB
推荐值:
- 单个Key的Value大小小于10KB
- 对于集合类型的Key,建议元素数量小于1000
BigKey的危害
- 网络阻塞
对于BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例乃至所在物理机变慢
- 数据倾斜
BigKey所在的Redis实例内存使用率远高于其他实例,无法使数据分片的内存资源达到均衡
- Redis阻塞
对于元素过多的Hash、List、ZSet等做运算耗时较久,使得处理命令的主线程阻塞
- CPU压力
对BigKey的数据序列化与反序列化会导致CPU的使用率飙高,影响Redis实例和本机其他应用
如何发现BigKey
- redis-cli –bigkeys
利用redis-cli提供的--bigkeys
参数,可以遍历分析所有Key,并返回Key的整体统计信息与每个数据的Top1的bigkey
- scan扫描
自己编程,利用scan
扫描Redis中的所有Key(千万不能使用keys *命令),利用strlen、hlen等命令判断key的长度(此处不建议使用MEMORY USAGE)
1 | final static int STR_MAX_LEN = 10 * 1024; |
- 第三方工具
利用第三方工具,如Redis-Rdb-Tools
工具分析RDB快照文件,全面分析内存使用情况
- 网络监控
自定义工具,监控进出Redis的网络数据,超出预警值时主动告警
如何删除BigKey
BigKey内存占用较多,删除这样的Key需要耗费很长时间,导致Redis主线程阻塞
,引发一系列问题。
- Redis3.0及以下版本
如果是集合类型,则遍历BigKey的元素,先逐个删除子元素,最后删除BigKey
- Redis4.0及以后版本
Redis在4.0以后提供了异步删除的命令:unlink
1.3恰当的数据类型
Key的最佳实践:
固定格式:[业务名称]:[数据名称]:[id]
足够简短:不超过44字节
不包含特殊字符
Value的最佳实践:
- 合理的拆分数据,拒绝BigKey
- 选择合适的数据结构
- Hash结构的entry数量不要超过512
- 设置合理的超时时间
2.批处理优化
2.1Pipeline
2.2集群下的批处理
3.服务端优化
3.1持久化配置
Redis的持久化虽然可以保证数据的安全性,但也会带来很多额外的开销,因此持久化请遵循下列建议:
- 用来作为缓存的Redis实例尽量不要开启持久化功能(安全性较高的业务如分布式锁、库存、流水等放在独立Redis实例中并开启持久化)
- 建议关闭RDB持久化功能,使用AOF持久化,利用脚本定期在Slave节点做RDB,实现数据备份
- 设置合理的rewrite阈值即
auto-aof-rewrite-min-size
,避免频繁的bgrewrite - 配置
no-appendfsync-on-rewrite=yes
,禁止在rewrite期间做AOF,避免因AOF引起的阻塞,但可能存在数据丢失的风险
部署有关建议:
- Redis实例的物理机需要预留足够内存,应对fork和rewrite
- 单个Redis实例内存上限不要太大,例如4G或8G,可以加快fork的速度、减少主从同步、数据迁移的压力
- 不要和高硬盘负载应用一起部署,如数据库、消息队列
3.2慢查询
慢查询的阈值可以通过配置指定:
slowlog-log-slower-than
:慢查询阈值,单位是微妙,默认是10000slowlog-max-len
:慢查询日志的长度,默认是128,建议增大为1000
查看慢查询日志列表:
slowlog len
:查询慢查询日志长度slowlog get[n]
:读取n条慢查询日志slowlog reset
:清空慢查询列表
3.3命令及安全配置
Redis会绑定在0.0.0.0:6379,这样将会使得Redis服务暴露到公网上,而Redis如果没有做身份认证,则会出现严重的安全漏洞(SSH免密登录漏洞)。
为了避免这样的漏洞,这里给出一些建议:
- Redis一定要设置密码
- 禁止线上使用下面命令:
keys
、flushall
、flushdb
、config set
等命令,可以利用rename-command
禁用
bind
限制网卡,禁止外网网卡访问
- 开启防火墙,不要使用root账户启动Redis
- 尽量不要使用默认的6379端口号