我正在阅读Aerospike的文档。并发现,为了存储主键,Aerospike使用散列和散列指向BTree,bTree包含指向实际记录的指针。 据我所知,Redis只使用散列(对于冲突解决,它们维护一个哈希列表)。并且hash指向实际记录。
空中飞人使用Btree有什么好处?是不是意味着通过其主键airospike访问记录需要O(logn)?而redis只需要O(1)。
我可能错了,但这是我从documentation理解的。请问有人可以对这个话题有所了解。?
答案 0 :(得分:5)
我不确定问题的关键点,但这里是:
实际上,Aerospike的primary index是red-black trees的分布式哈希值,每个分区1到4096 sprigs之间(请参阅partition-tree-sprigs
配置参数)。
在群集的节点上有4096个逻辑分区evenly distributed。标识任何record的密钥是通过将(namespace, set, PK)
3元组通过RIPEMD-160(客户端自动为您执行)生成的20字节摘要。记录始终散列到特定分区,因为此摘要中的位用于计算分区ID。
与设计为在单个节点上运行的单核,单线程应用程序的Redis相反,Aerospike是作为分布式数据库构建的。用户可以使用应用程序端解决方案或中间件来临时集群Redis,这是事实。对于Aerospike,集群中的所有节点以及所有客户端共享partition map。
由于客户端知道群集的分区映射,因此它始终距离持有主分区的节点(或保存副本分区的节点)一跳 - 这由replica read policy控制)。因此,它是集群中正确节点的O(1)。在该节点内,O(1)找到分区的rbTree,然后所有操作都是O(log n)。
当hash table中没有大量数据时(假设你对Redis使用的数据结构是正确的),找到一条记录应该是O(1)。但是,一旦哈希表中的元素多于插槽,它就会切换到链接列表,即O(n)。对于rbTree,它是平均和最差情况下的O(log n)。 Aerospike旨在处理具有可预测的低延迟的大型数据集,因此rbTree更合适。无论集群中的数据量如何,获取记录的成本都是相同的。
添加:从Aerospike DB版本4.2开始,sprigs在内存方面变得便宜得多,并且每个分区的4096个sprigs的限制已被删除。通过分配足够的sprigs,您可以有效地将sprigs转换为深度为1的红黑树,因此O(log n)可以与O(1)实际上相同。例如,如果您希望sprigs的平均树深度为1,并且数据库中有十亿个对象,则将partition-tree-sprigs
设置为262144(必须是2的幂),这将花费848MB均匀分布到节点(3节点集群中283MB)。