大厂Redis 性能优化的 13 条军规!收好了( 二 )


要避免 O(N) 命令对 Redis 造成的影响,可以从以下几个方面入手改造:

  • 决定禁止使用 keys 命令;
  • 避免一次查询所有的成员,要使用 scan 命令进行分批的,游标式的遍历;
  • 通过机制严格控制 Hash、Set、Sorted Set 等结构的数据大小;
  • 将排序、并集、交集等操作放在客户端执行,以减少 Redis 服务器运行压力;
  • 删除 (del) 一个大数据的时候,可能会需要很长时间,所以建议用异步删除的方式 unlink,它会启动一个新的线程来删除目标数据,而不阻塞 Redis 的主线程 。
5.使用 slowlog 优化耗时命令我们可以使用 slowlog 功能找出最耗时的 Redis 命令进行相关的优化,以提升 Redis 的运行速度,慢查询有两个重要的配置项:
  • slowlog-log-slower-than :用于设置慢查询的评定时间,也就是说超过此配置项的命令,将会被当成慢操作记录在慢查询日志中,它执行单位是微秒 (1 秒等于 1000000 微秒);
  • slowlog-max-len :用来配置慢查询日志的最大记录数 。
我们可以根据实际的业务情况进行相应的配置,其中慢日志是按照插入的顺序倒序存入慢查询日志中,我们可以使用 slowlog get n 来获取相关的慢查询日志,再找到这些慢查询对应的业务进行相关的优化 。
6.使用 Pipeline 批量操作数据Pipeline (管道技术) 是客户端提供的一种批处理技术,用于一次处理多个 Redis 命令,从而提高整个交互的性能 。
我们使用 Java 代码来测试一下 Pipeline 和普通操作的性能对比,Pipeline 的测试代码如下:
大厂Redis 性能优化的 13 条军规!收好了

文章插图
 
以上程序执行结果为:
执行耗时:297毫秒
普通的操作代码如下:
大厂Redis 性能优化的 13 条军规!收好了

文章插图
 
以上程序执行结果为:
执行耗时:17276毫秒
从以上的结果可以看出,管道的执行时间是 297 毫秒,而普通命令执行时间是 17276 毫秒,管道技术要比普通的执行大约快了 58 倍 。
7.避免大量数据同时失效Redis 过期键值删除使用的是贪心策略,它每秒会进行 10 次过期扫描,此配置可在 redis.conf 进行配置,默认值是 hz 10,Redis 会随机抽取 20 个值,删除这 20 个键中过期的键,如果过期 key 的比例超过 25%,重复执行此流程,如下图所示:
 
大厂Redis 性能优化的 13 条军规!收好了

文章插图
 
 
如果在大型系统中有大量缓存在同一时间同时过期,那么会导致 Redis 循环多次持续扫描删除过期字典,直到过期字典中过期键值被删除的比较稀疏为止,而在整个执行过程会导致 Redis 的读写出现明显的卡顿,卡顿的另一种原因是内存管理器需要频繁回收内存页,因此也会消耗一定的 CPU 。
为了避免这种卡顿现象的产生,我们需要预防大量的缓存在同一时刻一起过期,就简单的解决方案就是在过期时间的基础上添加一个指定范围的随机数 。
8.客户端使用优化在客户端的使用上我们除了要尽量使用 Pipeline 的技术外,还需要注意要尽量使用 Redis 连接池,而不是频繁创建销毁 Redis 连接,这样就可以减少网络传输次数和减少了非必要调用指令 。
9.限制 Redis 内存大小在 64 位操作系统中 Redis 的内存大小是没有限制的,也就是配置项 maxmemory <bytes> 是被注释掉的,这样就会导致在物理内存不足时,使用 swap 空间既交换空间,而当操心系统将 Redis 所用的内存分页移至 swap 空间时,将会阻塞 Redis 进程,导致 Redis 出现延迟,从而影响 Redis 的整体性能 。因此我们需要限制 Redis 的内存大小为一个固定的值,当 Redis 的运行到达此值时会触发内存淘汰策略,内存淘汰策略在 Redis 4.0 之后有 8 种:
  1. noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,Redis 默认内存淘汰策略;
  2. allkeys-lru:淘汰整个键值中最久未使用的键值;
  3. allkeys-random:随机淘汰任意键值;
  4. volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值;
  5. volatile-random:随机淘汰设置了过期时间的任意键值;
  6. volatile-ttl:优先淘汰更早过期的键值 。
在 Redis 4.0 版本中又新增了 2 种淘汰策略:
  1. volatile-lfu:淘汰所有设置了过期时间的键值中,最少使用的键值;
  2. allkeys-lfu:淘汰整个键值中最少使用的键值 。

  3. 推荐阅读