Sth*_*the 12 php distributed couchbase
我一直在浏览网络,试图找到一个允许我们在区域分布式环境中生成唯一ID的解决方案.
我查看了以下选项(以及其他选项):
SNOWFLAKE(Twitter)
UUID
与MYSQL类似的关系数据库中的自动编码
像COUCHBASE一样的非关系数据库中的自动识别
假设我们在5个不同的地区(非洲,欧洲,亚洲,美洲和大洋洲)拥有由10个Couchbase节点和10个应用节点组成的集群.这是为了确保从最靠近用户的位置提供内容(以提高速度)并在发生灾难时确保冗余等.
现在,任务是生成在复制(和平衡)发生时不会发生碰撞的ID,我认为这可以通过3个步骤实现:
步骤1
将为所有区域分配整数ID(唯一标识符):
第2步
为添加到群集的每个应用程序节点分配一个ID,记住一个群集中最多可能有99 999个服务器(尽管我怀疑:这是一个安全的预防措施).这看起来像这样(假IP):
请注意,所有这些都在同一个集群中,这意味着您可以在每个区域拥有节点00001.
第3步
对于插入数据库的每个记录,将使用递增的ID来标识它,这就是它的工作方式:
Couchbase提供了一个增量功能,我们可以使用它在群集内部创建ID.为确保冗余,将在群集中创建3个副本.由于它们位于同一个地方,我认为应该可以安全地假设除非整个群集关闭,否则将有一个负责此节点的节点,否则可以增加许多副本.
将它们整合在一起
假设用户正在从欧洲注册:服务请求的应用程序节点将获取区域代码(在这种情况下为4),获取自己的ID(比如00005),然后从Couchbase 获取增加的ID(1)(来自相同的)簇).
我们最终有3个组成部分:4, 00005,1
.现在,要从中创建ID,我们可以将这些组件加入其中4.00005.1
.为了使它更好(我对此不太确定),我们可以连接(而不是添加它们)组件以结束:4000051
.
在代码中,这将看起来像这样:
$id = '4'.'00005'.'1';
NB:没有$id = 4+00005+1;
.
优点
缺点
我知道每个解决方案都有缺陷,可能更多的是我们在表面上看到的.你能发现这整个方法的任何问题吗?
预先感谢您的帮助 :-)
编辑
正如@DaveRandom建议的那样,我们可以添加第4步:
第4步
我们可以生成一个随机数并将其附加到ID以防止可预测性.实际上,你最终得到这样的东西:
4000051357
而不仅仅是4000051
.
我认为这看起来很扎实。每个区域都保持一致性,如果您使用 XDCR,则不会发生冲突。INCR 在集群中是原子的,因此不会有任何问题。您实际上不需要其中包含机器代码部分。如果一个区域内的所有应用服务器都连接到同一个集群,则中缀其中的 00001 部分是无关紧要的。如果这对您出于其他原因(某种分析)有用,那么无论如何,但这不是必要的。
所以它可以简单地是 '4' 。1'(使用您的示例)
你能举个例子说明你需要什么样的“排序”吗?
第一:添加熵的一个缺点(我不确定为什么你需要它)是你不能轻松地迭代 ID 集合。
例如:如果您的 ID 为 1-100,您可以通过 Counter 键上的简单 GET 查询知道,您可以按组分配任务,此任务需要 1-10,接下来的 11-20 等等,以及工人可以并行执行。如果添加熵,则需要使用 Map/Reduce 视图来下拉集合,因此您将失去键值模式的好处。
其次:由于您关心可读性,因此添加文档/对象类型标识符也很有价值,这可以在 Map/Reduce 视图中使用(或者您可以使用 json 键来标识它)。
例如: 'u:' 。‘4’。‘1’
如果您在外部引用 ID,您可能需要以其他方式进行模糊处理。如果您需要一个示例,请告诉我,我可以在我的答案中附加您可以做的事情。