Redis性能调优

Posted by YaPi on April 13, 2018

性能调优

尽管Redis是一个非常快速的内存数据存储媒介,也并不代表Redis不会产生性能问题。Redis采用单线程模型,所有的命令都是由一个线程串行执行的,所以当某个命令执行耗时较长时,会拖慢其后的所有命令,这使得Redis对每个任务的执行效率更加敏感。

  • 性能优化
    1. 确保没有让Redis执行耗时长的命令
    1. 不要把List当做列表使用,仅当做队列来使用(list中在指定位置插入等操作是 O(N)时间复杂度的)
    2. 通过机制严格控制Hash、Set、Sorted Set的大小 (HGETALL/HKEYS/HVALS等命令如果太大很耗时)
    3. 可能的话,将排序、并集、交集等操作放在客户端执行(使用SUNION对两个Set执行Union操作,或使用SORT对List/Set执行排序操作是O(N) )
    4. 绝对禁止使用KEYS命令
    5. 避免一次性遍历集合类型的所有成员,而应使用SCAN类的命令进行分批的,游标式的遍历
      1. 使用pipelining将连续的命令组合执行
      2. 如果运行在虚拟机中,会有天然的延迟,可以通过./redis-cli –intrinsic-latency 100命令查看固有延迟。同时如果对Redis的性能有较高要求的话,应尽可能在物理机上直接部署Redis。
      3. 检查数据持久化策略
    6. AOF + fsync always的设置虽然能够绝对确保数据安全,但每个操作都会触发一次fsync,会对Redis的性能有比较明显的影响
    7. AOF + fsync every second是比较好的折中方案,每秒fsync一次
    8. AOF + fsync never会提供AOF持久化方案下的最优性能 (OS)自己决定flush时机
    9. 使用RDB持久化通常会提供比使用AOF更高的性能,但需要注意RDB的策略配置
    10. 每一次RDB快照和AOF Rewrite都需要Redis主进程进行fork操作。fork操作本身可能会产生较高的耗时,与CPU和Redis占用的内存大小有关。根据具体的情况合理配置RDB快照和AOF Rewrite时机,避免过于频繁的fork带来的延迟(Redis在fork子进程时需要将内存分页表拷贝至子进程,以占用了24GB内存的Redis实例为例,共需要拷贝24GB / 4kB * 8 = 48MB的数据。在使用单Xeon 2.27Ghz的物理机上,这一fork操作耗时216ms。)
      1. 考虑引入读写分离机制
    11. Redis的主从复制能力可以实现一主多从的多节点架构,在这一架构下,主节点接收所有写请求,并将数据同步给多个从节点。 在这一基础上,我们可以让从节点提供对实时性要求不高的读请求服务,以减小主节点的压力。 尤其是针对一些使用了长耗时命令的统计类任务,完全可以指定在一个或多个从节点上执行,避免这些长耗时命令影响其他请求的响应。
      1. 尽可能使用长连接或连接池,避免频繁创建销毁连接
      2. 当同一秒内有大量key过期时,也会引发Redis的延迟。在使用时应尽量将key的失效时间错开

原文 (https://www.jianshu.com/p/2f14bc570563)