使用Aerospike客户端进行查询的最佳方法是哪种?

时间:2020-08-02 08:13:38

标签: java primary-key aerospike bins

我有一套(set1)

bins:

bin1(PK = key1)

bin2(PK = key1)

bin3(PK = key2)

bin4(PK = key2)

从以下两种方法中更优化的方式(就查询时间,CPU使用率,1个客户端调用与2个客户端调用的失败情况而言)是从aerospike客户端查询数据的方式: < / p>

方法1:使用具有bins = [bin1,bin2,bin3,bin4]和键= [key1,key2]的aeropsike客户端拨打1个电话

方法2:使2个Aerospike客户接到电话。第一次呼叫将具有bins = [bin1,bin2]和键= [key1],第二次呼叫将具有bins = [bin3,bin4]和键= [key2]

我发现方法2更干净,因为在方法1中,我们将尝试获取所有组合的记录(例如:以key2作为主键的bin1),这将是额外的计算并且主键集可能很大。但是方法2的缺点是有两个Aerospike客户呼叫。

1 个答案:

答案 0 :(得分:1)

A。批量读取与多次单个读取

这是一个错误的选择。是的,您可以对[key1,key2](1)进行批量调用,并且您不应该指定bin1,bin2,bin3,bin4,只获取完整的记录而不选择bin。或者,您可以进行两个独立的get()调用,一个用于key1,一个用于key2(2)。

但是,没有理由您不需要读取key1,等待结果,然后读取key2。您可以在一个线程中使用同步get(key1)来读取它们,而在另一线程中使用同步get(key2)来读取它们。 Java客户端可以处理多线程使用。另外,您可以异步获取get(key1),然后立即异步获取get(key2)。

当记录的数量至少小于集群中节点的数量时,分批读取(如(1)中的)效率不如单次读取。记录是均匀分布的,因此,如果您有4个节点的群集,并且使用4个键发出批处理请求,则最终会得到每个节点大约1条记录的并行子批处理。在这种情况下,与批读取相关的开销是不值得的。在文档和知识库batch index中详细了解FAQ - batch-index tuning parametersFAQ - Differences between getting single record versus batch应该回答您的问题。

B。 Aerospike数据库中的记录数量不会影响读取性能!

您担心“主键集可能很大”。对于Aerospike来说,这根本不是问题。实际上,关于Aerospike的最好的事情之一就是,从具有100万条记录的数据库中获得一条记录或从具有1万亿条记录的数据库中获得一条记录几乎与big-O计算成本相同。

每个记录在primary index中都有一个64字节的元数据条目。由于data distribution in Aerospike非常均匀,因此主索引均匀分布在群集的各个节点上。在群集中每个名称空间的4096个逻辑分区中,每个节点平均存储分区。分区表示为红黑二叉树(sprigs)的集合,并带有指向正确小枝的哈希表。

要查找任何记录,客户​​端会将其密钥哈希为20字节的摘要。客户端使用摘要的12位查找分区ID,在本地保存的分区图中查找分区ID,然后找到正确的节点。现在,读取记录就是到正确节点的单跳。在该节点上,服务线程从网卡的通道中接听呼叫,并在正确的分区中查找它(再次,从摘要中找到分区ID是简单的O(1)操作)。它直接跳到正确的分支(也为O(1)),然后对记录的元数据进行简单的O(n log n)二叉树查找。现在,服务线程只需一个读取IO即可确切知道在存储中的哪里找到记录。我更详细地解释了此读取流程here(尽管在4.7版中,删除了事务队列和线程;服务线程完成了所有工作)。

另一点是,在索引中查找记录元数据所花费的时间比从存储中获取记录要少几个数量级。

因此,集群中的记录数不会改变从任意大小的数据集中读取随机记录所花费的时间。

我写了一篇文章Aerospike Modeling: User Profile Store,展示了如何利用这一事实从PB级数据存储中以每秒百万次的事务读取亚毫秒级的数据。