0

我有两个 postgres 数据库,必须在这些数据库之间同步相同的表(不是全部,只是其中几个)。

这会产生同步问题,如果我有表 A 和表 B(相同的结构,只是在不同的数据库中),如果有人插入表 A,则 pk id 可能是 5,但随后,有人可能会在表 B 上插入,得到pk id 也是 5。

在同步两个表时,我可能会发现两个寄存器具有相同的 pk,但内容不同。

我很确定必须有解决方案,必须有一个聪明的方法来保持 ids 同步。

到目前为止,我正在考虑创建一个简单的 web 服务,它将提供一个新的有效 pk id,但是这是有问题的,因为

1-它会减慢进程 2-它只是将问题转移到 Web 服务,Web 服务将如何找到下一个有效 id?

过去有没有人遇到过类似的问题?

环境是postgres 9.1

4

1 回答 1

2

是的,人们经常遇到这种情况。您需要问的问题不是“我该怎么做”,而是“现有的广为人知和成熟的方法中哪一种最适合我的需求”。

研究用于在分片和分布式数据库中生成密钥的解决方案。

选项包括:

  • 为每台机器分配不重叠的 ID 范围。一种常见的方法是将序列设置为以(例如)100 为单位递增,并为每台机器提供唯一的偏移量,因此机器 A 生成 101、201、301、401 等,机器 B 生成 102、202、302、402 , ... . 在您需要添加机器 #101 之前效果很好。您可以使用 bigint 密钥并为 10,000 台机器留出空间;这样,当您达到此限制时,无论如何您将重新设计整个系统三遍。

    (在您说“我将用完密钥”之前... max bigint 对于922337203685477580710000 台机器范围而言,您正在查看每台机器的每个表大约 10 15或 2 50 个键,这大约是一个 21 PB 的表每条记录 25 个字节,包括开销,即非常小的记录)。

  • 使用复合主键,如(machine_id, locally_generated_sequence_id). 除非您正在处理坚持使用单值主键的脑残 ORM,否则是理想的。

  • 对数据类型使用巨大的随机主键 (UUID)uuid,提供 128 位空间和绝对极小的冲突概率。在大多数情况下都可以正常工作,尽管生日悖论碰撞非常不寻常。偏执狂可以制定处理碰撞的计划。

  • 使用通用服务生成大块密钥。不经常调用它并将可用的密钥存储在本地。由于密钥表上的锁争用,这往往会妨碍每个节点上的并发写入性能,所以我不推荐它。

  • ...可能更多我不记得或从未听说过。

最简单的选择通常是分配不重叠的 ID。这很简单,它是透明的,而且很有效。

于 2013-04-04T06:38:28.680 回答