projecteru / redis-cerberus

Redis Cluster Proxy
MIT License
352 stars 82 forks source link

设计文档 #28

Closed tigerzhang closed 5 years ago

tigerzhang commented 8 years ago

我们团队觉得 redis-cerberus 代码质量不错,准备在这个代码基础上开发几个特性。

请问有关于代码里面几个重要的类的描述文档吗?最好有典型的数据流向路径的描述文档。

谢谢

zheplusplus commented 8 years ago

过奖过奖. (要是写得好的话可能不需要文档吧 :joy: )

先简单说一下吧, 详细的之后看有没有空补上...

Proxy 里负责处理 epoll API (实际上是一组包装在 epoll API 上的函数调用), 几种继承自 Connection 的类型将它们的 fd 交给 epoll. 其中

相对的 Server 里只有 2 个分组: _commands 表示刚刚从客户端来的, _sent_commands 表示写出了的. 而一旦有命令返回, 就马上把结果给 Client, 而不会存在 Server 对象里.

CommandGroup 则有个函数是 select_remote 表示如何选择对应的 Server , 对于单一 key 指令 SingleCommandGroup 来说就是选出 key 对应的那个, 而像 MGET 多 key 的 MultipleCommandsGroup 可能会选择多个 Server.

写出指令之后就等待从 Server 读入结果. 处理结果要稍简单一些, 代码在 core/response.hpp|cpp 中. Response 有个虚函数 rsp_to 其实也只有两种情况: 正常返回, 或发生了 MOVED 之类的集群状态改变, 后者要更新集群映射再重试.

要注意的是, 一些 IO 错误是用异常处理的, 在 Buffer 类中直接 throw 并在 epoll 循环里捕获.

最后, Buffer 的效率其实很挫...

tigerzhang commented 8 years ago

@neuront 谢谢回复。有个问题没太想明白,CommandGroup 这个命名的由来是因为像 MSET 这种命令会被拆分成多个 SET 命令,所有才会用 Group 来命名吗?

zheplusplus commented 8 years ago

@TigerZhang 正是. 从 Client 视角看来只是一个指令, 但是从 Server 看来是一个组.

tigerzhang commented 8 years ago

@neuront 非常感谢,基本都掌握了。 今天一直没有想明白 struct sref 和 struct sptr。我的理解,struct sptr 是为了方便使用 unique_ptr,不过感觉好像可以直接用 std 的相关函数。struct sref 就没太看明白,sref 封装的 unique_ptr::pointer,看起来好像又不能管理指针的生命周期,不能自动释放内存。

zheplusplus commented 8 years ago

@TigerZhang 这个是我的锅, 之前一个项目里移过来的文件.

sptr 就是包了一层 unique_ptr 限制了一些 API. sref 就是 reference_wrapper, 表示无生命周期控制权的弱引用. 早些的 gcc 版本里还没有 reference_wrapper, make_unique, 于是自己来了几个轮子, 顺便把名字缩短了一点. 用习惯了就拉到这个项目里了.

另外在 CommandServer 之间中用了 shared_ptr 存待发送的内容, 这是为了在简化这种情况的处理: 这些内容发送之前, 如果客户端断开连接, 那么 Client 实例会析构, 同时其中的 Command 也会间接失效, 如果这些 Command 进入了 Server 的等待队列, 那么接着 Server 就会读取到失效内存; 为了防止这一情况发生, Server 里的输出缓冲区是个 shared_ptr<Buffer> 容器 BufferSet, 这样客户端单方面退出, 其中的缓冲区内存还不会失效.

tigerzhang commented 8 years ago

@neuront 明白了,后面有时间我准备把这一部分修改成标准库的做法,方便团队其它人上手。谢谢。

tigerzhang commented 8 years ago

在 redis-cerberus 基础上做了一个初始版本 https://github.com/TigerZhang/redis-cerberus , 用来作为一个代理,整合一个 redis cache 和 redis DB (ardb),对外暴露统一的 redis 接口。

baiwfg2 commented 7 years ago

最近我们团队也在调研redis proxy,看到了cerberus。安排童鞋了解下实现,可源码中LOG打印好少啊,为此加了大量的TRACE LOG :joy: .作者有时间可写下详细的实现文档啊,这样也有利于推广