Redis学习笔记-避免Redis单线程阻塞

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
日志服务 SLS,月写入数据量 50GB 1个月
简介: Redis学习笔记-避免Redis单线程阻塞

我们都知道 Redis 中的增删改查操作使用的是单线程模型(对于读写操作,Redis 6.0也是单线程),既然 Redis 是单线程就需要注意其潜在阻塞点,这篇文章学习一下 Redis 有哪些可能造成单线程阻塞的原因,这样可以提前避免性能问题。

1.笔记图

2.影响 Redis 性能的因素


  • 内部阻塞操作
  • CPU 内核和 NUMA 架构
  • Redis 关键系统配置
  • Redis 内存碎片
  • Redis 缓冲区

3.和 Redis 实例的几种交互方式

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

4.Redis 潜在阻塞点

  • 和客户端交互时的阻塞点
  • 第一个阻塞点:集合全量查询和聚合操作,如 HGETALLSMEMBERS,其原因是一次性操作数据量大的聚合操作会阻塞 Redis 的主线程,导致其他操作无法进行

  • 第二个阻塞点:删除占用内存较大的键值对,如del key(删除bigkey),其原因是删除元素操作时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配,若一次性释放大量的内存,会导致空闲内存块链表操作时间增加,阻塞 Redis 主线程
  • 第三个阻塞点:清空数据,当删除所有键值对,需要释放内存空间,这个过程会阻塞 Redis 主线程
  • 和磁盘交互时的阻塞点AOF 日志同步写,其原因是 AOF 日志采用同步写回策略时,若有大量写入会阻塞 Redis 主线程(而生成 RDB 快照采用的是子进程不会阻塞 Redis 主线程)
  • 主从节点交互时的阻塞点:从库在第一次全量同步的时候需要清空当前所有数据,从库同步主库的 RDB 快照文件,清空数据删除所有键值对,需要释放内存空间,这个过程会阻塞 Redis 主线程,加载的主库 RDB 快照文件越大,从库 Redis 主线程阻塞时间越长
  • 切片集群实例交互时的阻塞点Redis Cluster 集群中迁移 bigkey,如果使用了 Redis Cluster 方案,且同时正好迁移的是 bigkey 的话,就会造成主线程的阻塞

5.潜在阻塞点优化(异步操作)

5.1 关键路径上的操作

       客户端把请求发送给 Redis 后,等着 Redis 返回数据结果的操作,不适合使用异步操作

  • 操作 A 并不用给客户端返回具体的数据,主线程可以把它交给后台子线程来完成,可以使用异步操作
  • 操作 B 需要把结果返回给客户端,它就是关键路径上的操作,不适合使用异步操作
  • 读操作:典型的关键路径操作,因为客户端发送了读操作之后,就会等待读取的数据返回,它不适合使用异步操作
  • 从库加载 RDB 文件:从库要想对客户端提供数据存取服务,就必须把 RDB 文件加载完成,必须让从库的主线程来执行

5.2 非关键路径上的操作

  • 删除元素:删除操作并不需要给客户端返回具体的数据结果,所以不算是关键路径操作,可以使用异步操作,若要异步删除键值对,可使用 UNLINK 命令
  • 清空数据操作:清空数据不需要返回给客户端结果,可以使用异步操作
  • AOF日志同步写回策略:它并不会返回具体的数据结果,可以使用异步操作

6.异步子线程机制

  • Redis 主线启动后,会使用操作系统提供的 pthread_create 函数创建 3 个子线程,分别负责 AOF 日志写操作、键值对删除、文件关闭的异步执行
  • 主线程通过一个链表形式的任务队列和子线程进行交互

  • 键值对删除:若要异步删除键值对,可使用 UNLINK 命令
  • 清空数据库:可以在 FLUSHDB FLUSHALL 命令后加上 ASYNC 选项:
FLUSHDB ASYNC
FLUSHDB ASYNC


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6月前
|
存储 缓存 NoSQL
Redis单线程已经很快了6.0引入多线程
Redis单线程已经很快了6.0引入多线程
58 3
|
6月前
|
NoSQL Redis 缓存
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?
【5月更文挑战第17天】Redis常被称为单线程,但实际上其在处理命令时采用单线程,但在6.0后IO变为多线程。持久化和数据同步等任务由额外线程处理,因此严格来说Redis是多线程的。面试时需理解Redis的IO模型,如epoll和Reactor模式,以及其内存操作带来的高性能。Redis使用epoll进行高效文件描述符管理,实现高性能的网络IO。在讨论Redis与Memcached的线程模型差异时,应强调Redis的单线程模型如何通过内存操作和高效IO实现高性能。
92 7
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?
|
6月前
|
NoSQL 网络协议 Linux
Redis单线程源码深入解析
Redis单线程源码深入解析
|
5月前
|
NoSQL Redis
Redis的单线程和高性能
Redis 的单线程主要是指 Redis 的网络 I0 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。 但Redis 的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。
28 0
|
6月前
|
NoSQL 网络协议 关系型数据库
redis-学习笔记(redis 单线程模型)
redis-学习笔记(redis 单线程模型)
55 3
|
6月前
|
缓存 NoSQL Redis
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?--epoll调用和中断
【5月更文挑战第18天】`epoll`包含红黑树和就绪列表,用于高效管理文件描述符。关键系统调用有3个:`epoll_create()`创建epoll结构,`epoll_ctl()`添加/删除/修改文件描述符,`epoll_wait()`获取就绪文件描述符。`epoll_wait()`可设置超时时间(-1阻塞,0立即返回,正数等待指定时间)。当文件描述符满足条件(如数据到达)时,通过中断机制(如网卡或时钟中断)更新就绪列表,唤醒等待的进程。
75 6
|
6月前
|
NoSQL 关系型数据库 MySQL
Redis -- 单线程模型
Redis -- 单线程模型
68 1
|
6月前
|
缓存 NoSQL 中间件
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?epoll、poll和select + Reactor模式
【5月更文挑战第19天】`epoll`、`poll`和`select`是Linux下多路复用IO的三种方式。`select`需要主动调用检查文件描述符,而`epoll`能实现回调,即使不调用`epoll_wait`也能处理就绪事件。`poll`与`select`类似,但支持更多文件描述符。面试时,重点讲解`epoll`的高效性和`Reactor`模式,该模式包括一个分发器和多个处理器,用于处理连接和读写事件。Redis采用单线程模型结合`epoll`的Reactor模式,确保高性能。在Redis 6.0后引入多线程,但基本原理保持不变。
65 2
|
6月前
|
存储 缓存 NoSQL
为什么Redis使用单线程 性能会优于多线程?
在计算机领域,性能一直都是一个关键的话题。无论是应用开发还是系统优化,我们都需要关注如何在有限的资源下,实现最大程度的性能提升。Redis,作为一款高性能的开源内存数据库,因其出色的单线程性能而备受瞩目。那么,为什么Redis使用单线程性能会优于多线程呢?
72 1
|
6月前
|
缓存 NoSQL Redis
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?-- Redis多线程
【5月更文挑战第21天】Redis启用多线程后,主线程负责接收事件和命令执行,IO线程处理读写数据。请求处理流程中,主线程接收客户端请求,IO线程读取并解析命令,主线程执行后写回响应。业界普遍认为,除非必要,否则不建议启用多线程模式,因单线程性能已能满足多数需求。公司实际场景中,启用多线程使QPS提升约50%,或选择使用Redis Cluster以提升性能和可用性。
54 0