目录
OPED-06 KV Store 的末日来了吗?
OPED 是 (我自己发起的) One Paper Each Day 挑战, 即每天读一篇 Paper, 领域不限.
这是 OPED 挑战的第六篇, 论文为 Fast key-value stores: An idea whose time has come and gone
说好的 OPED, 结果停更了这么久. 因为最近实在是太忙(懒)了, 工作上有一个大的上线, 然后最近期待很久的游戏也发售了. 工作日早起打游戏, 我还是肝得动.
这篇论文看标题有一点朋友圈标题党的感觉. 它的观点确实有点让人耳目一新. 但我的感觉是, 道理有的, 但是对于一般技术团队来说, 操作性不高, 性价比比较差, 可以暂时观望一下.
这篇论文的核心观点是, RInK (即 Remote in-memory KV Store) 虽然能帮助我们开发 stateless 的服务, 但是它们都有一些无法避免的天然缺陷. 开发者们应该使用 LInK (即 Local in-memory KV Store) 来开发 stateful 的服务.
上面的声明是不是让你觉得不可思议? 什么? 无状态的服务多么好管理, 多么容易水平扩展? Stateful? 开历史的倒车!
先静一静, 让我们先听他解释.
RInK, 包括 Redis, Memcached 等等, 作为一个通用的内存存储服务, 往往提供了通用的接口, 比如 GET/PUT (当然有一部分会提供一些高级一点的接口, 比如 append 之类的). 与此同时, 这些服务都需要通过 RPC 调用来使用. 以上这两个特点会带来三个无法避免的问题
- 序列化/反序列化开销. 各种编程语言中的数据在内存中的结构, 往往和 RInK 中存储的结构不同. 因此需要序列化和反序列化. 说出来你可能不信, 在很多服务中, 大部分 CPU 资源都是在干这个 (因为业务逻辑除了调用外部服务, 其他的都比较简单…)
- 为了保证通用性, 接口往往只能返回 key 对应的整个 value, 即使调用方只需要其中的一点点数据. 用于数据量大, 带宽压力, 反序列化压力也随之增大. 这也被称作 overreads 问题.
- 最后一个显而易见的问题当然是网络延迟. 确实大部分 RInK 服务的延迟都很低. 所以, 大部分情况下, 只有 tail latency 会受到影响. 但是如果你看了之前的文章, 再想想你的服务中, 处理一个请求, 要调用多少次 redis, 你可能会觉得事情并没有想象的那么简单.
说了那么多, 到底怎么解决这些问题呢? 这篇论文说他们用库的形式提供了 KV 服务, 还提供 replication, sharding, routing 等等功能. 然而关于实现细节一点没有讲… 这篇 7 页的论文着实有点让人失望.
总结一下, 我个人觉得性能上的损耗相对于更高的可维护性来说, 是一个可以承受的 trade off. LInK 确实有一定的好处, 但是在有成熟的实现之前, 还是先用一下 RInK 吧. 关于 overreads, 这就体现出 GraphQL 的优越性了.