使用Cassandra

时间:2016-10-17 14:06:27

标签: cassandra

我正在试图弄清楚如何使用Cassandra实现URL缩短服务。我有:

  • 3个cassandra节点(在Docker上)
  • 将base10编码为base62号码(字符串)的功能

例如:

1 => a, 2 => b, 1205 => JR

这种方法的问题是我需要确定总是给出一个唯一的(递增的数字),以便下一个函数调用将给我一个唯一的字符串。

CREATE TABLE urls (
  id int PRIMARY KEY, // 1215 (auto increment)
  short_key text, // calculated short string from 1215
  url text, // real url
  created_at timestamp
) WITH CLUSTERING ORDER BY (created_at DESC);

使用DESC clustering,我总能从行中获取最后一个ID。这几乎没有问题:

  1. 在每次写入之前读取一行
  2. 如果你有很多写作,那么全部 服务器必须知道下一个号码,即
  3. 你会如何解决这个问题?我已经尝试使用谷歌搜索解决方案,但在每个解决方案中我都找到了瓶颈。此外,哈希不是一种选择。

2 个答案:

答案 0 :(得分:0)

您正在尝试处理分布式计数器。正如您刚刚发现的那样,它们很难,而C *也不会解决这个问题,即使使用其counters版本也是如此,因为您无法更新同时计数器值。

我不是专家,但我建议您查看一些排队系统,例如RabbitMQActiveMQKafka仅举几例

答案 1 :(得分:0)

我不确定哪种性能对您有用,但我可以根据Cassandra建议以下解决方案:

您可以为每个用户服务器保留单独的计数器。每个服务器都分配了一个从1到62的唯一ID(我想在你的情况下62个服务器就足够了)。 id存储在服务器配置中的某个位置。您创建一个计数器表:

CREATE TABLE uniquecnt (
serverid int PRIMARY KEY,
cnt counter
) PRIMARY KEY (serverid)

当服务器启动时,它会通过自己的id读取计数器值,并在每次请求新的id时将其递增到内存中。还有必要在Cassandra增加计数器。如果对Cassandra的更新毫无例外地通过,则该值可用于生成URL。 (更新Cassandra时也至少使用Quorum一致性级别。)

对于url生成,你必须使用一种连接 域+" /" + base62(serverId)+ base62(counterValue)

在这种情况下,您的网址会更长(1个字母),但问题已解决。

这里我假设您能够在事务之间将每个服务器的内存中保持计数器状态。此外,您不应在一台服务器的范围内并行更新计数器。

(一般来说,你甚至不必使用计数器类型的表。它也可以使用简单的表。)