Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在cassandra中使用多个集群列有什么主要缺点吗?_Cassandra_Geohashing - Fatal编程技术网

在cassandra中使用多个集群列有什么主要缺点吗?

在cassandra中使用多个集群列有什么主要缺点吗?,cassandra,geohashing,Cassandra,Geohashing,我正在设计一个cassandra表,我需要能够通过geohash检索行。我有一些有效的方法,但我想避免范围查询,这是我目前无法做到的 当前的表模式是这样的,geo_键包含geohash字符串的前五个字符。我使用geo_键进行查询,然后对完整的geohash进行范围筛选,允许我根据长度为5或更长的geohash为搜索添加前缀: CREATE TABLE georecords (geo_key text,geohash text, data text) PRIMARY KEY (geo_key, g

我正在设计一个cassandra表,我需要能够通过geohash检索行。我有一些有效的方法,但我想避免范围查询,这是我目前无法做到的

当前的表模式是这样的,geo_键包含geohash字符串的前五个字符。我使用geo_键进行查询,然后对完整的geohash进行范围筛选,允许我根据长度为5或更长的geohash为搜索添加前缀:

CREATE TABLE georecords (geo_key text,geohash text, data text) PRIMARY KEY (geo_key, geohash))
我的想法是,我可以将geohash的字符存储为单独的列,允许我指定任意数量的字符,以便在geohash上进行前缀匹配。我关心的是使用多个群集列可能会产生什么影响:

CREATE TABLE georecords (g1 text,g2 text,g3 text,g4 text,g5 text,g6 text,g7 text,g8 text,geohash text, data text) PRIMARY KEY (g1,g2,g3,g4,g5,g6,g7,g8,geohash,pid))
(我并不真正关心分区键的基数-g1至少有30个值,我还有其他解决方法)


除了分区键的基数和额外的存储需求之外,如果使用多集群列方法,我应该注意什么?

以下是我找到的最好的Cassandra建模指南:

我已经成功地将复合列(其中6列)用于非常高的写/读负载。使用compact storage()时不会造成明显的性能损失

紧凑存储意味着数据在内部存储在一行中,限制是只能有一个数据列。无论您选择哪种数据模型,这似乎都非常适合您的应用程序,并将最大限度地利用您的地理索引过滤

另一个要考虑的方面是列在卡桑德拉中排序。拥有更多的集群列将提高排序速度,并可能提高查找速度

但是,在您的情况下,我首先将geohash作为行键,然后打开行缓存以进行快速查找()。如果性能不足,我会在不同的数据表示上运行性能测试

除了分区键的基数和额外的存储需求之外,如果使用多集群列方法,我应该注意什么

这似乎是一个需要帮助解决的有趣问题,因此我构建了几个不同主键结构和选项的CQL表。然后,我常常提出一些端点,并插入它们

aploetz@cqlsh:stackoverflow> SELECT g1, g2, g3, g4, g5, g6, g7, g8, geohash, pid, data FROm georecords3;

 g1 | g2 | g3 | g4 | g5 | g6 | g7 | g8 | geohash      | pid  | data
----+----+----+----+----+----+----+----+--------------+------+---------------
  d |  p |  8 |  9 |  v |  c |  n |  e |  dp89vcnem4n | 1001 |    Beloit, WI
  d |  p |  8 |  c |  p |  w |  g |  v |    dp8cpwgv3 | 1003 |   Harvard, IL
  d |  p |  c |  8 |  g |  e |  k |  t | dpc8gektg8w7 | 1002 | Sheboygan, WI
  9 |  x |  j |  6 |  5 |  j |  5 |  1 |    9xj65j518 | 1004 |    Denver, CO

(4 rows)
正如您所知,Cassandra设计用于使用特定的、精确的键返回数据。使用多个集群列有助于这种方法,因为您可以帮助Cassandra快速识别您希望检索的数据

我想更改的唯一一件事是,看看您是否可以在主键中不使用
geohash
pid
。我的直觉告诉我要摆脱pid,因为它真的不是任何你可以查询的东西。它提供的唯一价值是唯一性,如果计划多次存储相同的geohash,则需要唯一性

pid
包含在主键中会留下一个非键列,这允许您使用
with COMPACT STORAGE
指令。实际上,唯一让您受益的真正优势是节省磁盘空间,因为集群列名没有与值一起存储。当从
cassandra cli
工具中查看表格时,这一点变得很明显:

没有紧凑的存储:

[default@stackoverflow] list georecords3;
Using default limit of 100
Using default cell limit of 100
-------------------
RowKey: d
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001:, value=, timestamp=1428766191314431)
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001:data, value=42656c6f69742c205749, timestamp=1428766191314431)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003:, value=, timestamp=1428766191382903)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003:data, value=486172766172642c20494c, timestamp=1428766191382903)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002:, value=, timestamp=1428766191276179)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002:data, value=536865626f7967616e2c205749, timestamp=1428766191276179)
-------------------
RowKey: 9
=> (name=x:j:6:5:j:5:1:9xj65j518:1004:, value=, timestamp=1428766191424701)
=> (name=x:j:6:5:j:5:1:9xj65j518:1004:data, value=44656e7665722c20434f, timestamp=1428766191424701)

2 Rows Returned.
Elapsed time: 217 msec(s).
[default@stackoverflow] list georecords2;
Using default limit of 100
Using default cell limit of 100
-------------------
RowKey: d
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001, value=Beloit, WI, timestamp=1428765102994932)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003, value=Harvard, IL, timestamp=1428765717512832)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002, value=Sheboygan, WI, timestamp=1428765102919171)
-------------------
RowKey: 9
=> (name=x:j:6:5:j:5:1:9xj65j518:1004, value=Denver, CO, timestamp=1428766022126266)

2 Rows Returned.
Elapsed time: 39 msec(s).
具有紧凑的存储空间:

[default@stackoverflow] list georecords3;
Using default limit of 100
Using default cell limit of 100
-------------------
RowKey: d
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001:, value=, timestamp=1428766191314431)
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001:data, value=42656c6f69742c205749, timestamp=1428766191314431)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003:, value=, timestamp=1428766191382903)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003:data, value=486172766172642c20494c, timestamp=1428766191382903)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002:, value=, timestamp=1428766191276179)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002:data, value=536865626f7967616e2c205749, timestamp=1428766191276179)
-------------------
RowKey: 9
=> (name=x:j:6:5:j:5:1:9xj65j518:1004:, value=, timestamp=1428766191424701)
=> (name=x:j:6:5:j:5:1:9xj65j518:1004:data, value=44656e7665722c20434f, timestamp=1428766191424701)

2 Rows Returned.
Elapsed time: 217 msec(s).
[default@stackoverflow] list georecords2;
Using default limit of 100
Using default cell limit of 100
-------------------
RowKey: d
=> (name=p:8:9:v:c:n:e:dp89vcnem4n:1001, value=Beloit, WI, timestamp=1428765102994932)
=> (name=p:8:c:p:w:g:v:dp8cpwgv3:1003, value=Harvard, IL, timestamp=1428765717512832)
=> (name=p:c:8:g:e:k:t:dpc8gektg8w7:1002, value=Sheboygan, WI, timestamp=1428765102919171)
-------------------
RowKey: 9
=> (name=x:j:6:5:j:5:1:9xj65j518:1004, value=Denver, CO, timestamp=1428766022126266)

2 Rows Returned.
Elapsed time: 39 msec(s).
但是,我建议不要将
与紧凑型存储一起使用
,原因如下:

  • 创建表后不能添加或删除列
  • 它防止您在表中有多个非键列
  • 它实际上是用于旧的(不推荐使用的)基于节俭的列族(表)建模方法中,不应该再使用/需要了
  • 是的,它节省了磁盘空间,但是磁盘空间很便宜,所以我认为这是一个非常小的好处。
我知道您说过“除了分区键的基数”,但我还是要在这里提到它。您会注意到,在我的示例数据集中,几乎所有的行都存储有
d
分区键值。如果我为自己创建这样一个应用程序,跟踪威斯康星州/伊利诺伊州州界地区的地理哈希,我肯定会遇到这样的问题:我的大部分数据都存储在同一个分区中(在集群中创建热点)。因此,了解我的用例和潜在数据后,我可能会将前三列左右的内容组合成一个分区键

在同一分区键中存储所有内容的另一个问题是,每个分区最多可以存储约20亿列。因此,将一些想法放在数据是否会掩盖这一标记的后面也是有意义的。显然,分区键的基数越高,就越不可能遇到这个问题

通过查看您的问题,在我看来,您已经查看了您的数据,并且您理解了这一点……明确的“加号”。分区键中的30个唯一值应该提供足够的分布。我只是想花点时间来说明这有多重要

无论如何,我还想加上一句“做得很好”,因为听起来你的思路是对的

编辑

对我来说,尚未解决的问题是,在什么情况下,哪种方法可以更好地扩展

可伸缩性与跨N个节点拥有的R副本的数量更相关。像添加的节点越多,应用程序可以处理的事务就越多。纯粹从数据分发场景来看,您的第一个模型将具有更高的基数分区键,因此它将比第二个模型更均匀地分发。然而,第一个模型在查询灵活性方面提供了一个限制性更强的模型

此外,如果您在分区内执行范围查询(我相信您说过您是这样做的),那么第二个模型将