Database design 在Cassandra中组织范围扫描的行键的方法

Database design 在Cassandra中组织范围扫描的行键的方法,database-design,cassandra,phpcassa,Database Design,Cassandra,Phpcassa,我正试图找到一种很好的方法来组织我的行键,以便在不创建自己的索引列表的情况下对它们执行范围扫描 我有一个MySQL数据库,目前大约有15000个数据库,每个~50个表=75.000个表。由于99%的数据总是使用唯一标识符读取,因此计划将数据移动到Cassandra集群中 对于某些维护(列出完整表的内容、删除完整表或删除数据库),我需要获取完整表甚至数据库的内容。距离扫描似乎非常适合这种情况 目前,我计划为旧结构的每个部分生成UUID,并将它们放在一起,用一个(DB+Table+Id=UUID1

我正试图找到一种很好的方法来组织我的行键,以便在不创建自己的索引列表的情况下对它们执行范围扫描

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

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

目前,我计划为旧结构的每个部分生成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.marshall.AsciiType
进行排序

作为客户,我使用phpcassa

对于范围扫描,我想使用一个
UUID |
作为开始键,作为范围的结束键,相同的键,但附加了
chr(255)
z
。这两个字符的ascii值都大于该键后面的任何其他UUID字符


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

Cassandra的最佳实践是使用RandomPartitioner-这可以实现“免费”负载平衡,只要令牌分布均匀。不幸的是,使用随机分区器,行范围查询(即get\u range\u 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,
              ...
             }
  ...
}
将被转换为如下所示:

{ 
  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_切片)来执行范围查询。即

get_range_slice(start=row1, end=row2)
变成:

get_slice(row=row1-10, start=[row1, null], end=[row2, null])
请注意,列键上的第二个维度为空


诀窍是选择行(‘bucket’)键,这样列就不会变得太大(这对于普通的Cassandra来说会很糟糕),但是查询不需要获得太多的行。这将取决于您的平均查询大小和UUID的分布,但一个很好的选择可能是使用UUID1作为行键,[UUID2,UUID3]作为列键的第一个维度。

Cassandra的最佳实践是使用RandomPartitioner-这可以实现“免费”负载平衡,只要你的代币分布均匀。不幸的是,使用随机分区器,行范围查询(即get\u range\u 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,
              ...
             }
  ...
}
将被转换为如下所示:

{ 
  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_切片)来执行范围查询。即

get_range_slice(start=row1, end=row2)
变成:

get_slice(row=row1-10, start=[row1, null], end=[row2, null])
请注意,列键上的第二个维度为空


诀窍是选择行(‘bucket’)键,这样列就不会变得太大(这对于普通的Cassandra来说会很糟糕),但是查询不需要获得太多的行。这将取决于您的平均查询大小和UUID的分布,但最好使用UUID1作为行键,[UUID2,UUID3]作为列键的第一个维度。

感谢您确认该方法到目前为止是可靠的。排序顺序与我无关,只有访问某些范围才重要。使用chr(255)或z字符作为查找范围的小助手是一个好主意吗?(缩写示例:af-07-01 | 39-ef-98 | 12-52-98…要获取所有从第一部分开始的关键点,开始关键点是af-07-01 |,结束关键点是af-07-01 | z),如果您需要访问子范围(而不是整个CF),那么您的方法将无法工作。CF中的所有行都是以随机顺序排列的,因此在两个键之间选择一个范围不仅会以随机顺序返回键,而且会返回不在该范围内的“逻辑”键,因为所有键都是以随机顺序排列的。感谢您回到这个问题!因此,该方法仍然需要手动索引或将数据分割成块。和更多的家庭一起工作怎么样?假设我创建了15000个ColumnFamilies以提供更简单的管理级别(每个数据库一个)?这是可行的替代方法吗?据我所知,这可能是一个很大的内存问题,因为Cassandra如何为每个CF分配内存。在当前版本中仍然是这样吗?感谢您确认该方法到目前为止是可靠的。排序顺序与我无关,只有访问某些范围才重要。使用chr(255)或z字符作为查找范围的小助手是一个好主意吗?(缩写示例:af-07-01 | 39-ef-98 | 12-52-98…要获取所有从第一部分开始的关键点,开始关键点是af-07-01 |,结束关键点是af-07-01 | z),如果您需要访问子范围(而不是整个CF),那么您的方法将无法工作。CF中的所有行都是以随机顺序排列的,因此在两个键之间选择一个范围不仅会以随机顺序返回键,而且会返回不在该范围内的“逻辑”键,因为所有键都是以随机顺序排列的。感谢您回到这个问题!因此,该方法仍然需要手动索引或将数据分割成块。和更多的人一起工作怎么样