Aerospike - 存储*少量*大值

时间:2015-11-09 19:33:34

标签: aerospike

方案
假设我每个用户最多存储5个字节的数组,每个50kB

可能的实施:

1)每个记录一个字节数组,由二级密钥索引。
优点:快速读/写。
缺点:高基数查询(每个查询最多5个结果)。如果经常访问字节数组,则水平缩放不佳
2)单个记录中的所有字节数组都在单独的容器中
优点:快速阅读
中性:Blockize必须大于250kB
缺点:慢速写入(一次更改意味着重写所有字节数组)
3)将字节数组存储在LLIST LDT中
优点:避免解决方案(1)和(2)的缺点 缺点:LDT通常很慢
4)将每个字节数组存储在一个单独的记录中,键入UUID。将UUID列表存储在另一条记录中。
优点:写入每个字节数组不需要重写所有数组。二级索引没有低基数问题。避免使用LDT 缺点:客户端读取是2阶段:从元记录中获取UUID列表,然后为每个UUID获取多个获取(非常慢?)

5)使用预先确定的主键方案(例如userid_index,例如123_0,123_1,123_2,123_3,123_4)将每个字节数组存储为单独的记录 优点:避免两阶段阅读 缺点:与另一个用户的理论冲突可能性(例如,user1_index1和user2_index2产品相同的哈希)。我知道这是(非常,非常)低概率,但避免仍然是首选(假设一个用户能够读取由于冲突导致的另一个用户的字节数组。)

我的评价
对于平衡读/写或高读/低写情况,请使用#2(一个记录,多个容器)。重写成本更高,但避免了其他缺点(LDT惩罚,2阶段读取)。

对于高(重)写/低读的情况,使用#3(LDT)。这样可以避免在更新其中一个字节数组时重写所有字节数组,因为记录是写时复制的。

问题
考虑到当前的数据模式(少量,大型对象),哪种实现更可取?你同意我的评价(见上文)吗?

1 个答案:

答案 0 :(得分:4)

这是一些输入。 (我想透露我在Aerospike工作)。

避免#3。不要使用LDT,因为该功能肯定不如平台的其他部分那么成熟,特别是在节点离开/加入集群时,在群集重新平衡(迁移)情况下的性能/可靠性时。

我会尝试尽可能多地使用基本的键/值交易。这应该始终是最快和最具可扩展性的。正如您所指出的,选项#1不会扩展。二级索引在内存中也有开销,目前不允许快速启动(仅限企业版)。

对于高写入负载,你在#2上也是正确的,特别是如果你要总是更新1个bin ...

因此,这留下了选项#4和#5。对于选项#5,在实践中不会发生碰撞。你可以通过数学,它根本不会发生。如果确实如此,你就会出名并可以发表论文:)(甚至可能有发现碰撞的代价)。此外,请注意,您可以选择在记录中存储密钥,这将为您提供密钥检查'在写入时应该非常便宜(因为在写入之前无论如何都要读取记录)。选项#4也可以工作,它只会进行额外的读取(应该超快)。

这一切都取决于你想要的位置更复杂。因此,如果您在决定之前拥有这种奢侈品,那么您可以在两个选项之间进行一些简单的基准测试。