Redis学习7 Redis最佳实践

焦がせ不死なる絆

Redis最佳实践

Redis键值设计

设计优雅的Key

Redis的Key虽然可以自定义,但最好遵循下面的几个最佳实践约定:

遵循基本格式:[业务名称]:[数据名]:[id],例如之前设计的登录用户信息login:user:10
长度不超过44字节
不包含特殊字符

这样设计的优点:

可读性强
避免key冲突
方便管理
更节省内存:key是string类型,底层编码包含intembstrraw三种。embstr在小于44字节使用,采用连续内存空间,内存占用更小(和Redis版本有关)

避免BigKey

BigKey的情况:

Key本身的数据量过大:一个String类型的Key,它的值为5MB。
Key中的成员数过多:一个ZSET类型的Key,它的成员数量为10,000个。
Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1,000个但这些成员的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,利用strlenhlen等命令判断key的长度(此处不建议使用MEMORY USAGE)
第三方工具:利用第三方工具,如Redis-Rdb-Tools分析RDB快照文件,全面分析内存使用情况
网络监控:自定义工具,监控进出Redis的网络数据,超出预警值时主动告警

BigKey内存占用较多,即便时删除这样的key也需要耗费很长时间,导致Redis主线程阻塞,引发一系列问题。删除BigKey方式如下:

Redis3.0及以下版本:如果是集合类型,则遍历BigKey的元素,先逐个删除子元素,最后删除BigKey
Redis4.0以后:Redis在4.0后提供了异步删除的命令:unlink

恰当的数据结构

对于Value而言:

要选择合适的数据结构(JSON,Set,Hash等)

选择JSON,优点是实现简单粗暴,缺点是数据耦合、不够灵活
选择字段打散,优点是可以访问任意字段,缺点是占用空间大、无法做统一管理
选择Hash,优点是底层空间占用小、可以灵活访问任意字段,缺点是实现复杂

Hash结构的entry数量不超过1000
要设置合理的超时时间

批处理优化

单次命令的响应时间=1次往返的网络传输耗时+1次Redis执行命令耗时
image

N次命令依次执行的响应时间=N次往返的网络传输耗时+N次Redis执行命令耗时
image

N次命令批量执行的响应时间=1次往返的网络传输耗时+N次Redis执行命令耗时
image

批处理的具体命令有MSETpipeline

Redis集群的批处理优化

MSETpipeline这样的批处理需要在一次请求中携带多条命令,而此时如果Redis是一个集群,那批处理命令的多个key必须落在一个插槽中,否则就会导致执行失败。
image

Redis服务端优化

Redis持久化配置

Redis的持久化虽然可以保证数据安全,但也会带来很多额外的开销,因此持久化请遵循下列建议:

①用来做缓存的Redis实例尽量不要开启持久化功能
②建议关闭RDB持久化功能,使用AOF持久化
③利用脚本定期在slave节点做RDB,实现数据备份
④设置合理的rewrite阈值,避免频繁的bgrewrite
⑤配置no-appendfsync-on-rewrite=yes,禁止在rewrite期间做aof,避免因AOF引起的阻塞

部署有关建议:

①Redis实例的物理机要预留足够内存,应对forkrewrite
②单个Redis实例内存上限不要太大,例如4G8G。可以加快fork的速度、减少主从同步、数据迁移压力
③不要与CPU密集型应用部署在一起
④不要与高硬盘负载应用一起部署。例如:数据库、消息队列

Redis慢查询

慢查询:在Redis执行时耗时超过某个阈值的命令,称为慢查询。慢查询可能会导致Redis阻塞从而引发故障

慢查询的阈值可以通过配置slowlog-log-slower-than指定。slowlog-log-slower-than是慢查询阈值,单位是微秒。默认是10000,建议1000

慢查询会被放入慢查询日志中,日志的长度有上限,可以通过配置slowlog-max-len指定。slowlog-max-len是慢查询日志(本质是一个队列)的长度。默认是128,建议1000

查看慢查询日志

-- 查询慢查询日志长度
SLOWLOG len

-- 读取n条慢查询日志
SLOWGET get [n]

-- 清空慢查询日志列表
SLOWGET reset 

Redis服务器优化

命令和安全配置

漏洞出现的核心的原因有以下几点:

