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

栏目: IT技术 · 发布时间: 6年前

内容简介:在上一篇文章:我们在了解了导致Redis变慢的原因之后,针对性地优化,就可以让Redis稳定发挥出更高性能。这篇文章我们就来总结一下,在使用Redis时的最佳实践方式,主要包含两个层面:

在上一篇文章: Redis为什么变慢了?常见延迟问题定位与分析 ,主要分析了 Redis 常见的导致变慢的场景以及问题定位和分析,主要是由业务使用不合理和运维不当导致的。

我们在了解了导致Redis变慢的原因之后,针对性地优化,就可以让Redis稳定发挥出更高性能。

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

由于我之前写过很多UGC后端服务,在大量场景下用到了Redis,这个过程中也踩过很多坑,所以在使用过程中也总结了一套合理的使用方法。

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

下面就针对这两块,分享一下我认为比较合理的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 命令,如果业务线不同,建议拆分多个实例,还能提高单个实例的性能
  • 读的请求量很大时,推荐使用读写分离,前提是可以容忍从节数据更新不及时的问题
  • 写请求量很大时,推荐使用集群,部署多个实例分摊写压力

运维层面

运维层面主要是DBA需要关注的,目的是合理规划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性能
  • 线上扫描整个实例数时,记得设置休眠时间,避免扫描时QPS突增对Redis产生性能抖动
  • 做好Redis的运行时监控,尤其是 expired_keys 、 evicted_keys 、 latest_fork_usec 指标,短时间内这些指标值突增可能会阻塞整个实例,引发性能问题

总结

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

如果对上面的建议产生疑问,可以我之前写的这篇文章: Redis为什么变慢了?常见延迟问题定位与分析 ,里面详细描述了产生问题的原因。

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

如果你在使用Redis过程中,遇到更多的问题或者有更好的使用经验,可以留言一起探讨!


以上所述就是小编给大家介绍的《Redis最佳实践:业务层面和运维层面优化》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

Growth Hacker Marketing

Growth Hacker Marketing

Ryan Holiday / Portfolio / 2013-9-3 / USD 10.31

Dropbox, Facebook, AirBnb, Twitter. A new generation of multibillion dollar brands built without spending a dime on “traditional marketing.” No press releases, no PR firms, and no billboards in Times ......一起来看看 《Growth Hacker Marketing》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具