设想以下情况:
有一个分布式键/值数据库存储在计算机网络上。一台用于获取请求的中央“主”计算机,以及用于存储部分数据的多台子计算机。 IE。像这样:
main computer
|
+--child A
+--child B
+--child C
.....
即“星形”拓扑。
补充说明:
- 部分数据库重叠,具有相同“键”的多个不同版本的记录可以同时存储在多台机器上。
- 不保证 key 存在于所有机器或特定机器上。
- “ child ”之间不同步数据。
- 仅通过主计算机请求/读取数据,主计算机必须为请求的 key 返回最新版本的数据。
- 数据仅通过 child 写入 - 他们从多个来源接收新值。
- 数据永远不会被删除。
现在的主要问题:
有了这样的结构,我如何确定哪个版本是最新的?
我可以想到两种方法来处理这个问题:
- 为每条记录添加时间戳,当写入数据库vial子机时,使用时间戳来判断版本。
- 使用“修订号”或“写操作索引”(由主机发布,每次写操作加一)代替时间戳。
然而,这两种方法都不是完美的:
第一种方法需要所有机器的完美时钟同步,否则系统将无法提供最新的记录值。
第二种方法会导致每个 child 通过网络向主机请求时间戳,这会引入写入延迟,而且主机必须被互斥体锁定,因此多线程性能会受到影响。
处理这种情况的更好方法是什么? 真正的集群数据库如何处理这种情况(集群中最近的记录版本)?
最佳答案
您关于第一种方法需要完美时钟同步的说法是不正确的。
你不关心 child 发出的绝对时间戳,只关心相对时间戳。所以只要时钟以相同的速率前进,它们就不需要同步;您可以更正已知的偏移量。
如果 children 的时钟以不同的速度前进,那么你必须使用一种涉及协调的方法(在慢速路径上写不能是无锁的)。这可以通过矛盾来证明,因为很明显,两个 child 独立写入一个带有时间记录的值,彼此之间无法关联,这不会让外部观察者确定哪个是后来写入的。
但是,您可以在实际写入的同时进行协调:写入子进程,同时写入一个有序日志,这样可以确定哪个写入先发生(您不需要像这样的票证类型系统你似乎建议你是否有写日志)。所以它根本不会耽误写作的过程!
看看逻辑时间戳键值系统,例如 Accumulo,它是一种 HBase 替代方案(目前正在 Apache 项目孵化中)- 这是真实世界的集群数据库,完全符合您的要求。
关于c++ - 聚集键/值数据库 : most recent record,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9046786/