查看原文
其他

mini-redis,一个精简版Redis实现,基于Rust开发

高柯用 高可用架构 2020-11-06

我一直认为 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


参考阅读:



本文由高可用架构编译。技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。


高可用架构

改变互联网的构建方式


长按二维码 关注「高可用架构」公众号

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存