首先澄清一点: RocksDB 的 RemoteCompaction 是 Rockset 贡献的!现在开始正文:
原理上, RocksDB 的 RemoteCompaction 和 ToplingDB 的分布式 Compact 是类似的。
分布式 Compact 的创新点是 理念,落实到工程实现上并没有多少难度。作为 理念创新:
● RocksDB 的 RemoteCompaction 主要是把 Compact 转移到 RocksDB 的 Secondary Instance
● ToplingDB 的分布式 Compact 则把它转移到专们执行 Compact 的弹性计算集群,这样做大幅降低了计算的 成本(5倍以上),并且大幅提高了性能,下面我们详细展开——
按照传统方式,在 DB 结点上,既服务读写请求,又执行 Compact,而这两种计算的需求特征完全不同:
- 1.服务读写请求,是 在线计算,评价的指标是每个请求的 延时
- 2.执行 Compact,是 离线计算,评价的指标是所有 Compact 的总 吞吐
这两种计算并发执行时,会互相争抢资源,即便 在线计算的优先级更高,但终归还是会被离线计算拖累,所以,在实际应用中,大家都不敢把系统负载跑太高,比如有些业务在规划时就要求在线服务的负载不应高于 30%,实际上可能常年在 10% 左右。
另一方面,在 RocksDB 这种 LSM 引擎中,写操作本身消耗的算力不超过 10%,而写操作引发的 后台线程(Flush & Compact)消耗的算力才是大头,这样综合起来,细思极恐!
按照 RocksDB RemoteCompaction 的理念,把 Compact 转移到 Secondary Instance,其实并未解决在线计算与 离线计算争抢资源的问题—— 除非这个 Secondary Instance 只做 Compact,不服务在线请求,但此时它就不是 Secondary Instance 了,而是跟 ToplingDB 一样,是专门的 Compact 服务器了!
按照 ToplingDB 的理念,把 Compact 转移到专们执行 Compact 的弹性计算集群,好处在于:
- 多个 DB 结点可以共享相同的 Compact 服务器,这样,因为不同 DB 的流量峰值和低谷在时间上的交错,在 Compact 服务器上,对来自不同 DB 结点的 Compact 请求,自然而然地起到平峰错谷的效果,其结果就是 提升了资源的利用率
- Compact 服务器上只运行 Compact,而 Compact 作为离线计算,对 延时并不敏感,所以,我们就可以把机器的负载打到很高(例如 90%,对比前面的 30%),从而用另一种方式 提升了资源的利用率
- Compact 计算,可以使用 空闲算力,在公有云上(例如阿里云的 抢占式实例),空闲算力的价格非常便宜,最低可以低至 1折! 从 Topling 的角度,这是 降低了计算资源的成本,从公有云厂商的 角度,提高了他们的资源利用率!
所以,综合起来,我们说计算成本降低了5倍,还是非常保守的数字!
接下来,对用户而言,要使用分布式 Compact,关注点在于: 功能性、 易用性、 可靠性、 可观测性,下面我们展开来讲:
(一)功能性
作为 Offload 出去的计算,其计算结果必须与本地计算等效,这样,功能上的等同就是一个必要条件,比如说,Comparator, CompactionFilter, MergeOperator ... 都必须支持,如果缺乏这些支持,最多就只是一个半成品!
ToplingDB 可自定义 CompactionFilter, MergeOperator ... 的 序列化/反序列化,还可以将更多的数据放到共享存储上,例如 Todis 中 hash/list/set/zset 对 meta data 的处理
其次,Compact 过程中会更新很多指标(RocksDB 的 Statistics),这些指标虽然不影响数据内容,但是会影响引擎的可观测性。
ToplingDB 将这些指标从远端发送回来,并聚合到本地,对于特殊指标进行分别处理,例如将远端的 lcompact 指标聚合到本地的 dcompact 指标,因为远端将 compact 作为它的本地 compact 运行,回到 DB 端时,DB 端的 dcompact 指标对应的就是远端的 lcompact……
在这两点上,ToplingDB 完胜!
(二)易用性
怎样通过 用户代码来使用,分 DB 端(Client 端)与 Worker 端(Server 端):
| RocksDB 的 RemoteCompaction | ToplingDB 的分布式 Compact | |
|---|---|---|
| DB 端 | 用户需要修改代码进行配置和启用 | 在 json/yaml 中修改配置,用户代码无需任何改动 |
| Worker 端 | 用户需要完全自己写一个 Worker | 通过 LD_PRELOAD 加载用户自定义的
动态库,其中可包含 CompactionFilter, MergeOperator ...
可以跟 DB 端共享相同的动态库(在 Todis 中就是这样干的) |
(三)可靠性
- RocksDB 的 RemoteCompaction 还处在 Experimental 状态
- ToplingDB 的分布式 Compact 已在 托管 Todis 中使用多时,得到了充分的验证
可靠性仰赖良好的实现与充分的测试,在实现上,按 DB 端(Client 端)与 Worker 端(Server 端)来看:
| RocksDB 的 RemoteCompaction | ToplingDB 的分布式 Compact | |
|---|---|---|
| DB 端 | 显式序列化、发送参数 | 设置最少参数集,调用 DB 端 Executor 抽象接口 |
| Worker 端:Compact Setup | 以幽灵模式打开 DB,创建一个 DB 对象,setup 速度慢 | 用 compact job 的参数创建一个 Version,setup 速度快 |
| Worker 端:Compact 过程的实现 | 重新实现了一遍 Compact 的主要 逻辑,可靠性还需要时间的检验(目前还是 Experiment) | 完全复用现有的(本地) Compact 代码,可靠性已经过检验,并且工程量更小 |
(四)可观测性
RocksDB 的 RemoteCompaction 只能查看 LOG。
ToplingDB 通过 引擎内嵌 Web,支持 分布式 Compact 在线观测(长时间运行的 演示实例)。
