我一直认为 Redis 是学习 C 语言的最好资源之一。很高兴现在有了 Rust 的等价物!
Reddit 网友 sjustinas
mini-redis 是一个使用 Rust Tokio 框架构建的 Redis 不完整的实现,包括服务器和客户端。
这个项目的目的是提供一个如何更好的使用 Tokio 的示范。
免责声明:目前 mini-redis 更多的是示范作用,不要在生产环境中使用这个项目。
为什么选择实现 Redis
mini-redis 项目主要目标是更好示范使用 tokio,要做到这一点,就需要一个具有广泛功能的项目,并注重实现的简单性。Redis 是一个内存数据库,提供了广泛的功能,并使用了简单的网络协议。广泛的特性使其可以在真实使用场景下展示 Tokio 的使用模式。
Redis 协议文档可以在这里找到:
https://redis.io/topics/protocol
Redis 提供的一系列命令可以在这里找到。
https://redis.io/commands
运行
仓库提供了一个服务器、客户端库,以及一些与服务器交互的客户端可执行文件。
启动服务器。
RUST_LOG=debug cargo run --bin server
追踪箱用于提供结构化的日志。你可以用所需的日志级别来代替debug。
然后,在不同的终端窗口中,可以执行各种客户端实例。举例来说
cargo run --example hello_world
此外,还提供了一个CLI客户端,可以从终端运行任意命令。在服务器运行的情况下,下面的命令可以运行。
cargo run --bin cli set foo bar
cargo --bin cli get foo
支持的命令
mini-redis 目前支持以下命令。
GET
SET
PUBLISH
SUBSCRIBE
目前 mini-redis 还没有对持久化的支持。
Tokio 模式
mini-redis 项目展示了许多有用的模式,包括以下方面:
TCP服务器
server.rs 启动一个接受连接的 TCP 服务器,并在每个连接中生成一个新任务。它可以优雅地处理接受错误。
客户端库
client.rs 展示了如何建立一个异步客户端的模型。各种功能都是以异步方法的形式显示的。
通过 Socket 共享状态
服务器维护一个 Db 实例,该实例可从所有连接的连接中访问。该 Db 实例管理键值状态以及 pub/sub 功能。
框架化
connection.rs 和 frame.rs 展示了如何简单实现一个网络协议。该协议使用一个中间表示法 Frame 结构。Connection 取一个 TcpStream,并暴露了一个API,用来发送和接收 Frame 值。
优雅的关闭
tokio:::signal 被用来监听 SIGINT。一旦收到信号,shutdown 开始。服务器停止接受新的连接。现有的连接会被通知优雅地关闭。等待运行中的工作完成,连接被关闭。
并行连接限制
服务器使用 Semaphore 限制最大并发连接数。一旦达到限制,服务器将停止接受新的连接,直到现有的连接终止。
pub/sub
服务器实现了 non-trivial 的 pub/sub 功能。客户端可以订阅多个频道,并随时更新订阅。服务器使用每个频道一个广播频道和每个连接一个 StreamMap 来实现。客户端能够向服务器发送订阅命令来更新活动订阅。
在异步应用程序中使用 std:::sync:::Mutex
服务器使用 std:::sync:::Mutex 而不是 Tokio mutex 来同步访问共享状态。更多细节请参见 db.rs:
https://github.com/tokio-rs/mini-redis/blob/master/src/db.rs
测试依赖时间的异步代码
在test/server.rs中,有对密钥过期的测试。这些测试取决于时间的通过。为了使测试具有确定性,我们使用Tokio的测试工具来模拟时间。
mini-redis 项目地址:
https://github.com/tokio-rs/mini-redis
参考阅读:
深入浅出Rust异步编程之Tokio
硬核!Rust异步编程方式重大升级:新版Tokio如何提升10倍性能详
如何快速定位 Redis 热 key?
当不懂某项技术时候,如何面试工程师?
理想的DevOps流程怎么做?看看Slack的代码部署实
新项目用 Rust 还是 Go ?
本文由高可用架构编译。技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。
高可用架构
改变互联网的构建方式
长按二维码 关注「高可用架构」公众号