如何在Cassandra中创build自动增量ID

我们知道在SQL数据库中创build自动增量标识很容易,在Cassandra中是否有一个很好的解决scheme? 这些ID应该是键名或列名。

在分布式系统中创build一个全局的序列号码并没有什么意义。 使用UUID。
(因为你必须让所有的参与者同意并接受序列的演变 – 在一个天真的实现下)

如何使用Cassandra的Lightweight交易

1 – 创buildID表:

CREATE TABLE ids ( id_name varchar, next_id int, PRIMARY KEY (id_name) ) 

2 – 插入你想使用全局序列的每个ID

例如:

 INSERT INTO ids (id_name, next_id) VALUES ('person_id', 1) 

3 – 然后,当插入到您想要使用自动递增键的表格中时,请执行以下操作:

3.1 – 从ID表获取next_id:

 SELECT next_id FROM ids WHERE id_name = 'person_id' 

假设结果是next_id = 1

3.2 – 递增next_id,方法如下:

 UPDATE ids SET next_id = 2 WHERE id_name = 'person_id' IF next_id = 1 

结果应该是这样的:

 [{[applied]: True}] 

如果更新成功,或者

 [{[applied]: False, next_id: 2}] 

如果别人已经更新它。

所以,如果你真的,使用id'1' – 这是你的。 否则,增加next_id(或仅使用返回的next_id)并重复该过程。

没有好的解决scheme。

  1. 创build一个数字列,增加数量,并将其与所有副本一起保存到临时ID,读取所有副本,并检查临时ID是否是“你的”,如果不是这样做再次..不是一个很好的解决scheme,不会规模。

要么

  1. build立你自己的id服务,你获取你的下一个id。 这个服务只能在一个实例中运行,并且是一个不缩放的可怕因素。

一旦任何事情超出了一个实例,id的顺序变得复杂,至less如果你想要它的规模。 这包括关系数据库。

有一个可以使用的计数器数据types。 考虑下面的例子。

 CREATE KEYSPACE counterks WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'datacenter1' : 3 }; 

为计数器列创build一个表。

 CREATE TABLE counterks.page_view_counts (counter_value counter, url_name varchar, page_name varchar, PRIMARY KEY (url_name, page_name) ); 

将数据加载到计数器列中。

 UPDATE counterks.page_view_counts SET counter_value = counter_value + 1 WHERE url_name='www.datastax.com' AND page_name='home'; 

看看柜台的价值。

 SELECT * FROM counterks.page_view_counts; 

输出是:

  url_name | page_name | counter_value ------------------+-----------+--------------- www.datastax.com | home | 1 

增加柜台的价值。

  UPDATE counterks.page_view_counts SET counter_value = counter_value + 2 WHERE url_name='www.datastax.com' AND page_name='home'; 

看看柜台的价值。

  url_name | page_name | counter_value ------------------+-----------+--------------- www.datastax.com | home | 3 

有关更多详细信息,请参阅: http : //docs.datastax.com/en/cql/3.1/cql/cql_using/use_counter_t.html

这个问题很老,但我想用其他解决scheme来完成。

任何依靠节点同步的解决scheme都是不合理的。 通过阻止ID生成或通过创build重复的ID,非常肯定会中断。

MySQL的方式

您可以使用auto_increment_incrementauto_increment_offset参数重现mysql master-master复制的方式。

要重现它,您需要知道节点的数量或预期节点的最大数量,并且您需要在每个节点上创build一个(非cassandra)计数器(每个示例为一个文件)。

每当你想要生成一个新的号码,你会发现当前值,添加增量并保存。 如果它还不存在,那就是抵消。

因此,对于10个节点,增量为10,第一个节点的偏移量为1,第二个节点的偏移量为2,等等。节点1将创buildID 1,11,21。节点2将创buildID 2, 21,22。

如果您希望您的ID在节点之间(近似)sorting,则需要维护共享计数器,并确保每个生成的ID高于共享计数器。 这样,除非你的节点/数据中心长时间不同步,否则你不应该注意到太多的区别。

前缀

通过在节点编号(或名称)前添加ID(如果是可接受的解决scheme),您可以做基本相同的事情。 而且您不必知道节点的数量。 节点1将创build1_1,1_2,1_3。 节点2将创build2_1,2_2,2_3。

编辑:这个解决scheme是不正确的。 看到第一个评论。

我的解决scheme

1 – 创buildID表:

 CREATE TABLE ids ( id_name varchar, next_id counter, PRIMARY KEY (id_name) ) 

2 – 当您想要使用自动递增键的表格中插入时,请执行以下操作:

2.1 – 增量计数器(如果不存在,将被创build),使用最高的一致性级别

 UPDATE ids SET next_id = next_id + 1 WHERE id_name = $AUTO_INCREMENTED_ID USING CONSISTENCY ALL 

2.2 – 获取新的ID值:

 SELECT next_id FROM ids WHERE id_name = $AUTO_INCREMENTED_ID 

2.3 – 用自动递增的ID插入值

 INSERT INTO some_table ($AUTO_INCREMENTED_ID, ...) VALUES ($RESULT_FROM_PREVIOUS_QUERY, ...) 

在我的答案中以'$'开头的单词是不言自明的(我希望)占位符…

当然这不是推荐的方法。 只有必要时才使用它。

他们真的需要顺序吗?还是只需要计算比UUID小得多的数字呢?

如果您确实需要连续编号,那么您将需要执行以下操作之一。

  • 在cassandra中有一个表,其中key / id是生成器的字段,值是一个数字…在循环中执行条件更新,直到成功递增计数为止。 (馊主意)

  • 有一个发电机服务,会给你下一个号码。 这只能在单个系统上运行,并且是单点故障,但根据您的需求,这可能是最好的。

或者…与第一个类似,但一次获得100个左右的数字,并在你的进程/线程中处理这些…这将有较less的争用,但不保证顺序,唯一性。如果你只想要更短的数字是唯一的显示,这可能是你最好的select。

我想恕我直言,希望卡桑德拉提供一个自动增量本身是错误的

卡桑德拉是一个分散的数据库,因此它提供了一个自动增长的领域是征税和挫败目的,因为这个价值必须在一个中心的地方

因此,不要做任何基于DB的解决scheme来获得一个自动递增的数字

实例在您的应用程序中创build一个ID代码或服务,它可以继续生成随机唯一的ID并将其用于保存在您的数据库中,这样Cassandra的目标和好处将不会被打败