1

我正在尝试找到一种好方法来组织我的行键以对它们执行范围扫描,而无需创建自己的索引列表。

我有一个 MySQL 数据库,目前大约有 15.000 个数据库,每个 ~50 个表 = 75.000 个表。因为 99% 的数据始终使用唯一标识符读取,因此计划将数据移动到 Cassandra 集群中。

对于某些维护(列出完整表的内容、删除完整表或删除数据库)的情况,我需要获取完整表甚至数据库的内容。Range-Scans 似乎非常适合这种情况。

目前,我正计划为旧结构的每个部分生成 UUID,并将它们放在一起,用|(DB + Table + Id = UUID1|UUID2|UUID2) 分隔。

例子:

07424eaa-4761-11e1-ac67-12313c033ac4|0619a6ec-4525-11e1-906e-12313c033ac4|0619a6ec-4795-12e9-906e-78313c033ac4

带有数据的 CF 应使用 排序org.apache.cassandra.db.marshal.AsciiType

作为客户端,我正在使用 phpcassa。

对于范围扫描,我想使用一个UUID|作为开始键和作为范围的结束,相同的键但带有chr(255)z附加到它。这两个字符的 ascii 值大于该键中跟随的任何其他 UUID 字符。

这是一种可靠的方法,可以让我实现范围扫描的解释目标吗?

4

1 回答 1

5

Cassandra 的最佳实践是使用 RandomPartitioner - 只要您的令牌均匀分布,这将为您提供“免费”负载平衡。不幸的是,使用随机分区器,行范围查询(即 get_range_slices)以随机顺序返回键。

这适用于对整个列族进行分页(如果这是您想要的,那么您的方法将起作用)。但是,如果您只想通过较小的、连续的行键范围进行分页,则它将不起作用。

解决此问题的一种选择是使用宽行和复合列。例如,如下所示的列族:

{ 
  row1 -> {column1: value1, column2: value2},
  row2 -> {column3: value3, column4: value4},
  ... 
}

将被转置为如下所示:

{
  row1-10 -> {
              [row1, column1]: value1, [row1, column2]: value2,
              [row2, column3]: value3, [row2, column4]: value4,
              ...
             }
  ...
}

您可以通过在右列之间的右行上执行列切片 (get_slice) 来执行范围查询。IE

get_range_slice(start=row1, end=row2)

变成:

get_slice(row=row1-10, start=[row1, null], end=[row2, null])

请注意列键上的空第二维。

The trick is to pick your row ('bucket') keys such that your columns won't grow too large (this will perform badly for normal Cassandra), but that you queries won't need to get too many rows. This will depend on your average query size, and the distribution of your uuids, but a good candidate might be to use UUID1 as the row keys and [UUID2, UUID3] as the first dimensions of the column keys.

于 2012-01-31T20:49:39.947 回答