Cassandra 数据建模

Cassandra datamodelling

我有以下 table 来存储时间序列数据:

CREATE TABLE alerts_by_year_day (
    day_of_year int,
    year int,
    alert_timestamp timestamp,
    serial_number text,
    alert_id uuid,
    alert_type text,
    ....
    ....
  PRIMARY KEY((year, day_of_year), alert_timestamp, serial_number, alert_id)
) WITH CLUSTERING ORDER BY (alert_timestamp DESC, serial_number DESC);
  1. 对于 UI 报告,我想检索给定时间段内的所有警报。我有这个查询:

select * from alerts_by_year_day where year = 2015 and day_of_year in (241, 240);

但是这个查询返回的结果是按年的 ASC 顺序排列的,然后是按天的 ASC 顺序排列的。 所以这样的结果

2015 | 240 |.....

2015 | 241 |.....

但是我想先显示最新的结果,或者按降序显示。添加 'order by alert_timestamp;' 会报错 那么如何显示降序的结果呢?

  1. 然后在给定的时间段内,我只想检索基于 alert_type 的某些类型的警报。

所以我创建了一个像这样的垫子视图:

CREATE MATERIALIZED VIEW alerts_by_type_and_timestamp AS 
    SELECT *
    FROM alerts_by_year_day
    WHERE alert_timestamp IS NOT NULL AND
        alert_type IS NOT NULL AND 
        day_of_year IS NOT NULL AND 
        year IS NOT NULL AND serial_number IS NOT NULL AND 
        alert_id IS NOT NULL
    PRIMARY KEY ((year, day_of_year, alert_type), alert_timestamp, serial_number, alert_id)
    WITH CLUSTERING ORDER BY (alert_timestamp DESC, serial_number DESC, alert_id DESC);

当然,它 returns 首先按类型产生结果,然后按时间戳产生结果。 我正在寻找的只是类型的一个子集,并且按照它们生成的 desc 顺序。 这在 Cassandra 中可能吗?

谢谢

分区的顺序是令牌顺序。它是主键的 murmur3 散列的顺序。即:

cqlsh:test> select * from alerts_by_year_day ;

 year | day_of_year | alert_timestamp                 | serial_number | alert_id                             | alert_type
------+-------------+---------------------------------+---------------+--------------------------------------+------------
 2015 |          10 | 1970-01-01 00:00:00.001000+0000 |          s123 | b7baa710-b87b-11e6-9137-eb2177fd2cc2 |       type
 2015 |         110 | 1970-01-01 00:00:00.001000+0000 |          s123 | bf110270-b87b-11e6-9137-eb2177fd2cc2 |       type
 2015 |          11 | 1970-01-01 00:00:00.001000+0000 |          s123 | bce08de1-b87b-11e6-9137-eb2177fd2cc2 |       type
 2016 |         110 | 1970-01-01 00:00:00.001000+0000 |          s123 | c2e22eb1-b87b-11e6-9137-eb2177fd2cc2 |       type

因为你的 IN 查询,它按顺序走他们(你无法控制)。 Under cover 必须对主键的每个组合进行单独查询。

这需要在 in 子句中对每个值进行多次提取,如果您在其中放入过多的值,可能会很快变得效率低下,因为这会给您的协调器带来很多负担。仅进行两个 async select 查询的成本几乎相同。然后你可以按照你想要的顺序阅读。这也避免了让集群中的单个协调器管理对多个节点的提取,最终这有助于集群健康。每天 1 个查询在您的应用程序中循环访问并不坏。

如果日子不是 "everyday" 可能要考虑第二个 table 那只是 (year, day_of_year)(type, year, day_of_year) 你在插入之前写的尽你所能查询。

note: can keep local in memory cache so you dont have thousands of unnecessary writes, can write just once but it is ok to write multiple times incase multiple instances of app or restarts

year = 2015
days = query('select * from alert_day_index where year = %s', year)
results = []
for day in days:
  results.extend(query('select * from alerts_by_year_day where year = %s and day_of_year = %s', year, day))

如果您有很多天只需要使查询异步,这样查询的延迟就不会阻塞应用程序的吞吐量。