内存数据库索引

  记得早前第一份工作的时候,很得意自己能写非常庞大的存储过程,聊起天来就是怎样引用索引、怎么写sql快;想想那时候多好,容易满足,容易开心,开怀大笑!

  还是在前年的时候,忙完一个大项目之后!刚好有点时间研究fastdb,因为早期没用商用数据库之前就是用的这个。后来发现并发能力的问题,才切换到商用数据库。

  如果单从数据读写能力来看,fastdb无疑具有非常强的竞争力;我记得几年前测试fastdb查询能力就比timesten的速度快非常多,但是关键在于fastdb在进程并发的时候就变的很慢。因为fastdb并不是行级锁,而是表锁+库锁,多进程时候冲突增加的情况下性能跟不上。

  fastdb有两种索引,hash索引和T-tree索引。

  hash索引采用分桶的方式,数据和分桶数达到一定比例就从新分配桶,以保证hash结果能得到一个比较精确匹配的值,这样才能保证hash索引的效率。他的实现其实和stl里面的hash实现基本一样,我觉得它的缺点和优点都很明显:

  a、如果数据不能保证key是唯一的,那么大量的重复key将会导致hash性能直线下降

  b、上述缺点其实也是优点,如果能保证key唯一。那么hash效率无疑比较好的算法选择

  c、hash从新分配桶的时候,性能明显变慢。而且其占用空间也比较大

  我今天主要是要记录关于T-tree索引的理解。11年的时候刚开始接触内存数据库,开始在网上搜相关资料,很惊奇的发现大量的文章在论证为何内存数据库用的是T-tree而传统的物理数据库用的是B+tree。依据主要是以下两点

  a、很多的文字在描述T-tree的效率理论上就比B-tree要高,虽然时间复杂度都是log2n,但那是基于时间复杂最坏打算来说的;而数据库索引T-tree查询只有一半的概率查询需要到最坏情况,而且一半情况下可以提前查询到结果。

  b、物理数据库选择B+tree一个重要原因是磁盘换入换出,而内存数据库不存在这种需求。

  不知道是不是基于这个理论,当时我所接触的几个数据库都是采用了T-tree索引,timesten、altibase、fastdb等几个无一例外。

 

  等到前年去尝试改造fastdb的时候,把数据库改成行级锁,其中重要一部分就是T-tree索引的支持。基于上述理论,我开始不断的coding+test,很长一段时间都没有得到理想结果。其中我觉得最难解决的问题是,T-tree索引在插入一个数据之后,节点分裂无法控制其父节点影响的层次。这种情况下,我只能无限的递归去锁定上层节点父节点,最终锁定的你会发现是跟节点,所以我想这就是当时fastdb为何只能做到表锁的根本原因。

  我无法确定timesten这些公司的人是怎么实现这种情况下的并发,除非他们有大量的松耦合逻辑来辅助这颗索引树来完成互斥的功能。

  很幸运公司来了一个韩国数据库的团队(据说是大佬从altibase挖出来的核心团队)来交流产品,更幸运的是领导让我来接待他们,陪他们测试和交流技术,跟我们在用的timesten进行了对标。他们总结的优势在于:

  1、国产的,虽然是棒子做的。但是boss是中国大佬(那时候刚好掀起去IOE的风潮)

  2、性能高,比市面上的主流数据库产品性能都高。还有一大批的性能对比测试报告(相当专业)

  3、复制代理性能高,基于他们高速网络框架能够实现实时的数据同步。(有接触过高可用产品的人都知道,这一点至关重要。但是不能确定他们是不是吹的)

  另外,他们不否认的一个点是,现在市面上商用少,说国内有一个金融产品的点;主要还是在韩国用。

  基于他们说的这些,我们进行了一些测试。基于这些测试数据,倒是对他们产品有一些了解。首先是并发性能好,对比timesten完全不是一个等级的,在3个进程以内,两者持平,但是进程数越多就越明显。后来我和他们来的韩国专家(当然有翻译,完全装不起来B)交流,他们用的是B-tree,我问他怎么不用T-tree。棒子专家说了足有半小时,但是翻译兄弟给我的结果是:他们原来用的是T-tree,后来改成B-tree了,他们有历来的测试报告。至于原因,翻译兄弟说他翻不过来了。。。后来还叨叨了很多其他的,经过翻译兄弟的嘴之后,索引互斥锁、复制代理啥的。感觉收获不多(语言太重要!!)

  经过这次交流,开始重新审视两颗树的差异,发现其实T-tree在索引更新时搞不定的问题用B-tree完全可以解决。因为B-tree在分裂的时候,没有旋转的概念,而且他可以确定分裂节点的父节点以上就不需要变更,基于这点就可以实现B-tree的互斥索引了。

  于是我另外有一个发现,timesten11版本已经把T-tree索引改成了B-tree索引,而且新的内存数据库像sqlite也用的是B-tree。但是网上很难找到相关的论证文章。

  不过不管如何,那时候已经决定从T-tree改成B-tree了,又开始了一个周期的coding+test。不断的修改和测试,这个小小的B-tree已经为我搞定了行级索引锁的问题测试了几百万数据,几个进程并发的情况下,3w/s的插入,查询20w+/s。。问题仍然存在,性能太差了。但是能帮我验证写的其它数据库管理代码,索引确实是个问题,希望后面能找到其它灵感吧

  

posted @ 2016-05-26 20:51  一介莽夫  阅读(512)  评论(1编辑  收藏  举报