返回顶部

Redis 核心技术与实战 —— 实战(二)

异步机制:如何避免单线程模型的阻塞?

Redis 实例有哪些阻塞点

  • 客户端:网络 IO,键值对增删改查操作,数据库操作;

  • 磁盘:生成 RDB 快照,记录 AOF 日志,AOF 日志重写;(子进程完成)

  • 主从节点:主库生成、传输 RDB 文件,从库接收 RDB 文件、清空数据库、加载 RDB 文件;

  • 切片集群实例:向其他实例传输哈希槽信息,数据迁移

删除数据时:在应用程序释放内存时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配,如果一下子释放了大量内存,空闲内存块链表操作时间就会增加,相应地就会造成 Redis 主线程的阻塞。

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

那些阻塞点可以异步执行

如果一个操作能被异步执行,就意味着,它并不是 Redis 主线程的关键路径上的操作,这就是说,客户端把请求发送给 Redis 后,等着 Redis 返回数据结果的操作。

所以 集合全量查询和聚合操作和从库加载 RDB 文件(从库的主线程加载完数据后从库才可用) 都是主要的操作,不能异步。

异步的子线程机制

 

异步的键值对删除和数据库清空操作是 Redis 4.0 后提供的功能,Redis 也提供了新的命令来执行这两个操作

键值对删除:当你的集合类型中有大量元素(例如有百万级别或千万级别元素)需要删除时,我建议你使用 UNLINK 命令。

清空数据库:可以在 FLUSHDB 和 FLUSHALL 命令后加上 ASYNC 选项,这样就可以让后台子线程异步地清空数据库,如下所示

1
2
FLUSHDB ASYNC
FLUSHALL AYSNC

对于这两个阻塞点

  • 集合全量查询和聚合操作:可以使用 SCAN 命令,分批读取数据,再在客户端进行聚合计算;

  • 从库加载 RDB 文件:把主库的数据量大小控制在 2~4GB 左右,以保证 RDB 文件能以较快的速度加载。  

为什么CPU结构也会影响Redis的性能

主流的cpu架构

一个 CPU 处理器中一般有多个运行核心,我们把一个运行核心称为一个物理核,每个物理核都可以运行应用程序。每个物理核都拥有私有的一级缓存(Level 1 cache,简称 L1 cache),包括一级指令缓存和一级数据缓存,以及私有的二级缓存(Level 2 cache,简称 L2 cache)。 当数据或指令保存在 L1、L2 缓存时,物理核访问它们的延迟不超过 10 纳秒,速度非常快,如果 Redis 把要运行的指令或存取的数据保存在 L1 和 L2 缓存的话,就能高速地访问这些指令和数据。(l1和l2只能保存 kB 的数据不大)

 在主流的服务器上,一个 CPU 处理器会有 10 到 20 多个物理核。同时,为了提升服务器的处理能力,服务器上通常还会有多个 CPU 处理器(也称为多 CPU Socket),每个处理器有自己的物理核(包括 L1、L2 缓存),L3 缓存,以及连接的内存,同时,不同处理器间通过总线连接。

在多 CPU 架构上,应用程序可以在不同的处理器上运行,虽然可以在不同的核上来回切换运行,在切换的时候还要知道之前scoket连接的内存,这种访问属于远端内存访问。就会增加程序延迟。

解决方法:

让 redis 绑定到一个或多个核上  

1
taskset -c 0,12 ./redis-server

如何应对变慢的Redis?

1 存在大量过期的key ,如果一批 key 的确是同时过期,可以在 EXPIREAT 和 EXPIRE 的过期时间参数上,加上一个一定大小范围内的随机数

EXPIRE key seconds   

  • 设置key的生存时间还剩多少秒

EXPIREAT key timestamp

  • 设置key生存到什么时候,接受的参数是时间戳

2 一些慢查询的语句,在服务端的计算拿到客户端来进行。避免一次拿太多的数据可以分批次去拿

如果不是客户端程序导致的,就需要考虑文件系统和操作系统了 

3 查看redis 的内存碎片,修改配置项即可

1
config set activedefrag yes

  

 

posted @   Crazymagic  阅读(16)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示

目录导航