前言

俗话说得好,系统慢不用怕,没有什么是加一层缓存解决不了的,一层不行的话,就加两层。

但加缓存也并不是一劳永逸的,就哪 Redis 来说,还是有很多因素会影响 Redis 性能的,本文就来说一说其中的一些阻塞点,以及如何解决。一键获取最新java文档。

说到 Redis,大家自然而然的会想到基于内存、单线程执行等。话说回来,Redis 真的只有单线程吗?这篇文章来说说 Redis
的异步机制。

影响 Redis 性能的因素

我们从 Redis 内部及外部因素总结一下,主要有:

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

首先说说 Redis 实例的阻塞点:

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

客户端的阻塞

因 Redis 使用了 IO 多路复用机制,能避免主线程一直处于等待状态,网络 IO 不是导致 Redis 阻塞的因素。

而键值对的增删改查是主线程的主要工作,复杂度高的操作当然会阻塞 Redis 了。我们去判断复杂度高不高的标准就是看操作的复杂度是否为 O(N),也就是否要全表扫描。比如 hgetall, smembers 等操作就属于复杂度高的了。

然后还要注意的一个点就是数据的删除。

删除本质上来说就是对键值对的内存空间进行释放。在释放内存时,操作系统需要将释放掉的内存块插入一个空闲内存块的链表,以便后续管理和再分配。这个过程会阻塞当前释放内存的应用程序。

如果这个键值对数据很大,比如一个 zset 包含大量元素,就会释放大量的内存。有测试过删除 100 万个元素的集合时,删除时间会达到 2s,要知道 Redis 的响应是毫秒级别的。所以这种 bigkey 的删除也会成为 Redis 的阻塞点。

清空数据库(flushdb、flushall)也涉及到删除和释放所有的键值对,也是 Redis 的阻塞点。

磁盘带来的阻塞

AOF 重写和 RDB 快照,Redis 都用了子进程的方式操作,所以不会阻塞主线程。但 Redis 直接记录 AOF 日志,若有大量的写操作,并且配置的是同步写回的话,就会阻塞主线程了。

主从节点带来的阻塞

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

但是从库在接收了 RDB 文件后,需要使用 flushdb 命令清空当前数据库,这又是一个阻塞点。而且,在从库清空数据库后,需要将 RDB 文件加载到内存,快慢和 RDB 文件大小相关。加载 RDB 文件又是一个阻塞点。

切片集群的阻塞

切片集群的实例在负载均衡或者实例增加删除时,数据迁移是渐进式操作的,所以不会阻塞主线程。

小结

总结一下,Redis 就有 5 个阻塞点:

  • 集合全量查询和聚合操作;
  • bigkey 删除;
  • 清空数据库;
  • AOF 日志同步写;
  • 从库加载 RDB 文件。

异步机制解决阻塞

我们通过异步的方式,去解决可能阻塞的场景。但也不是每个操作都能用异步的方式去解决。如果一个操作能够异步执行,说明客户端不需要马上得到具体值,在 Redis 中描述为若一个操作能异步执行,就意味着它不是主线程的关键路径的操作。

对于第一个阻塞点,因为读操作需要等待数据的返回,所以第一个阻塞点不能异步执行。

第二个阻塞点和第三个阻塞点,因为删除不需要返回具体的结果,因此都可以用子线程去异步执行。

第四个阻塞点“AOF 日志同步写”,也可启动子线程操作,不用让主线程等待 AOF 日志的写完成。

第五个阻塞点“从库加载 RDB 文件”,从库要想对客户端提供数据存取服务,就必须把 RDB 文件加载完成,不能启用子进程。

异步是如何进行的

Redis 主线程启动后,会使用操作系统提供的 pthread_create 函数创建 3 个子线程,分别由它们负责 AOF 日志写操作、键值对删除以及文件关闭的异步执行。

异步删除 lazy-free

lazy-free 机制是 Redis 收到删除指令后,主线程会将这个操作放入队列,然后马上给客户端返回一个完成信息。实际上删除还没执行呢。

lazy-free 是 Redis4.0 之后才有的功能,需要手动开启。需要注意的是,即使开启了 lazy-free,如果直接使用 DEL 命令还是会同步删除 key,只有使用 UNLINK 命令才会可能异步删除 key。

而且 Redis 在删除一个 key 时,首先会评估删除的时间成本,如果成本小,也不会异步执行,直接用主线程就完成返回了。

总结

