若是我告诉您有一个 Redis 的分支版本,它的性能比原生的 Redis 快 5 倍,并且延迟却下降近 5 倍,你会不会想了解一下这个项目?而若是您再也不须要哨兵节点而且您的副本能够接受读取和写入,这将有可能使分片数量减小 10 倍,这样对你的吸引力是否是更大了呢?git
我说的这个分支版本,它实际上是 Redis 的一个分叉版本,名叫 KeyDB 。KeyDB 是 Redis 开源的多线程分叉版本。本文咱们将提供最新的基准测试结果,并讨论更强大的 KeyDB 实例如何减小集群大小以及简化堆栈。同时咱们还将讨论了多线程体系结构,并演练了如何利用它实现性能的提高。github
凭借着咱们不受限制的代码库开发能力,KeyDB 可以在短期内取得长足的进步,而且所走的道路将在将来几个月内破坏整个数据库格局。数据库
关于为何首先搞一个 Redis 分叉的缘由,这是由于 KeyDB 和 Redis 在如何发展方面有不一样的理念。咱们认为易用性、高性能和“内置动力”的方法是创造良好用户体验的最佳方法。尽管咱们很是尊重 Redis 维护者,但咱们认为 Redis 的方法过于注重代码的简单性,而以牺牲用户的便利性为代价。这致使常常须要借助外部组件和方案来解决不少常见问题。服务器
因为存在乎见分歧,所以适合 KeyDB 的功能可能不适用于 Redis。而作一个新的分叉版本能够容许咱们探索这一新的开发路径并实现可能永远不会成为 Redis 一部分的功能。KeyDB 将与上游的 Redis 代码变动保持同步,在适用的状况下,咱们还给 Redis 提交错误修复和改进。咱们但愿这两个项目可以继续发展并相互学习。网络
KeyDB 于今年3月推出,尽管咱们的性能有所提升,但咱们仍然但愿它能更快地发展。咱们最新的基准测试数据显示,KeyDB的单个实例的每秒操做数(图范围为53-5.49)比Redis(v5)的单个实例多5倍以上,而延迟(图形范围为4.6-5.1)近5倍:数据结构
增长 KeyDB 的单个实例/节点的功能能够减小分片的须要,而且能够大大减小数据移动的数量。您可能会问,与在单个节点上多线程化相比,在群集中运行许多Redis 节点是否能够得到比单线程多线程更多的吞吐量?您能够像 Redis 同样对 KeyDB 进行分片,这对数据库进行水平扩展颇有意义。可是,若是您能够选择增长马力而不购买第二辆车,那为何不呢?除分片外,还可以扩展节点的大小,为用户增长了新的功能和选择。这是 Redis 与 KeyDB 之间意见分歧的其中之一。这不只是社区中的常见讨论点,仍是某些圈子中的争论点。多线程
所以,为了回答 “用 KeyDB 运行更多线程看起来像什么?” 这个问题,咱们提供了一些基本数字,以便您对此问题有所了解。架构
如下是基准测试(操做/秒)与使用的线程数对应关系的图表:ide
随着分配更多资源给实例,您能够看到性能获得大幅提升。同时还能够能够将线程固定到某个CPU上以获得进一步的提高,但最适合您的选择可能取决于您的设置。默认状况下,此选项是禁用的。性能
仅将一个线程分配给KeyDB,平均而言,与 Redis 的单个线程实例相比,它仍可保持约5%的性能提高。所以,即便添加了新功能并更改了体系结构,性能也没有受到影响。
KeyDB 经过在多个线程上运行常规的 Redis 事件循环来工做。网络 IO 和查询解析是同时进行的。每一个链接在 accept() 上分配一个线程。自旋锁保护对核心哈希表的访问。由于哈希表访问很是快,因此此锁的争用较低。事务在EXEC命令的持续时间内保持锁定。模块与GIL协同工做,而GIL仅在全部服务器线程都暂停时才获取。这保持了模块指望的原子性保证。
与大多数数据库不一样,核心数据结构是系统中最快的部分。查询的大部分时间来自解析REPL协议并将数据复制到网络或从网络复制数据。
将来的工做包括容许在链接以后从新平衡与不一样线程的链接,并容许多个读取器同时访问哈希表
此外,KeyDB 还提供了一些有助于简化用户体验的功能。例如活动副本功能已在最新的稳定版本 5 中普遍采用并在生产中使用。此功能使您可以在两个主节点彼此复制,同时接受读取和写入操做。并且不须要哨点节点来控制故障转移。您将得到很高的可用性,同时最大限度地利用资源。若是还没有平衡对副本节点的读取,则可使用此选项将吞吐量提升一倍。这意味着从简单的 Redis 主副本设置转移到使用 KeyDB 的多线程活动副本设置,能够将分片需求减小多达10倍。