• Redis Plus 来了,性能炸裂!

Redis Plus 来了,性能炸裂!

2025-06-24 08:37:03 栏目:宝塔面板 106 阅读

KeyDB项目是从Redis fork出来的分支。众所周知Redis是一个单线程的kv内存存储系统,而KeyDB在100%兼容Redis API的情况下将Redis改造成多线程。

线程模型

KeyDB将Redis原来的主线程拆分成了主线程和worker线程。每个worker线程都是io线程,负责监听端口,accept请求,读取数据和解析协议。如图所示:

KeyDB使用了SO_REUSEPORT特性,多个线程可以绑定监听同个端口。

每个worker线程做了cpu绑核,读取数据也使用了SO_INCOMING_CPU特性,指定cpu接收数据。

解析协议之后每个线程都会去操作内存中的数据,由一把全局锁来控制多线程访问内存数据。

主线程其实也是一个worker线程,包括了worker线程的工作内容,同时也包括只有主线程才可以完成的工作内容。在worker线程数组中下标为0的就是主线程。

主线程的主要工作在实现serverCron,包括:

  • 处理统计
  • 客户端链接管理
  • db数据的resize和reshard
  • 处理aof
  • replication主备同步
  • cluster模式下的任务

链接管理

在Redis中所有链接管理都是在一个线程中完成的。在KeyDB的设计中,每个worker线程负责一组链接,所有的链接插入到本线程的链接列表中维护。链接的产生、工作、销毁必须在同个线程中。每个链接新增一个字段。

int iel; /* the event loop index we're registered with */

用来表示链接属于哪个线程接管。

KeyDB维护了三个关键的数据结构做链接管理:

  • clients_pending_write:线程专属的链表,维护同步给客户链接发送数据的队列;
  • clients_pending_asyncwrite:线程专属的链表,维护异步给客户链接发送数据的队列;
  • clients_to_close:全局链表,维护需要异步关闭的客户链接。

分成同步和异步两个队列,是因为redis有些联动api,比如pub/sub,pub之后需要给sub的客户端发送消息,pub执行的线程和sub的客户端所在线程不是同一个线程,为了处理这种情况,KeyDB将需要给非本线程的客户端发送数据维护在异步队列中。同步发送的逻辑比较简单,都是在本线程中完成,以下图来说明如何同步给客户端发送数据:

如上文所提到的,一个链接的创建、接收数据、发送数据、释放链接都必须在同个线程执行。异步发送涉及到两个线程之间的交互。KeyDB通过管道在两个线程中传递消息:

int fdCmdWrite; //写管道
int fdCmdRead; //读管道

本地线程需要异步发送数据时,先检查client是否属于本地线程,非本地线程获取到client专属的线程ID,之后给专属的线程管到发送AE_ASYNC_OP::CreateFileEvent的操作,要求添加写socket事件。专属线程在处理管道消息时将对应的请求添加到写事件中,如图所示:

Redis有些关闭客户端的请求并非完全是在链接所在的线程执行关闭,所以在这里维护了一个全局的异步关闭链表。

锁机制

KeyDB实现了一套类似spinlock的锁机制,称之为fastlock。

fastlock的主要数据结构有:

struct ticket
{
    uint16_t m_active;  //解锁+1
    uint16_t m_avail;  //加锁+1
};
struct fastlock
{
    volatile struct ticket m_ticket;

    volatile int m_pidOwner; //当前解锁的线程id
    volatile int m_depth; //当前线程重复加锁的次数
};

使用原子操作__atomic_load_2,__atomic_fetch_add,__atomic_compare_exchange来通过比较m_active=m_avail判断是否可以获取锁。

fastlock提供了两种获取锁的方式:

  • try_lock:一次获取失败,直接返回
  • lock:忙等,每1024 * 1024次忙等后使用sched_yield 主动交出cpu,挪到cpu的任务末尾等待执行。

在KeyDB中将try_lock和事件结合起来,来避免忙等的情况发生。每个客户端有一个专属的lock,在读取客户端数据之前会先尝试加锁,如果失败,则退出,因为数据还未读取,所以在下个epoll_wait处理事件循环中可以再次处理。

Active-Replica

KeyDB实现了多活的机制,每个replica可设置成可写非只读,replica之间互相同步数据。主要特性有:

  • 每个replica有个uuid标志,用来去除环形复制
  • 新增加rreplay API,将增量命令打包成rreplay命令,带上本地的uuid
  • key,value加上时间戳版本号,作为冲突校验,如果本地有相同的key且时间戳版本号大于同步过来的数据,新写入失败。采用当前时间戳向左移20位,再加上后44位自增的方式来获取key的时间戳版本号。

