2017-05-19 16 views

回答

6

从客户机到群集节点

在你应用程序中,记录的key是3元组(命名空间,集合,标识符)。对于所有键值方法(例如getput),密钥都被传递给client

然后,客户端散列(设置标识符)通过RIPEMD-160关键的部分,从而导致20B摘要。此摘要是您的Aerospike群集中指定namespace内的record的实际唯一标识符。每个名称空间都有4096个partitions,它们分布在集群的各个节点上。

客户端uses 12 bits of the digest确定此特定密钥的分区ID。使用分区映射,客户端查找拥有与分区ID相对应的主分区的节点。随着集群的增长,查找正确节点的成本保持不变(O(1)),因为它不依赖于记录数或节点数。

客户端将操作及其数据转换为Aerospike wire protocol消息,然后使用其池中的现有TCP连接(或创建一个新连接)将消息发送到正确的节点(持有该分区ID的主节点复制品)。

服务线程和事务队列

当操作消息到达作为NIC transmit/receive queue中断, 一个service thread拾取从NIC该消息。接下来会发生什么取决于这个操作应该执行的命名空间。如果它是内存中的命名空间,则服务线程将执行以下所有步骤。如果它是一个名称空间,其数据存储在SSD上,则服务线程将把该操作放在transaction queue上。队列的其中一个transaction threads将执行以下步骤。

主索引查找

每条记录​​在内存primary index一个64B的元数据项。主要指数表示为sprigs per-partition的集合,每个小枝被实施为red-black tree

线程(事务线程或服务线程,如上所述)从记录的摘要中找到分区ID,并跳到正确的分区分支。

存在,读取,更新,替换

如果操作是存在,一个,一个更新更换,线程获取记录锁定,在此期间,其他操作等待访问特定的小枝。这是一个非常短暂的锁。线程走过红黑树找到带有这个摘要的条目。如果操作是exists,并且元数据条目存在,则该线程将打包相应的消息并作出响应。对于读取,该线程将使用指针元数据来读取namespace storage中的记录。

更新需要按上述方式读取记录,然后合并bin数据。替换类似于更新,但是它跳过首先读取当前记录。如果名称空间在内存中,则服务线程将修改后的记录写入内存。如果命名空间存储在SSD上,则合并记录被放置在streaming write buffer中,等待存储设备的flush。调整主索引中的元数据条目,将其指针更新为记录的新位置。 Aerospike为创建/更新/替换执行写入时复制。

如果名称空间的replication factor大于1,则还需要将更新和替换传递给副本。在记录锁定过程之后,该操作也将驻留在RW哈希(串行器)中,而副本写入完成。这是同一条记录上的其他交易将排队等待直到他们达到transaction pending limit(也就是hot key)。副本写入由另一个线程(rw-receive)处理,释放事务或服务线程以转到下一个操作。当副本写入完成时,RW哈希锁定被释放,并且rw-receive线程将打包回复消息并将其发送回客户端。

创建和删除

如果操作是被写入一个新的记录,或记录被删除,分区小枝需要修改。

和更新/替换一样,这些操作获取记录级锁,并且将通过RW散列。因为他们从代表枝的红黑树中添加或删除元数据条目,所以他们还必须获取索引树缩减锁。当名称空间管理程序线程发现expired records并将它们从主索引中删除时,也会发生此过程。创建操作将向分区分支添加一个元素。

如果名称空间存储在SSD上,则create将把该记录加载到流写入缓冲区中,等待刷新到SSD,并且在副本写入之前。它将更新主索引中的元数据条目,并将其指针调整为新块。

删除操作会从主索引的分区分支中删除元数据条目。

摘要

  • 存在/读取抢记录级锁,并保持它的最短时间。当复制因子为1时,更新/替换的情况也是如此。
  • 更新/替换也复制RW哈希锁定,当复制因子高于1时。
  • 创建/删除也获取索引树还原锁。
  • 对于内存中的命名空间,服务线程完成所有工作,直到可能是副本写入点。
  • 有关SSD的命名空间数据服务线程抛出运行到一个事务队列,之后,其交易的一个线程处理的东西,如装载记录成数据流写入缓冲区写入,直到潜在的副本写入。
  • rw-receive线程处理副本写入并在更新/替换/创建/删除写入操作之后返回消息。

进一步阅读

+0

@ mohit-gupta这是否回答你的问题? –

+1

非常感谢Ronen对此进行了清晰而详细的解释。这是我正在寻找的。这应该是我认为的文档的一部分:)。几个后续问题: –

+0

1.是否都是树锁(我认为你把它们称为记录级锁)和减少锁独占?如果是这样,两种类型的锁有什么好处? 2.什么是“RW Hash(Serializer)”的数据结构。它是一个带有键的队列表表作为记录的键的哈希值,值是等待该记录的事务列表吗?如果是这样,在这种情况下如何处理并发性? 3.当发生副本关闭并且rw-接收线程超时的情况时尤其如此。关于“写入提交策略”。什么时候交易可以说是犯了? 再次感谢。 –

2

服务线程==事务队列== CPU中的内核数量或使用CPU固定 - 自动固定配置参数(如果适用于您的版本并且可能在您的操作系统环境中)。每queue-

交易线> 3(默认为4,对于objsize < 1KB,非数据在内存中的命名空间,3是最优的)

+0

这是好的,我想知道的工作。谢谢 –

+0

这就是Aerospike建议的 - 似乎是通过统一传播传入的事务工作负载来简单地利用每个核心,同时不会使其大于核心数量,以避免不必要的上下文切换。 – pgupta