Redis五大影响性能原因(一):Redis实例内部的阻塞操作

思路:

1.建立一张redis主从切片集群图 ->->
2.以一个切片节点为中心考虑其与周围节点会造成阻塞的情况 ->->
3.对每一个阻塞情况考虑其是否是客户端需要的返回数据决定是否可以用异步子线程处理

一、Redis实例内部阻塞的四大原因

  • 客户端:网络 IO,键值对增删改查操作,数据库操作;
  • 磁盘:生成 RDB 快照,记录 AOF 日志,AOF 日志重写;
  • 主从节点:主库生成、传输 RDB 文件,从库接收 RDB 文件、清空数据库、加载 RDB 文件;
  • 切片集群实例:向其他实例传输哈希槽信息,数据迁移。

对应如下图所示:
请添加图片描述

下面解释一下为什么会造成阻塞:

一:与客户端交互
  • 复杂的sql语句,全量查询、聚合操作等(由主线程执行);
  • bigkey删除(Redis除了释放内存外,还会将空闲内存进行整理,涉及内存空间的移动);
  • 清空数据库。
二:与磁盘交互

AOF和RDB处理均有子进程执行,不会影响主线程,但是需要先fork子进程,当AOF和RDB操作频繁时,频繁的fork操作会影响主线程。

三:与从库交互

主库向从库传输RDB文件由子进程完成,主库主线程不受影响,主要会导致从库阻塞,从库接收RDB文件后要

  • 清空数据库导致bigkey删除操作阻塞;
  • 加载过大的RDB数据到内存阻塞。
四:切片集群交互(不是bigkey操作的话不容易导致阻塞
  • 彼此通过gossip协议传输哈希槽信息数据量小不易阻塞);
  • 增删实例时哈希槽重新分配渐进式重分配不易阻塞)。

二、如何解决Redis实例内部阻塞问题

  1. 对于客户端无关请求(客户端不需要Redis返回具体数据)—采用异步子线程执行机制(可以参考这个来思考redis的主线程、主线程的子线程、子进程等建立情况)
  • redis启动时默认会建立一个主线程以及三个异步子线程,只要是客户端对redis发送的请求不需要得到具体的返回数据,那么redis就采用一个异步子线程来处理该请求(可以想象成放入到一个消息队列中,主线程不去管它的执行情况),客户端直接收到一个redis返回的ok响应,比如lazy free惰性删除

请添加图片描述

  1. 对于客户端相关请求(客户端需要Redis返回具体数据)
  • A) 全量查询以及聚合操作:分批次返回数据到客户端,然后在客户端进行聚合操作
  • B) 从库加载RDB文件:实时控制主库的RDB文件不要过大,这样每次从库加载RDB文件就不会需要过多时间。

参考文章:

https://time.geekbang.org/column/article/285000

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值