titan icon indicating copy to clipboard operation
titan copied to clipboard

能否考虑将与存储层的通信抽象成接口

Open gotoxu opened this issue 5 years ago • 14 comments

我们现在底层KV存储没有使用TiKV。

我们希望通过改造titan项目,将与存储层的通信抽象成接口,通过配置的方式自由选择连接具体的底层KV存储,不知道你们是否可以接受这样的改动。

如果不行的话我们只能fork出去自行开发,希望得到你的回复,谢谢!

gotoxu avatar Jan 18 '20 02:01 gotoxu

@gotoxu 这可能无法实现。titan 的实现基于 tikv 的架构提供的ACID 事务,底层抽象无法解决各种数据库的事务接口的不同。

或者说无法抽象出一套适用于所有带有分布式事务的存储组件的接口

arthurkiller avatar Jan 19 '20 06:01 arthurkiller

@gotoxu 通用的接口我觉得是没问题的,Titan 也不一定会一直使用 TiKV,对于这样的改动,我个人觉得是可以接受的。不过这一层的抽象非常核心,需要有足够的灵活性。我们可以详细探讨下。我目前想到需要做的事情:

  • 有一个设计文档,总结抽象接口的意义,思路,设计和实现方案
  • 讨论并定义出足够灵活的接口,这依赖于底层存储引擎的接口和特性,甚至有些需要特殊处理的地方。
  • 深入讨论不同存储引擎的特性,可能的坑等。比如你们期望使用什么存储引擎,都有什么特性等。

shafreeck avatar Jan 20 '20 05:01 shafreeck

NVM, 可行性上当然是 open 的。不过有 以下几点 我觉得需要考虑:

  • titan 的名字叫 ti tan 而不是其他的什么 tan , 在设计的一开始就默认了使用 tikv 提供的存储引擎,以及 tikv 提供的 ACID 事务。众所周知,ACID 事务的实现并不是唯一的 ,因此接口并不是特别容易想清楚。
  • titan 开发初始设计的对于 redis 数据结构的实现,目前数据结构的实现上对于 tikv 的 sdk 是没有解耦的。尽管设计上尽可能的拆分出了 DB 的概念和抽象
  • titan 本身还是非常重视性能,对于性能的优化一旦深入,必然会涉及到存储引擎的对应性优化。尽管目前单机数据库底层的存储大多是以 LSM tree 为主,但是不同的上层分布式实现仍然会导致使用姿势的较大差异,尤其是不同数据库对于 CAP 的设计取舍会导致同类操作性能上的极大差异。因此 脱离底层存储的 titan 实现较难对于性能进行调优
  • 换个角度,如果希望实现一个基于其他存储引擎的的 titan ,完全可以把 titan 封装的 RESP 协议库拿出来用,然后重新实现数据结构即可,没必要拘泥于一个大而全的实现

@shafreeck

arthurkiller avatar Jan 20 '20 06:01 arthurkiller

@shafreeck 提一个不成熟的建议,是否可以参考golang标准库中database/sql包的实现方式,通过抽象出一个Driver来向系统进行注册,从而可以实现对接多种数据库实现。

@arthurkiller 我看了一下tidb的源码,应该也是这么实现的(当然我可能有遗漏之处,我暂时没时间仔细看)。如果是这样的话,那么我觉得titan也可以同样的方式实现,毕竟tidb也叫ti db

gotoxu avatar Jan 21 '20 02:01 gotoxu

实现是工程问题,不是阻碍。问题是想清楚为啥要这样做。

arthurkiller avatar Jan 21 '20 03:01 arthurkiller

@arthurkiller 站在我的角度

  • Redis数据结构和RESP协议解析是可以重用的,不需要和TiKV的sdk进行绑定,这样当我需要实现一个基于磁盘KV并兼容Redis协议的系统而言,我只需要实现通信层即可,不需要从头再实现一遍。

  • 对于用户而言,也许我已经有一个稳定运行的分布式磁盘KV系统,我不需要为了对接Redis而重新启用一套新的KV系统,这样会增加我的运维成本。

  • 便于切换。假如我发现有新的磁盘KV系统更适合我的需求,或者性能更强大, 我可以更快速的切换到新的系统上,而不需要做大量修改。

基于此,我个人建议可以考虑抽象titan的通信层,避免重复造轮子。

gotoxu avatar Jan 21 '20 08:01 gotoxu

@gotoxu 你们的存储具体是什么样的?

shafreeck avatar Feb 03 '20 03:02 shafreeck

https://apple.github.io/foundationdb/

FoundationDB 看起来是可以作为一个 TiKV 替换的 KV 层的。

shafreeck avatar Feb 07 '20 04:02 shafreeck

@shafreeck 抱歉这么久才回复,今天才开工。我们使用的是nebula的底层KV存储,目前还不支持分布式事务,不过为了兼容titan可以mock一下。

gotoxu avatar Feb 10 '20 10:02 gotoxu

@gotoxu 没有事务的话,可能无法保证正确性,实现起来比较困难。具体可以参考这里的讨论https://github.com/distributedio/titan/issues/186

shafreeck avatar Feb 10 '20 15:02 shafreeck

@shafreeck 这个问题我看了,我们现在也在纠结是否需要更换实现了分布式事务的KV存储,我们内部先讨论一下。

gotoxu avatar Feb 10 '20 16:02 gotoxu

回到抽象接口这个问题,#186 中提到了 Pika 的解决方案。 我突然意识到 Titan 其实也可以实现类似 Pika 的系统,问题的关键在于 Titan 底层接入的存储引擎是什么,这个引擎可以是内存存储,单机存储,或者分布式存储。

可能的选择有:

如果 titan 后端接入的是 badger,那他就是一个单机的基于硬盘的存储系统(类 Pika),如果接入的是 foundationdb 或 TiKV,就是一个分布式存储系统。

shafreeck avatar Feb 10 '20 16:02 shafreeck

无论对接的是一个单机存储,还是分布式存储,Titan提供的抽象接口应该是一致的。也即,Titan不应该关心底层的存储对象是什么,只要该存储能够实现Titan需要其提供的API,那么就可以进行对接。

gotoxu avatar Feb 13 '20 01:02 gotoxu

我这边正在实现一个基于通用kv存储的redis协议兼容的方案,目前已经实现string/hash相关命令,当前底层支持hbase、tikv、obkv,也可以自己替换,欢迎大家加我微信一起讨论哈(微信:hdnxttl)

项目地址:https://github.com/netease-im/camellia 项目文档:https://github.com/netease-im/camellia/blob/master/docs/redis-proxy/kv/kv.md

@gotoxu @shafreeck

caojiajun avatar Apr 30 '24 01:04 caojiajun