Java技术栈
www.javastack.cn
关注阅读更多优质文章
本文作者:Kaito
出处:kaito-kidd.com/2020/07/04/redis-best-practices/
在上一篇文章:Redis为什么变慢了?
常见延迟问题定位与分析,主要分析了Redis常见的导致变慢的场景以及问题定位和分析,主要是由业务使用不合理和运维不当导致的。
我们在了解了导致Redis变慢的原因之后,针对性地优化,就可以让Redis稳定发挥出更高性能。
这篇文章我们就来总结一下,在使用Redis时的最佳实践方式,主要包含两个层面:业务层面、运维层面。
由于我之前写过很多UGC后端服务,在大量场景下用到了Redis,这个过程中也踩过很多坑,所以在使用过程中也总结了一套合理的使用方法。
后来做基础架构,开发Codis、Redis相关的中间件,在这个阶段关注领域从使用层面下沉到Redis的开发和运维,更多聚焦在Redis的内部实现和运维过程中产生的各种问题,在这块也积累了一些经验。
下面就针对这两块,分享一下我认为比较合理的Redis使用和运维方法,不一定最全面,也可能与你使用Redis的方法不同,但以下这些方法都是我在踩坑之后总结的实际经验,供你参考。关注公众号Java技术栈回复redis获取系列Redis教程。
业务层面主要是开发人员需要关注,也就是开发人员在写业务代码时,如何合理地使用Redis。开发人员需要对Redis有基本的了解,才能在合适的业务场景使用Redis,从而避免业务层面导致的延迟问题。
在开发过程中,业务层面的优化建议如下:
lazy-free
机制,释放大value时异步操作,不阻塞主线程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产生性能抖动db0
,不推荐使用多个db,使用多个db会增加Redis的负担,每次访问不同的db都需要执行SELECT
命令,如果业务线不同,建议拆分多个实例,还能提高单个实例的性能运维层面主要是DBA需要关注的,目的是合理规划Redis的部署和保障Redis的稳定运行,主要优化如下:
readonly
slowlog
阈值,推荐10毫秒,并对其进行监控,产生过多的慢日志需要及时报警repl-backlog
大小,适当调大repl-backlog
可以降低主从全量复制的概率client-output-buffer-limit
大小,对于写入量很大的实例,适当调大可以避免主从复制中断问题info
信息时,使用长连接,频繁的短连接也会影响Redis性能,Redis 的监控指标,这篇推荐看下expired_keys
、evicted_keys
、latest_fork_usec
指标,短时间内这些指标值突增可能会阻塞整个实例,引发性能问题以上就是我在使用Redis和开发Redis相关中间件时,总结出来Redis推荐的实践方法,以上提出的这些方面,都或多或少在实际使用中遇到过。
如果对上面的建议产生疑问,可以我之前写的这篇文章:Redis为什么变慢了?常见延迟问题定位与分析,里面详细描述了产生问题的原因。
可见,要想稳定发挥Redis的高性能,需要在各个方面做好工作,但凡某一个方面出现问题,必然会影响到Redis的性能,这对我们使用和运维提出了更高的要求。
如果你在使用Redis过程中,遇到更多的问题或者有更好的使用经验,可以留言一起探讨!