[转帖]Redis性能之内部阻塞式操作及应对方法

redis,性能,内部,阻塞,操作,应对,方法 · 浏览次数 : 0

小编点评

**Redis阻塞点集合全量查询和聚合操作** **网络IO阻塞点** * 客户端:网络IO * 阻塞点:读取和写入键值对数据 * 解决方案:使用IO多路复用机制,避免主线程一直等待网络请求或请求到来的状态 **键值对增删改查阻塞点** * 客户端:键值对增删改查 * 阻塞点:操作键值对数据 * 解决方案:操作键值对数据时,使用异步执行的阻塞点异步子线程 **数据库操作阻塞点** * 客户端:数据库操作(例如生成RDB快照、记录AOF日志) * 阻塞点:进行数据库操作时,主线程会被阻塞 * 解决方案:使用异步执行的阻塞点异步子线程 **缓存清理阻塞点** * 客户端:清空数据库,频繁删除键值对 * 阻塞点:进行数据库清理操作时,主线程会被阻塞 * 解决方案:使用异步执行的阻塞点异步子线程 **切片集群实例交互阻塞点** * 客户端:向切片集群实例传输哈希槽信息 * 阻塞点:在多个实例之间传递哈希槽信息时,会阻塞主线程 * 解决方案:使用异步执行的阻塞点异步子线程 **其他阻塞点** * 异步执行的阻塞点异步子线程 * 主线程创建3个子线程来处理AOF日志写操作、键值对删除和文件关闭异步执行

正文


Redis的网络IO和键值对读写都是由主线程完成的。

Redis实例都有哪些阻塞点

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

和客户端交互的阻塞点

网络IO使用了IO多路复用机制,避免了主线程一直等待网络请求或请求到来的状态,所以网络IO不是阻塞点

键值对的增删改查是对外提供的主要功能,操作复杂度为O(N)的会阻塞Redis

集合的全量查询和聚合操作

Redis中涉及集合的操作复杂度通常为O(N),比如HGETALL、SMEMBERS,以及集合的聚合统计操作,求交,求并,求差集。

bigkey删除操作

  • 删除的本质是要释放键值对占用的内存空间,释放掉的内存块需要插入一个空闲的内存块的链表,以便后续的管理和再分配,这个过程需要耗费一定的时间,阻塞当前释放内存的应用程序
  • 释放大量内存的时候,必然会空闲内存块的链表的操作时间变长,造成Redis阻塞

不同元素、不同大小删除key时结果如下:
在这里插入图片描述
集合元素越大,删除时间越长,必定会阻塞Redis

清空数据库

频繁删除键值对是潜在的阻塞点,清空数据库(例如 FLUSHDB 和 FLUSHALL 操作)必然也是一个潜在的阻塞风险

磁盘交互的阻塞点

磁盘IO一般都是比较费时费力的。

Redis采用子进程的方式生成RDB快照、执行AOF日志重写,那么就不会去阻塞主线程了

Redis 记录AOF日志时,根据不同的写回策略对数据做落盘保存,若是同步写回的话,会阻塞主线程。

主从节点交互时的阻塞点

主从集群中,主库生成RDB文件,传输给从库,主库在复制过程中,创建和传输RDB文件都是子进程来完成的,不会阻塞主线程

  • 从库接收RDB文件后,需要FLUSHDB清空数据库,就会产生阻塞
  • 加载RDB的过程中,RDB文件越大,加载过程会越慢,这也是Redis的一个阻塞点

切片集群实例交互时的阻塞点

Redis部署切片集群时,每个Redis实例分配的哈希槽信息需要在不同的实例间进行传递,需要负载均衡或有实例增加的时候,数据会在不同的实例间进行渐进式的迁移,一般不会阻塞主线程。

Redis Cluster方案,同时正好迁移的是bigkey的话,因为采用的是同步迁移,所以就会造成主线程的阻塞

可以异步执行的阻塞点

如果一个操作能被异步执行,说明它不是Redis主线程的关键路径。

  • 集合的全量查询和聚合操作,读操作是典型的关键路径,不能异步
  • bigkey删除操作、清空数据库 非关键路径,可以异步
  • AOF日志同步写,也不需要返回给客户端结果,也可以异步执行
  • 从库加载RDB,属于关键路径,不能异步

异步的子线程

Redis会通过主线程创建3个子线程,分别负责AOF日志写操作、键值对删除、文件关闭异步执行。

主线程通过一个链表形式的任务队列和子线程进行交互,收到键值对删除和清空数据库操作时,主线程会把这个操作封装成一个任务,放入任务队列中,然后给客户端返回完成信息。

