Redis最佳实践

1.键值设计

1.1 优雅的key设计

  • 遵循基本格式:【业务名称】:【数据名】:【id】
  • 长度不超过44字节(Redis版本4.0以后)
  • 不包含特殊符号

例如:注册业务,保存用户信息的key设计:register:user:12345

为什么使用长度不超过44字节?

因为key是string类型,底层编码包括int、embstr和raw三种,embstr在小于44字节使用,采用连续内存空间,内存占用更小

注意:如果redis版本低于4.0,则embstr在小于39个字节使用

1.2 BigKey

BigKey通常是Key单点大小和Key中成员的数量来综合判定,例如:

  • Key本身数据量过大:一个String类型的Key,它的值为5 MB
  • Key中的成员数过多:一个ZSET类型的Key,它的成员的数量为10,000个
  • Key中的成员的数据量过大:一个Hash类型的Key,虽然只有100个成员数量,但是这些成员数量的Value大小有100MB

推荐值:

  • 单个Key的value小于10KB
  • 对于集合类型的Key,建议元素数量小于1000

如果发现BigKey:

  • redis-cli --bigkeys:利用redis-cli提供的--bigkeys参数,可以遍历分析所有key,并返回key的整体统计信息和每个数据的Top1的big key
  • scan扫描:通过自己编程,利用scan扫描Redis中的所有key,利用strlen、hlen、llen、scard、zcard命令判断key的长度(此处不建议使用MEMORY USAGE)
  • 第三方工具:如使用Redis-Rdb-Tools分析RDB快照文件,全面分析内存使用情况
  • 网络监控:自定义工具,监控进出Redis的网络数据,超出预警值时主动告警

如何删除BigKey:

BigKey内存占用较多,删除这样的key 需要耗费很长的时间,导致Redis主线程阻塞,引起一系列的问题。

  • Redis 3.0以及以下版本:如果是集合类型,通过遍历BigKey的元素,逐个删除子元素,最后删除BigKey
  • Redis 4.0以后:Redis在4.0后提供了异步删除的命令:unlink

1.3 hash数据类型

如果有hash类型的Key,其中1000万对field和value,field是自增的id,这个key存在什么问题?如果优化?

可以拆分小的hash,将 id / 100作为key,将 id % 100 作为field,这样每100个元素作为一个Hash

2. 批处理优化

2.1 Pipeline

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

如果将大量的数据量依次执行插入数据将会是巨大的耗时

Redis中提供了很多Mxxx这样的命令,可以实现批量插入数据:

  • mset
  • hmset

不要在一次批处理中传输过多的命令,否则单次命令占用宽带过多,会导致网络阻塞

2.2 集群下的批处理:

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

串行命令:使用for循环遍历,依次执行每个命令,实现简单,耗时久

串行slot:在客户端计算每个key的slot,将slot一致分为一组,每组都利用Pipeline批处理,串行执行各组命令,耗时较短,实现复杂

并行slot:在客户端计算每个key的slot,将slot一致分为一组,每组都利用Pipeline批处理,并行执行各组命令,耗时非常短,实现复杂

hash_tag:将所有key设置相同的hash_tag,所有的key的slot一定相同,耗时非常短,实现简单,容易出现数据倾斜

3. 服务端优化

3.1 持久化配置

3.2 慢查询

 3.3 命令及安全配置

 3.4内存配置

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

  • 数据内存:是Redis的最主要的部分,存储Redis的键值信息,主要问题是BigKey问题,内存碎片问题。
  • 进程内存:Redis主进程本身运行需要占用一定的内存,如代码、常量池等,这部分的内存大约几兆,大多数生产环境中与Redis数据占用单点内存相比可以忽略。
  • 缓冲区内存:一般包括客户端缓冲区,AOF缓冲区,复制缓冲区等,客户端缓冲区又包括输入缓冲区和输出缓冲区,这部分内存占用波动较大,不当使用BigKey,可能会导致内存溢出。

Redis查看内存分配状态:

info memory:命令将仅返回与内存消耗相关的信息

memory status:

内存缓冲区的三种:

  • 复制缓冲区:主从复制的repl_backlog_buf,如果大小可能导致频繁的全量复制,影响性能,通过repl-backlog-size来设置,默认1mb
  • AOF缓冲区:AOF刷盘之前的缓冲区域,AOF执行rewrite的缓冲区,无法设置容器上限。
  • 客户端缓冲区:分为输入缓冲区和输出缓冲区,输入缓冲区最大1G且不能设置,输入缓冲区可以设置。

4. Redis集群最佳实践

在Redis的默认配置中,如果发现任意一个插槽不可用,整个集群都会停止对外服务。

为了保证高可用特性,建议将cluster-require-full-coverage配置设置为false

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

探索星辰大海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值