Redis 最佳实践!业务和运维层面优化

做者:Kaito
出处:kaito-kidd.com/2020/07/04/redis-best-practices/

这篇文章咱们就来总结一下,在使用Redis时的最佳实践方式,主要包含两个层面:业务层面、运维层面。redis

因为我以前写过不少UGC后端服务,在大量场景下用到了Redis,这个过程当中也踩过不少坑,因此在使用过程当中也总结了一套合理的使用方法。后端

后来作基础架构,开发Codis、Redis相关的中间件,在这个阶段关注领域从使用层面下沉到Redis的开发和运维,更多聚焦在Redis的内部实现和运维过程当中产生的各类问题,在这块也积累了一些经验。缓存

下面就针对这两块,分享一下我认为比较合理的Redis使用和运维方法,不必定最全面,也可能与你使用Redis的方法不一样,但如下这些方法都是我在踩坑以后总结的实际经验,供你参考。关注公众号Java技术栈回复redis获取系列Redis教程。网络

业务层面主要是开发人员须要关注,也就是开发人员在写业务代码时,如何合理地使用Redis。开发人员须要对Redis有基本的了解,才能在合适的业务场景使用Redis,从而避免业务层面致使的延迟问题。架构

在开发过程当中,业务层面的优化建议以下:app

  • key的长度尽可能要短,在数据量很是大时,过长的key名会占用更多的内存
  • 必定避免存储过大的数据(大value),过大的数据在分配内存和释放内存时耗时严重,会阻塞主线程
  • Redis 4.0以上建议开启lazy-free机制,释放大value时异步操做,不阻塞主线程
  • 建议设置过时时间,把Redis当作缓存使用,尤为在数量很大的时,不设置过时时间会致使内存的无限增加
  • 不使用复杂度太高的命令,例如SORT、SINTER、SINTERSTORE、ZUNIONSTORE、ZINTERSTORE,使用这些命令耗时较久,会阻塞主线程
  • 查询数据时,一次尽可能获取较少的数据,在不肯定容器元素个数的状况下,避免使用LRANGE key 0 -1,ZRANGE key 0 -1这类操做,应该设置具体查询的元素个数,推荐一次查询100个如下元素
  • 写入数据时,一次尽可能写入较少的数据,例如HSET key value1 value2 value3...,-控制一次写入元素的数量,推荐在100如下,大数据量分多个批次写入
  • 批量操做数据时,用MGET/MSET替换GET/SET、HMGET/MHSET替换HGET/HSET,减小请求来回的网络IO次数,下降延迟,对于没有批量操做的命令,推荐使用pipeline,一次性发送多个命令到服务端
  • 禁止使用KEYS命令,须要扫描实例时,建议使用SCAN,线上操做必定要控制扫描的频率,避免对Redis产生性能抖动
  • 避免某个时间点集中过时大量的key,集中过时时推荐增长一个随机时间,把过时时间打散,下降集中过时key时Redis的压力,避免阻塞主线程
  • 根据业务场景,选择合适的淘汰策略,一般随机过时要比LRU过时淘汰数据更快
  • 使用链接池访问Redis,并配置合理的链接池参数,避免短链接,TCP三次握手和四次挥手的耗时也很高
  • 只使用db0,不推荐使用多个db,使用多个db会增长Redis的负担,每次访问不一样的db都须要执行SELECT命令,若是业务线不一样,建议拆分多个实例,还能提升单个实例的性能
  • 读的请求量很大时,推荐使用读写分离,前提是能够容忍从节数据更新不及时的问题
  • 写请求量很大时,推荐使用集群,部署多个实例分摊写压力

运维层面运维

目的是合理规划Redis的部署和保障Redis的稳定运行,主要优化以下:异步

  • 不一样业务线部署不一样的实例,各自独立,避免混用,推荐不一样业务线使用不一样的机器,根据业务重要程度划分不一样的分组来部署,避免某一个业务线出现问题影响其余业务线
  • 保证机器有足够的CPU、内存、带宽、磁盘资源,防止负载太高影响Redis性能
  • 以master-slave集群方式部署实例,并分布在不一样机器上,避免单点,slave必须设置为readonly
  • master和slave节点所在机器,各自独立,不要交叉部署实例,一般备份工做会在slave上作,作备份时会消耗机器资源,交叉部署会影响到master的性能
  • 推荐部署哨兵节点增长可用性,节点数量至少3个,并分布在不一样机器上,实现故障自动故障转移
  • 提早作好容量规划,一台机器部署实例的内存上限,最好是机器内存的一半,主从全量同步时会占用最多额外一倍的内存空间,防止网络大面积故障引起全部master-slave的全量同步致使机器内存被吃光
  • 作好机器的CPU、内存、带宽、磁盘监控,在资源不足时及时报警处理,Redis使用Swap后性能急剧降低,网络带宽负载太高访问延迟明显增大,磁盘IO太高时开启AOF会拖慢Redis的性能
  • 设置最大链接数上限,防止过多的客户端链接致使服务负载太高
  • 单个实例的使用内存建议控制在20G如下,过大的实例会致使备份时间久、资源消耗多,主从全量同步数据时间阻塞时间更长
  • 设置合理的slowlog阈值,推荐10毫秒,并对其进行监控,产生过多的慢日志须要及时报警 设置合理的复制缓冲区repl-backlog大小,适当调大repl-backlog能够下降主从全量复制的几率
  • 设置合理的slave节点client-output-buffer-limit大小,对于写入量很大的实例,适当调大能够避免主从复制中断问题
  • 备份时推荐在slave节点上作,不影响master性能
  • 不开启AOF或开启AOF配置为每秒刷盘,避免磁盘IO消耗下降Redis性能
  • 当实例设置了内存上限,须要调大内存上限时,先调整slave再调整master,不然会致使主从节点数据不一致
  • 对Redis增长监控,监控采集info信息时,使用长链接,频繁的短链接也会影响Redis性能,redis性能监控指标,参考这个文章
  • 线上扫描整个实例数时,记得设置休眠时间,避免扫描时QPS突增对Redis产生性能抖动
  • 作好Redis的运行时监控,尤为是expired_keys、evicted_keys、latest_fork_usec指标,短期内这些指标值突增可能会阻塞整个实例,引起性能问题

以上就是我在使用Redis和开发Redis相关中间件时,总结出来Redis推荐的实践方法,以上提出的这些方面,都或多或少在实际使用中遇到过。性能

可见,要想稳定发挥Redis的高性能,须要在各个方面作好工做,但凡某一个方面出现问题,必然会影响到Redis的性能,这对咱们使用和运维提出了更高的要求。大数据

若是你在使用Redis过程当中,遇到更多的问题或者有更好的使用经验,能够留言一块儿探讨!

image

相关文章
相关标签/搜索