后台子进程从任务队列里读取任务,开始删除键值对,释放空间的过程就是异步删除,也叫惰性删除

当把AOF日期配成everysec后,主线程会把AOF写日志操作封装成一个任务放入任务队列,后台子线程读取,开始自己写入AOF日志。

在这里插入图片描述

Redis 4.0 提供了新的命令来删除操作

  • 键值对删除:当集合类型有大量元素需要删除时,用UNLINK命令
  • 清空数据库:可以在FLUSHDB和FLUSHALL命令后加上ASYNC选项,可以让后台异步子线程清空数据库

总结

  • 集合的全量查询和聚合操作可以使用SCAN命令,分批读取数据,在客户端做聚合计算
  • 从库加载RDB文件中,把主库的数据量控制在2-4GB,保证RDB能以较快速度加载

与[转帖]Redis性能之内部阻塞式操作及应对方法相似的内容:

[转帖]Redis性能之内部阻塞式操作及应对方法

文章目录 Redis实例都有哪些阻塞点和客户端交互的阻塞点集合的全量查询和聚合操作bigkey删除操作清空数据库 磁盘交互的阻塞点主从节点交互时的阻塞点切片集群实例交互时的阻塞点可以异步执行的阻塞点异步的子线程总结 Redis的网络IO和键值对读写都是由主线程完成的。 Redis实例都有哪些阻塞点

[转帖]Day742.Redis阻塞主线程的问题 -Redis 核心技术与实战

Redis阻塞主线程的问题 Hi,我是阿昌,今天学习记录的内容是Redis阻塞主线程的问题。 Redis 之所以被广泛应用,很重要的一个原因就是它支持高性能访问。 也正因为这样,我们必须要重视所有可能影响 Redis 性能的因素(例如命令操作、系统配置、关键机制、硬件配置等),不仅要知道具体的机制,

[转帖]Redis性能调优万字总结,面试必问!

https://zhuanlan.zhihu.com/p/541745804 于哥你好,最近面试挺多的,尤其是在问到java面试题,Redis被问的特别多,比如 Redis的内存模型? Redis的底层数据结构是怎么的? Redis的多线程模型 Redis的集群原理 Redis的雪崩,击穿,穿透怎么

[转帖]面试官:Redis 性能优化都有哪些方法?

https://cloud.tencent.com/developer/article/2168105?areaSource=104001.13&traceId=zcVNsKTUApF9rNJSkcCbB 前言 Redis作为高性能的内存数据库,在大数据量的情况下也会遇到性能瓶颈,日常开发中只有时刻

[转帖]面试官:Redis 性能优化都有哪些方法?

https://cloud.tencent.com/developer/article/2168105?areaSource=105001.13&traceId=iLuwwg5L5-kYlGSYRZNBH 前言 Redis作为高性能的内存数据库,在大数据量的情况下也会遇到性能瓶颈,日常开发中只有时刻

[转帖]面试官:Redis 性能优化都有哪些方法?

https://cloud.tencent.com/developer/article/2168105?areaSource=&traceId= 前言 Redis作为高性能的内存数据库,在大数据量的情况下也会遇到性能瓶颈,日常开发中只有时刻谨记优化铁则,才能使得Redis性能发挥到极致。 本文将会介

[转帖]浅谈redis采用不同内存分配器tcmalloc和jemalloc

http://www.kaotop.com/it/173669.html 我们知道Redis并没有自己实现内存池,没有在标准的系统内存分配器上再加上自己的东西。所以系统内存分配器的性能及碎片率会对Redis造成一些性能上的影响。 在Redis的 zmalloc.c 源码中,我们可以看到如下代码: ?

[转帖]KV数据库调研

https://zhuanlan.zhihu.com/p/499313638 Redis作为NoSQL领域的代表,拥有很高的读写性能,支持比较丰富的数据类型,但是Redis也存在一些缺陷。 l 内存数据库,容量有限,成本很高 l 主从复制模型,存在数据丢失的风险 l 自身备份代价很大 l 集群模式存

[转帖]5分钟学会这种更高效的Redis数据删除方式

https://ost.51cto.com/posts/12513 简述 我们知道,Del命令能删除数据,除此之外,数据在Redis中,还会以哪种方式被删除呢?在Redis内存满一定会返回OOM错误?Key到达过期时间就立即删除?删除大Key会影响性能吗?下面,咱们一起探讨。 同步和异步删除 1.D

[转帖]

https://cloud.tencent.com/developer/article/2168105?areaSource=104001.13&traceId=zcVNsKTUApF9rNJSkcCbB 前言 Redis作为高性能的内存数据库,在大数据量的情况下也会遇到性能瓶颈,日常开发中只有时刻