【问题标题】:Composite columns and "IN" relation in CassandraCassandra中的复合列和“IN”关系
【发布时间】:2013-09-24 19:29:51
【问题描述】:

我在 Cassandra 中有以下列族,用于将时间序列数据存储在少数非常“宽”的行中:

CREATE TABLE data_bucket (
  day_of_year int,
  minute_of_day int,
  event_id int,
  data ascii,
  PRIMARY KEY (data_of_year, minute_of_day, event_id)
)

在 CQL shell 上,我可以运行如下查询:

select * from data_bucket where day_of_year = 266 and minute_of_day = 244 
  and event_id in (4, 7, 11, 1990, 3433)

本质上,我修复了复合列名称 (minute_of_day) 的第一个组成部分的值,并希望根据第二个组成部分 (event_id) 的不同值选择一组不连续的列。由于“IN”关系被解释为等式关系,因此可以正常工作。

现在我的问题是,我将如何在没有 CQL 的情况下以编程方式完成相同类型的复合列切片。到目前为止,我已经尝试过 Python 客户端 pycassa 和 Java 客户端 Astyanax,但没有任何成功。

欢迎提出任何想法。

编辑:

我正在添加通过 cassandra-cli 看到的列族的描述输出。由于我正在寻找基于 Thrift 的解决方案,也许这会有所帮助。

ColumnFamily: data_bucket
  Key Validation Class: org.apache.cassandra.db.marshal.Int32Type
  Default column value validator: org.apache.cassandra.db.marshal.AsciiType
  Cells sorted by: org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.Int32Type,org.apache.cassandra.db.marshal.Int32Type)
  GC grace seconds: 864000
  Compaction min/max thresholds: 4/32
  Read repair chance: 0.1
  DC Local Read repair chance: 0.0
  Populate IO Cache on flush: false
  Replicate on write: true
  Caching: KEYS_ONLY
  Bloom Filter FP chance: default
  Built indexes: []
  Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy
  Compression Options:
    sstable_compression: org.apache.cassandra.io.compress.SnappyCompressor

【问题讨论】:

标签: cassandra


【解决方案1】:

Thrift API 中没有“IN”类型的查询。您可以对每个复合列值(day_of_yearminute_of_dayevent_id)执行一系列 get 查询。

如果您的 event_ids 是连续的(而您的问题表明它们不是),您可以执行单个 get_slice 查询,在范围内传递(例如,day_of_yearminute_of_day 和 @987654331 的范围@s)。您可以通过这种方式抓取它们并自己以编程方式过滤响应(例如,抓取日期中事件 ID 介于 4-3433 之间的所有数据)。更多的数据传输,更多的客户端处理,所以不是一个很好的选择,除非你真的在寻找一个范围。

因此,如果您想在 Cassandra 中使用“IN”,则需要切换到基于 CQL 的解决方案。如果您正在考虑在 python 中使用 CQL,另一个选项是 cassandra-dbapi2。这对我有用:

import cql

# Replace settings as appropriate
host = 'localhost'
port = 9160
keyspace = 'keyspace_name'

# Connect
connection = cql.connect(host, port, keyspace, cql_version='3.0.1')
cursor = connection.cursor()
print "connected!"

# Execute CQL
cursor.execute("select * from data_bucket where day_of_year = 266 and minute_of_day = 244 and event_id in (4, 7, 11, 1990, 3433)")
for row in cursor:
  print str(row) # Do something with your data

# Shut the connection
cursor.close()
connection.close()

(使用 Cassandra 2.0.1 测试。)

【讨论】:

  • 它在 CQL 中工作,但正如我在问题中提到的,我正在寻找没有它的解决方案。
  • 如果您不想使用 CQL,您是否正在寻找基于 Thrift 或 CLI 的替代方案? Cassandra's own recommendation is to use CQL-based clients。提出的解决方案将允许您构建任何基于 CQL 的查询(传递给 cursor.execute 的字符串)并使用 cassandra-dbapi2 客户端以编程方式执行它。
  • 我必须与使用 Astyanax 而没有 CQL 的现有代码库集成。虽然我可能会推动 CQL,但我很想通过 Thrift 弄清楚它是如何在幕后工作的。
  • 明白。将问题中的 CF/表定义添加到 CLI 格式是值得的。带有复合列(IntegerType、IntegerType、IntegerType 或只是 DateType、IntegerType)的宽行怎么样?如果有帮助,我可以用 CLI 公式来扩充我的答案(我自己刚刚从 CLI [hector&pycassa] 迁移到 CQL [datastax/cassandra-dbapi2] - 这很痛苦,但从长远来看是值得的)。
  • 增加了列族的cli描述。这将是一个宽行,其中包含一个复合列 (int32, int32) 名称,表示 minute_of_day 和 event_id,以及一个用于 day_of_year 的 int32 键验证器。
猜你喜欢
  • 2013-07-09
  • 2015-01-15
  • 2016-09-28
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
  • 2012-08-31
  • 2012-07-12
  • 2021-11-18
相关资源
最近更新 更多