cassandra获得时间范围内的所有记录

Fab*_*ber 27 cql cassandra

我必须使用以(user_id,timestamp)为键的列族.在我的查询中,我想获取给定时间范围内的所有记录,与user_id无关.这是确切的表模式:

CREATE TABLE userlog (
  user_id text,
  ts timestamp,
  action text,
  app_type text,
  channel_name text,
  channel_session_id text,
  pid text,
  region_id text,
  PRIMARY KEY (user_id, ts)
)
Run Code Online (Sandbox Code Playgroud)

我试着跑

SELECT * FROM userlog  WHERE ts >= '2013-01-01 00:00:00+0200' AND  ts <= '2013-08-13 23:59:00+0200' ALLOW FILTERING;
Run Code Online (Sandbox Code Playgroud)

这在我的本地cassandra安装中工作正常,包含一个小数据集,但失败了

Request did not complete within rpc_timeout.
Run Code Online (Sandbox Code Playgroud)

在包含所有数据的生产系统上.

是否有一个,最好是cql,查询与给定的列系列顺利运行或de我们必须更改设计?

Ric*_*ard 34

超时是因为Cassandra花费的时间超过了超时(默认为10秒)才能返回数据.对于您的查询,Cassandra将在返回之前尝试获取整个数据集.对于多个记录,这可能比超时更长.

对于生成大量数据的查询,您需要进行分页

SELECT * FROM userlog WHERE ts >= '2013-01-01 00:00:00+0200' AND  ts <= '2013-08-13 23:59:00+0200' AND token(user_id) > previous_token LIMIT 100 ALLOW FILTERING;
Run Code Online (Sandbox Code Playgroud)

这里user_id是以前的USER_ID返回.您还需要在ts上进行分页,以保证您获得最后返回的user_id的所有记录.

或者,在Cassandra 2.0.0(刚刚发布)中,分页是透明完成的,因此您的原始查询应该没有超时或手动分页.

ALLOW FILTERING方法Cassandra是通读所有的数据,但只有指定的范围内返回数据.只有范围是大部分数据时,这才有效.如果你想在例如5分钟的时间窗口内找到记录,这将是非常低效的.

  • 什么对'5分钟时间窗'有效? (30认同)

rog*_*ack 7

似乎能够按时间(或任何范围)查询的热点是将某些“其他列”指定为您的分区键,然后将时间戳指定为“集群列”

CREATE TABLE postsbyuser (
     userid bigint,
     posttime timestamp,
     postid uuid,
     postcontent text,
     PRIMARY KEY ((userid), posttime)
   ) WITH CLUSTERING ORDER BY (posttime DESC);
Run Code Online (Sandbox Code Playgroud)

插入假数据

  insert into postsbyuser (userid, posttime) values (77, '2013-04-03 07:04:00');
Run Code Online (Sandbox Code Playgroud)

和查询(重要的部分是它是一个“快速”查询并且ALLOW FILTERING不是必需的,它应该是这样的):

  SELECT * FROM postsbyuser where userid=77 and posttime > '2013-04-03 07:03:00' and posttime < '2013-04-03 08:04:00';
Run Code Online (Sandbox Code Playgroud)

您还可以使用技巧按天分组(从而能够按天查询)或其他什么。

如果您使用“按天分组”风格的技巧,那么二级索引也是一种选择(尽管二级索引似乎只适用于“EQ”=运算符?)。