redis堵塞了怎么办(上)

losetowin 发布于:2016-12-26 20:17 分类:技术  有 4422 人浏览,获得评论 0 条 标签: redis 

本文地址:http://www.dutycode.com/redis_duse_chuli_fangshi_shang.html
除非注明,文章均为 www.dutycode.com 原创,欢迎转载!转载请注明本文地址,谢谢。
背景描述:
硬件成本越来越低,所以在很多实际项目中,经常用到redis来作为缓存提高系统的响应速度,也有系统用它来做DB存储, redis很快,主要原因在于以下几点:
     1、纯内存操作,读写操作简单,线程占用时间短。
     2、单线程模型,避免了上下文切换带来的时间消耗。
     3、采用非堵塞IO。
但是依旧存在问题,因为是单线程模型,所以当某个请求耗时比较长的时候,整个redis就会被堵塞住,导致吞吐量下降。

该如何解决?
针对具体情况做处理,主要有以下两种情况导致堵塞。
     1、耗时长的命令导致的堵塞(本文)
     2、fork产生的堵塞。(下文)

耗时长的命令导致的堵塞:

keys/sort等命令
这类命令的使用频率不是很高,在生产环境下,一般不对外开放,在数据统计分析的时候可能会用到,对于此类的命令导致的堵塞可以采用分流的方式解决。
分流是指,将处理快的和处理慢的分开处理,防止处理慢的命令导致原本处理快的操作出于等待状态,导致堵塞。具体实施中可以采用主从的方式,处理快的操作全部交由主库操作,处理慢的操作比如keys/sort命令交由从库处理。这样keys操作虽然慢,但因为是在从库上,而且一般情况下这种命令一般用于线下的数据分析和统计用,慢也就慢了,没有影响到线上服务就可以。

325A530B-ED3C-47F4-90D1-62CB7CF228F0.png
smembers等命令

与keys命令不同的地方在于,smembers此类的命令可能在生产环境中使用的比较多,所以分流的方式虽然能保证响应时间快的命令在主库上不堵塞,但却解决不了smembers等命令在从库上响应时间长导致的从库的堵塞。

一般的解决办法有:
     1、控制集合元素数量,限制每个key下对应的集合的元素数量,建议在500以下(数据参考于网络,未做实际测试)
     2、分散数据,拆分Key值,比如之前集合内容为一年的数据,可以拆分为12月份,每个月份一个key值。查询时可放置到本地做数据处理。(BTW:一般情况下,查询当月的数据的频率比查询整年的数据频率高)
          类似的,可根据实际场景,使用uid的方式来分割key。
     3、如果使用场景上是随机选择的话,可以使用SRANDMEMBER代替。

类似的命令还有LRANGE/ZRANGE等,不过这两个命令的好处在于可以指定查询大小,性能上可控。但如果是查询全部的话,可以考虑上面的方式。

注:smembers : 返回集合key下的所有成员,时间复杂度O(N) N是集合的基数

save命令
SAVE命令执行一个同步保存操作,将当前 Redis 实例的所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。
一般来说,在生产环境很少执行SAVE操作,因为它会阻塞所有客户端,保存数据库的任务通常由 BGSAVE 命令异步地执行。然而,如果负责保存数据的后台子进程不幸出现问题时, SAVE 可以作为保存数据的最后手段来使用。
实际生产环境中,如果真的一定要做save操作,可以考虑在从库上采用save,主库不做此类操作,保证主库正常提供线上服务。








版权所有:《攀爬蜗牛》 => 《redis堵塞了怎么办(上)
本文地址:https://www.dutycode.com/redis_duse_chuli_fangshi_shang.html
除非注明,文章均为 《攀爬蜗牛》 原创,欢迎转载!转载请注明本文地址,谢谢。