5 个版本
0.1.4 | 2024年2月15日 |
---|---|
0.1.3 | 2024年2月2日 |
0.1.2 | 2024年2月2日 |
0.1.1 | 2024年1月7日 |
0.1.0 | 2024年1月2日 |
#735 在 数据库接口
每月 64 次下载
120KB
2.5K SLoC
roster
用 Rust 和 io-uring 替代 Redis
roster
是一个内存数据存储,旨在提供完全兼容的 Redis API。
目前它更像是一个实验,欢迎贡献。一些涉及 resp 协议的初始代码来自 mini-redis
。
目前的工作是建立一个良好的基础,以便能够在这之上构建 Redis 协议。
基准测试
如果您需要基准测试,请查看: 基准测试;
Redis API 没有得到适当的实现,只有一些基本的功能存在,因此这些基准测试只是为了检查对存储和 I/O 所做的决策是否良好。
随着实现的进展,这些将会更新。
基准测试是在 Redis、Dragonfly 和 Roster 之间进行的。
ENT1-M Scaleway
第一次基准测试是基于一个 ENT1-M Scaleway,这是一个相当不错的实例,但并不是非常大,我们受到实例和两个实例之间网络的限制很大,就像 Redis 和 Dragonfly 一样。
- 16 个 vCPU
- RAM: 64G
- BW: 3,2 Gbps
协议
Redis
- 目前只需要 RESP3。
已实现命令的完整列表可以在 这里 查看。
架构
性能
为了能够充分发挥应用程序的性能,我们必须能够实现线性可扩展性。[^1] 常见的可扩展性问题是在线程之间共享数据时(例如,虚假共享[^3])。
为了解决这个问题,我们使用了一个 scc::Hashmap,这是一个非常有效的数据结构。这个数据结构可以在多个线程之间共享,而不会损失性能,除非线程太多。当这种情况发生时,当我们需要时,我们会通过负载均衡 TCP 连接来分区存储。
我们还使用了一个基于 io-uring
的运行时来处理应用程序中的所有 I/O: monoio。
[^1]: 这意味着如果我们有一个在一根线程上运行 100 op/s 的应用程序,如果我们添加另一个,我们应该达到 200 op/s。我们有一个线性可扩展性。(或者近似线性可扩展性)。[^3]: 一篇解释它非常出色的文章:[alic.dev](https://alic.dev/blog/false-sharing)。
与无共享架构相同的理念,我们使用每个核心一个线程以最大化硬件上的资源。
"应用程序尾部延迟对于服务满足其延迟期望至关重要。我们已经证明,与在通用硬件和Linux上运行的基线Memcached相比,线程每核心方法可以将键值存储的应用程序尾部延迟降低高达71%。"[^2]
[^2]: 线程每核心架构对应用程序尾部延迟的影响
存储
对于存储,而不是让每个线程通过基于TCP连接的负载均衡来处理其存储部分,似乎让多个线程共享存储更加高效。
我们将整个应用程序拆分为多个存储段,这些存储段在固定数量的线程之间共享。
参考文献
- RESP3
- https://github.com/tair-opensource/compatibility-test-suite-for-redis
- https://github.com/redis/redis-specifications
- https://github.com/redis/redis-benchmarks-specification
许可证
依赖项
~16–28MB
~411K SLoC