Redis未设置密码
利用了Redis的config set命令动态修改Redis配置
使用了Root账号权限启动Redis

为了避免这样的漏洞,这里给出一些建议:

Redis一定要设置密码
禁止线上使用下面命令:keysflushallflushdbconfig set等命令。可以利用rename-command禁用。
bind:限制网卡,禁止外网网卡访问
开启防火墙
不要使用Root账户启动Redis
尽量不是有默认的端口

内存配置

当Redis内存不足时,可能导致Key频繁被删除、响应时间变长、QPS不稳定等问题。当内存使用率达到90%以上时就需要我们警惕,并快速定位到内存占用的原因。

Redis内存占用分为以下三类,其中最容易出问题的是数据内存缓冲区内存
image

Redis提供了一些命令用于查看Redis内存分配状态

info memory

memory xxxx

image
image

内存缓冲区常见的有三种:

复制缓冲区:主从复制的repLbacklog_buf,如果太小可能导致频繁的全量复制,影响性能。通过repl-backlog-size来设置,默认1mb,一般不会存在波动
AOF缓冲区:AOF刷盘之前的缓存区域,AOF执行rewrite的缓冲区。无法设置容量上限,但是AOF速度很快,一般不会导致问题
客户端缓冲区:分为输入缓冲区和输出缓冲区,输入缓冲区最大1G且不能设置,输出缓冲区可以设置。

输出缓冲区设置命令

client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

class表示客户端类型,具体如下:

normal:普通客户端
replica:主从复制客户端
pubsub:PubSub客户端

hard limit表示缓冲区上限,缓冲区上限在超过hard limit后断开客户端
soft limit也是缓冲区上限,在超过soft limit并且持续了soft seconds秒后断开客户端

默认情况下,normal类型的客户端是没有上限的。相应的应对手段如下:

拦截手段:自定义设置上限
预防手段:①尽可能出现BigKey ②适当提高Redis物理机带宽

使用如下命令查看客户端信息以定位客户端故障:

# 用于提供当前 Redis 实例中客户端连接的‌整体统计摘要‌
info clients
# 列出‌每一个‌连接到 Redis 服务器的客户端的详细信息
client list

image

集群最佳实践

集群完整性

‌Redis集群中的插槽(Slot)是数据分片的基本单位,共16384个‌,用于实现数据的分布式存储、负载均衡和集群的动态扩缩容。在Redis的默认配置中,如果发现任意一个插槽不可用,则整个集群都会停止对外服务。

为了保证高可用特性,这里建议将cluster-require-full-coverage配置为nocluster-require-full-coverage表示当集群中出现部分哈希槽(Slot)不可用时,整个集群是否继续对外提供服务‌。

‌设置为yes‌:安全保守。任一槽位缺失导致整个集群停机。适合强一致性场景,例如金融和交易系统。
‌设置为no‌:激进可用。任一槽位缺失导致仅该槽位数据不可用,其余正常。适合高可用、缓存场景,例如会话存储、缓存层,日志以及一般互联网业务。
除非有极强的数据一致性要求,否则‌推荐设置为no‌,并配合完善的客户端容错机制和监控体系,以换取更高的服务可用性。

集群带宽

Redis分片集群不存在哨兵节点。集群节点之间会不断的互相Ping来确定集群中其它节点的状态从而保证安全。每次Ping携带的信息至少包括:

插槽信息
集群状态信息。

集群中节点越多,集群状态信息数据量也越大,10个节点的相关信息可能达到1kb,此时每次集群互通需要的带宽会非常高。

解决途径:

①避免大集群,集群节点数不要太多,最好少于1000,如果业务庞大,则建立多个集群。
②避免在单个物理机中运行太多Redis实例
③配置合适的cluster-node-timeout

集群虽然具备高可用特性,能实现自动故障恢复,但是如果使用不当,也会存在一些问题:

集群完整性问题
集群带宽问题
数据倾斜问题
客户端性能问题
命令的集群兼容性问题
lua和事务问题

注意:单体Redis(主从Redis)已经能达到万级别的QPS,并且也具备很强的高可用特性。如果主从能满足业务需求的情况下,尽量不搭建Redis集群

posted @ 2026-05-10 16:54  tcswuzb  阅读(30)  评论(0)    收藏  举报