项目地址:https://github.com/JohnSully/KeyDB

本文地址:https://www.yitenyun.com/301.html

搜索文章

Tags

数据库 API FastAPI Calcite 电商系统 MySQL Web 应用 异步数据库 数据同步 ACK 双主架构 循环复制 TIME_WAIT 运维 负载均衡 JumpServer SSL 堡垒机 跳板机 HTTPS JumpServer安装 堡垒机安装 Linux安装JumpServer Deepseek 宝塔面板 Linux宝塔 Docker esxi esxi6 root密码不对 无法登录 web无法登录 生命周期 序列 核心机制 HexHub Windows Windows server net3.5 .NET 安装出错 服务器 管理口 HTTPS加密 宝塔面板打不开 宝塔面板无法访问 查看硬件 Linux查看硬件 Linux查看CPU Linux查看内存 Windows宝塔 Mysql重置密码 Oracle 处理机制 InnoDB 数据库锁 连接控制 机制 监控 无法访问宝塔面板 ES 协同 Serverless 无服务器 语言 技术 开源 PostgreSQL 存储引擎 Spring Redis 异步化 分页查询 索引 group by 高可用 服务器性能 缓存方案 缓存架构 缓存穿透 机器学习 SQL 动态查询 日志文件 MIXED 3 Undo Log GreatSQL 连接数 SVM Embedding 响应模型 自定义序列化 R edis 线程 ​Redis 推荐模型 数据 主库 Postgres OTel Iceberg 云原生 Netstat Linux 服务器 端口 工具 R2DBC PG DBA Linux 安全 SQLark RocketMQ 长轮询 配置 scp Linux的scp怎么用 scp上传 scp下载 scp命令 AI 助手 向量数据库 大模型 共享锁 存储 SQLite-Web SQLite 数据库管理工具 优化 万能公式 openHalo 查询 Recursive 电商 系统 OB 单机版 Ftp Hash 字段 • 索引 • 数据库 Rsync 架构 流量 聚簇 非聚簇 数据分类 加密 磁盘架构 修改DNS Centos7如何修改DNS 人工智能 推荐系统 redo log 重做日志 sftp 服务器 参数 防火墙 黑客 线上 库存 预扣 MVCC 场景 同城 双活 MySQL 9.3 业务 信息化 智能运维 传统数据库 向量化 向量库 Milvus RDB AOF Doris SeaTunnel 高效统计 今天这篇文章就跟大家 INSERT COMPACT 数据备份 Redisson 锁芯 mini-redis INCR指令 缓存 不宕机 窗口 函数 网络架构 网络配置 Python 锁机制 prometheus Alert PostGIS 事务 Java 开发 Canal B+Tree ID 字段 引擎 性能 Web 崖山 新版本 MongoDB 数据结构 核心架构 订阅机制 分库 分表 filelock ZODB IT运维 数据脱敏 加密算法 分布式 集中式 启动故障 Redis 8.0 读写 容器化 数据类型 OAuth2 Token JOIN 网络故障 容器 DBMS 管理系统 虚拟服务器 虚拟机 内存 频繁 Codis 模型 Go 数据库迁移 自动重启 Pottery 聚簇索引 非聚簇索引 QPS 高并发 原子性 发件箱模式 微软 SQL Server AI功能 Entity 排行榜 排序 Testcloud 云端自动化 SSH Web 接口 部署 数据页 工具链 事务隔离 SpringAI 分页方案 排版 数据集成工具 速度 服务器中毒 Caffeine CP MCP 开放协议 悲观锁 乐观锁 StarRocks 数据仓库 Redka 分页 AIOPS 1 优化器 池化技术 连接池 单点故障 网络 sqlmock LRU 大表 业务场景 意向锁 记录锁 EasyExcel MySQL8 dbt 数据转换工具 行业 趋势 事务同步 仪表盘 分布式架构 分布式锁​ Order InfluxDB 国产数据库 日志 IT RAG HelixDB 对象 字典 单线程 双引擎 订单 Crash 代码 Ansible 编程 LLM UUIDv7 主键 主从复制 代理 播客 UUID ID Valkey Valkey8.0 Pump 线程安全 List 类型 ReadView 产业链 兼容性 数据字典 恢复数据 Weaviate MGR 分布式集群 语句 解锁 调优 Next-Key 失效 关系数据库 表空间 慢SQL优化 GitHub Git 矢量存储 数据库类型 AI代理 查询规划 分布式锁 Zookeeper 国产 用户 RR 互联网 算法 快照读 当前读 视图 千万级 神经系统 count(*) count(主键) 行数 CAS 多线程 并发控制 恢复机制 拦截器 动态代理 技巧 闪回