本文总结 Redis 有哪些阻塞点,以及这些阻塞点是否可用异步机制去解决。但我们在使用 Redis 时,还是要避免 bigkey 的使用。

Redis有哪些阻塞点以及如何解决?相关推荐

  1. 谈谈redis的热key问题如何解决

    谈谈redis的热key问题如何解决 参考文章: (1)谈谈redis的热key问题如何解决 (2)https://www.cnblogs.com/leeego-123/p/11588429.html ...

  2. 使用Redis分布式锁处理并发,解决超卖问题

    使用Redis分布式锁处理并发,解决超卖问题 参考文章: (1)使用Redis分布式锁处理并发,解决超卖问题 (2)https://www.cnblogs.com/VitoYi/p/8726070.h ...

  3. redis 命令 释放连接_redis scan命令导致redis连接耗尽,线程上锁的解决

    使用redis scan方法无法获取connection,导致线程锁死. 0.关键字 redis springboot redistemplate scan try-with-resource 1.异 ...

  4. 记一次线上环境 redis偶尔连接超时报错 解决

    记一次线上环境 redis偶尔连接超时报错 解决 贴出本地控制台日志 说实话,很痛苦,跟进很久了,一直认为的jvm程序所使用的配置的连接池框架问题 因为程序为 springboot 2 spring ...

  5. 遇到Redis server went away报错解决

    遇到Redis server went away报错解决 这个问题网上有很多思路,现在记录一下我碰到的 **环境:Windows(TP5)+Centos 7服务器(redis)**首先,在config ...

  6. Redis server went away报错解决

    redis:Redis server went away报错解决 1.查看redis.conf 绑定ip是否为0.0.0.0默认是127.0.0.1 如果127.0.0.1 redis-cli 连接时 ...

  7. redis启动后 允许访问_解决Redis开启远程访问及密码问题

    Redis开启远程访问及密码,具体介绍如下所示: 一.开启远程访问 1.开放端口 firewall-cmd --zone=public --add-port=6379 firewall-cmd --z ...

  8. 29 | 案例篇:Redis响应严重延迟,如何解决?

    在访问商品搜索接口时,我们发现接口的响应特别慢.通过对系统 CPU.内存和磁盘 I/O 等资源使用情况的分析,我们发现这时出现了磁盘的 I/O 瓶颈,并且正是案例应用导致的. 接着,我们借助 pids ...

  9. java redis 没密码配置_如何解决redis的NOAUTH Authentication required异常

    前言 最近学习中需要使用redis,于是在window上安装了一个redis(其实是我搞不好虚拟机和本地连接,于是放弃了虚拟机安装redis).一开始使用还很正常,也没有设置密码,按照网上所说的启动服 ...

最新文章

  1. c/c++ 如何输入带空格的字符串
  2. 1所更名、3所新设!山西4所高校获批复
  3. Linux13-bash脚本编程基础及配置文件
  4. 计算机信息技术在教学中的发展,浅析计算机在信息技术教学中的应用
  5. [NOIP2001]Car的旅行路线
  6. 深度剖析冒泡排序机制
  7. Appium 移动端自动化 - Android SDK的安装与配置,使用安卓SDK连接手机实例演示
  8. 摩托车计算机辅助设计,摩托车消声器消声特性及计算机辅助设计研究
  9. nodejs搭配phantomjs highcharts后台生成图表
  10. 研究显示每天工作超8小时得心脏病概率增加80%,生命很重要,工作不要那个累。
  11. 简述osi参考模型各层主要功能_OSI网络模型
  12. python优雅编程_Python——traceback的优雅处理
  13. 计算机毕设选题可以选什么?计算机本科毕业设计选题2023年指南
  14. fastadmin 表格文字实现换行
  15. restTemplate封装工具类
  16. 完整的网络端口表《二》
  17. Uva 10559 消除方块
  18. 【iOS开发】—— 通过URL Scheme调用外部地图软件
  19. java iqq_iQQ
  20. sqlite3数据导入导出

热门文章

  1. 【CVPR2020】何恺明团队最新力作RegNet:超越EfficientNet
  2. java实现多继承的三种方式
  3. 号称最挤的北京十条公交车
  4. Spring5从入门到精通(史上最全版)
  5. 多表 JOIN 查询统计要记得去重
  6. Elasticsearch从入门到放弃:文档CRUD要牢记
  7. RC振荡器与有源滤波器1
  8. js打开界面直接下载链接被拦截
  9. 2022-4-10 Leetcode 219.存在重复元素
  10. U盘exFAT格式转NTFS