• Redis Plus 来了,性能炸裂!

Redis Plus 来了,性能炸裂!

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

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