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

这篇文章咱们就来总结一下,在应用Redis时的最佳实际形式,次要蕴含两个层面:业务层面、运维层面。

因为我之前写过很多UGC后端服务,在大量场景下用到了Redis,这个过程中也踩过很多坑,所以在应用过程中也总结了一套正当的应用办法。

起初做基础架构,开发Codis、Redis相干的中间件,在这个阶段关注畛域从应用层面下沉到Redis的开发和运维,更多聚焦在Redis的外部实现和运维过程中产生的各种问题,在这块也积攒了一些教训。

上面就针对这两块,分享一下我认为比拟正当的Redis应用和运维办法,不肯定最全面,也可能与你应用Redis的办法不同,但以下这些办法都是我在踩坑之后总结的理论教训,供你参考。关注公众号Java技术栈回复redis获取系列Redis教程。

业务层面次要是开发人员须要关注,也就是开发人员在写业务代码时,如何正当地应用Redis。开发人员须要对Redis有根本的理解,能力在适合的业务场景应用Redis,从而防止业务层面导致的提早问题。

在开发过程中,业务层面的优化倡议如下:

  • 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过程中,遇到更多的问题或者有更好的应用教训,能够留言一起探讨!