卡桑德拉存储内部

Woo*_*Kim 5 time-series cql cassandra apache-spark

我试图了解在CQL样式表中插入行(列)时,内部存储引擎级别究竟发生了什么.

CREATE TABLE log_date (
  userid bigint,
  time timeuuid,
  category text,
  subcategory text,
  itemid text,
  count int,
  price int,
  PRIMARY KEY ((userid), time) - #1
  PRIMARY KEY ((userid), time, category, subcategory, itemid, count, price) - #2
);
Run Code Online (Sandbox Code Playgroud)

假设我有一个像上面这样的表.

在#1的情况下,CQL行将在存储中生成6(或5?)列.
在#2的情况下,CQL行将在存储中生成非常复合的列.

我想知道将日志存储到Cassandra的更有效方法.
请关注两种情况.
我不需要任何实时读取.只是着作.



如果您想建议其他选项,请参阅以下内容.
我选择Cassandra存储日志的原因是

  1. 线性可扩展性,适合繁重的写作.
  2. 它具有CQL中的模式.我真的更喜欢有一个架构.
  3. 似乎足够支持Spark.Datastax的cassandra-spark连接器似乎具有数据局部性感知.

Aar*_*ron 7

我试图了解在CQL样式表中插入行(列)时,内部存储引擎级别究竟发生了什么.

假设我使用两个PRIMARY KEY构建表,并插入一些数据:

aploetz@cqlsh:stackoverflow2> SELECT userid, time, dateof(time), category, subcategory, itemid, count, price FROM log_date1;

 userid | time                                 | dateof(time)             | category | subcategory    | itemid            | count | price
--------+--------------------------------------+--------------------------+----------+----------------+-------------------+-------+-------
   1002 | e2f67ec0-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:48:20-0500 |    Books |         Novels | 678-2-44398-312-9 |     1 |   798
   1002 | 15d0fd20-f589-11e4-ade7-21b264d4c94d | 2015-05-08 08:49:45-0500 |    Audio |     Headphones | 228-5-44343-344-5 |     1 |  4799
   1001 | 32671010-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:43:23-0500 |    Books | Computer Books | 978-1-78398-912-6 |     1 |  2200
   1001 | 74ad4f70-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:45:14-0500 |    Books |         Novels | 678-2-44398-312-9 |     1 |   798
   1001 | a3e1f750-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:46:34-0500 |    Books | Computer Books | 977-8-78998-466-4 |     1 |   599

(5 rows)
aploetz@cqlsh:stackoverflow2> SELECT userid, time, dateof(time), category, subcategory, itemid, count, price FROM log_date2;

 userid | time                                 | dateof(time)             | category | subcategory    | itemid            | count | price
--------+--------------------------------------+--------------------------+----------+----------------+-------------------+-------+-------
   1002 | e2f67ec0-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:48:20-0500 |    Books |         Novels | 678-2-44398-312-9 |     1 |   798
   1002 | 15d0fd20-f589-11e4-ade7-21b264d4c94d | 2015-05-08 08:49:45-0500 |    Audio |     Headphones | 228-5-44343-344-5 |     1 |  4799
   1001 | 32671010-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:43:23-0500 |    Books | Computer Books | 978-1-78398-912-6 |     1 |  2200
   1001 | 74ad4f70-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:45:14-0500 |    Books |         Novels | 678-2-44398-312-9 |     1 |   798
   1001 | a3e1f750-f588-11e4-ade7-21b264d4c94d | 2015-05-08 08:46:34-0500 |    Books | Computer Books | 977-8-78998-466-4 |     1 |   599

(5 rows)
Run Code Online (Sandbox Code Playgroud)

看起来几乎一样cqlsh.那么让我们看看cassandra-cli,并查询userid1002的所有行:

RowKey: 1002
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:, value=, timestamp=1431092900008568)
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:category, value=426f6f6b73, timestamp=1431092900008568)
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:count, value=00000001, timestamp=1431092900008568)
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:itemid, value=3637382d322d34343339382d3331322d39, timestamp=1431092900008568)
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:price, value=0000031e, timestamp=1431092900008568)
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:subcategory, value=4e6f76656c73, timestamp=1431092900008568)
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:, value=, timestamp=1431092985326774)
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:category, value=417564696f, timestamp=1431092985326774)
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:count, value=00000001, timestamp=1431092985326774)
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:itemid, value=3232382d352d34343334332d3334342d35, timestamp=1431092985326774)
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:price, value=000012bf, timestamp=1431092985326774)
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:subcategory, value=4865616470686f6e6573, timestamp=1431092985326774)
Run Code Online (Sandbox Code Playgroud)

很简单吧?我们将userid1002视为RowKey,将我们的聚类列time视为列键.接下来,我们列的每一列都是key(time).我相信你的第一个实例会生成6列,因为我很确定它包含列键的占位符,因为你的PRIMARY KEY可能指向一个空值(如第二个示例键所示).

但是userid1002 的第二个版本怎么样?

RowKey: 1002
=> (name=e2f67ec0-f588-11e4-ade7-21b264d4c94d:Books:Novels:678-2-44398-312-9:1:798:, value=, timestamp=1431093011349994)
=> (name=15d0fd20-f589-11e4-ade7-21b264d4c94d:Audio:Headphones:228-5-44343-344-5:1:4799:, value=, timestamp=1431093011360402)
Run Code Online (Sandbox Code Playgroud)

为RowKey 1002返回两列,一列用于我们的列(聚类)键的每个唯一组合,具有空值(如上所述).

那对你来说意味着什么呢?嗯,有几件事:

  • 这应该告诉你Cassandra的PRIMARY KEYs确保唯一性.因此,如果您决定需要更新像categorysubcategory(第二个示例)这样的键值,除非您删除并重新创建行,否则您确实无法更新.虽然从日志记录的角度来看,这可能没问题.
  • Cassandra将特定分区/行键(userid)的所有数据存储在一起,按列(聚类)键排序.如果您担心查询和排序数据,那么了解您必须查询userid排序顺序的每个特定内容才能产生任何差异.
  • 我看到的最大问题是,现在你正在为无限的列增长做好准备.分区/行键最多可以支持20亿列,因此您的第二个示例将帮助您最多.如果你认为你userid的某些人可能会超过这个,你可以实施一个"日期桶"作为额外的分区密钥(例如,如果你知道userid一年内永远不会超过20亿,或者其他什么).

在我看来,你的第二个选择可能是更好的选择.但老实说,对于你正在做的事情,他们中的任何一个都可能正常工作.