Cassandra通过非聚类键对结果进行排序

时间:2017-05-27 02:11:08

标签: cassandra datastax cassandra-3.0

我们与Cassandra的使用案例是显示博客帖子的前10位最近访问者。以下是Cassandra表定义

CREATE TABLE blogs_by_visitor (
             blogposturl text,
             visitor text,
             visited_ts timestamp,
             PRIMARY KEY (blogposturl, visitor)
           );

现在,为了显示给定博客帖子的前10位访问者,需要有一个明确的"顺序"关于时间戳的条款。由于visted_ts不是Cassandra中聚类列的一部分,因此我们无法完成此操作。 visit_ts不属于群集列的原因是为了避免记录重复(读取为重复)访问者。主键的设计方式是为重复访问者设置最新时间戳。

在RDBMS世界中,查询看起来如下所示,可以使用blogposturl和timestamp列创建辅助索引。

Select visitor from blog_table
where 
blogposturl = ?
and rownum <= 10
order by timestamp desc

我们的Cassandra应用程序当前正在遵循的另一种方法是获取结果,然后根据应用程序端的时间戳进行排序。但是,如果一个特定的博客文章变得如此受欢迎并且它拥有超过100,000名访问者,该怎么办这些博客的查询变得非常慢。

我认为二级索引在这里不会有用,因为我不担心过滤它(而只是为了排序 - 这是不可能的)。

关于我们如何以不同方式对表进行建模的任何想法?

实际表中有其他列,为简单起见,将其简化为

1 个答案:

答案 0 :(得分:2)

这些类型的工作由Apache Spark或Hadoop完成。一个计划作业,按时间戳计算每个URL的唯一访问者顺序,并将结果存储到cassandra中。

或者您可以在blogs_by_visitor之上创建Materialized View。此表格将确保唯一身份访问者,实体化视图将根据visited_ts时间戳记显示结果。

让我们创建物化视图:

CREATE MATERIALIZED VIEW unique_visitor AS
    SELECT *
    FROM blogs_by_visitor
    WHERE blogposturl IS NOT NULL AND visitor IS NOT NULL AND visited_ts IS NOT NULL
    PRIMARY KEY (blogposturl, visited_ts, visitor)
    WITH CLUSTERING ORDER BY (visited_ts DESC, visitor ASC);

现在,您只需选择博客帖子中最近的10位唯一身份访问者。

SELECT * FROM unique_visitor WHERE blogposturl = ? LIMIT 10;

你可以看到我没有在select查询中指定排序顺序。因为在物化视图架构中,a指定了默认排序顺序visited_ts DESC

注意:以上架构将在物化视图中产生大量意外的墓碑生成

或者您可以像下面那样更改表格schmea:

CREATE TABLE blogs_by_visitor (
     blogposturl text,
     year int,
     month int,
     day int,
     visitor text,
     visited_ts timestamp,
     PRIMARY KEY ((blogposturl, year, month, day), visitor)
);

现在,您在单个分区中只有少量数据。因此,您可以根据客户端的单个分区中的visited_ts对所有访问者进行排序。如果您认为一天中的访问者数量可能很大,那么也可以在分区键中添加小时数。