内存数据库索引
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存数据库索引相关的知识,希望对你有一定的参考价值。
记得早前第一份工作的时候,很得意自己能写非常庞大的存储过程,聊起天来就是怎样引用索引、怎么写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。。问题仍然存在,性能太差了。但是能帮我验证写的其它数据库管理代码,索引确实是个问题,希望后面能找到其它灵感吧
以上是关于内存数据库索引的主要内容,如果未能解决你的问题,请参考以下文章