【问题标题】:Cassandra/Redis: Way to create feed without Cassandra 'IN' secondary index?Cassandra/Redis:在没有 Cassandra 'IN' 二级索引的情况下创建提要的方法?
【发布时间】:2014-06-20 18:53:31
【问题描述】:

我的应用程序功能与 Cassandra 集成时遇到了一点问题。我正在尝试为我的users 创建内容提要。用户可以创建帖子,这些帖子又具有user_id 字段。我将 Redis 用于整个社交图,并将 Cassandra 列仅用于对象。在 Redis 中,用户 1 有一个名为 user:1:followers 的集合,其中包含他/她的所有关注者 ID。这些 follower id 对应于 users 表中的 Cassandra ids 和 posts 表中的 user_ids。

我的目标最初是简单地将这个 Redis 集中的所有 user_ids 插入一个查询中,该查询将使用 FROM posts WHERE user_id IN (user_ids here) 并从二级索引 user_id 中获取所有帖子。问题是 Cassandra 故意不在二级索引中使用 support IN 运算符,因为该索引会强制 Cassandra 在其所有节点中搜索该值。我只能看到两个选项:为帖子 ID 创建一个 user:1:follow_feed 的 Redis 列表,然后在单个查询中搜索 Cassandra 的主索引以查找这些帖子,或者保持我现在拥有的方式并运行user:1:follower 集合中每个 user_id 的单独查询。

我非常反对第一个选项,因为我在 Redis 中已经拥有大量的图形数据,而这个选项会为每个用户添加一个新列表。第二种方式更糟糕。我会在 Cassandra 上放置大量读取负载,并且需要很长时间才能为一组 id 运行单独的查询。就我所见,我有点卡在岩石和坚硬的地方之间。有没有办法查询具有多个值的二级索引?如果没有,与更多 Redis 列表或多个 Cassandra 查询的选项相比,是否有更有效的方式来加载这些内容提要(RAM 和速度方面)?提前致谢。

【问题讨论】:

    标签: cassandra redis nosql


    【解决方案1】:

    如果不知道帖子表的架构(最好也知道其他表),很难提出任何有用的建议。

    我不清楚为什么你需要将 user_id 作为二级索引,而不是你的主键。

    一般来说,关键内容(例如创建它的用户的帖子)非常有用,因为它允许您非常有效地执行诸如检索所有帖子(可选地在给定范围内,假设它们是按时间排序的)之类的事情。

    使用 Cassandra,如果您发现某个表可以有效地回答您想要执行的某些查询,但不能有效地回答其他查询,您通常最好对该表进行非规范化并创建另一个具有不同结构的表以保留您的查询到单个 CQL 分区和节点。

    CREATE TABLE posts (
      user_id int,
      post_id int,
      post_text text,
      PRIMARY KEY (user_id, post_id)
      ) WITH CLUSTERING ORDER BY (post_id DESC)
    

    此表可以回答如下查询:

     select * from posts where user_id = 1234;
    
     select * from posts where user_id = 1 and post_id = 53;
    
     select * from posts where user_id = 1 and post_id > 5321 and post_id < 5400;
    

    post_id 上的反向集群是通过将最近的帖子放置在 sstable 中物理分区的开头来最有效地检索它们。

    在该示例中,user_id 是一个分区列,意味着“具有此 user_id 的所有 cql 行将被散列到同一个分区,因此是相同的物理节点,最终是相同的 sstables。这就是为什么可以

    1. 检索具有该 user_id 的所有帖子,因为它们是连续存储的
    2. 通过对 post_id 进行范围查询来检索其中的一部分
    3. 通过同时提供分区列 (user_id) 和集群列 (post_id) 来检索单个帖子

    实际上,这变成了 hashmap 查找的 hashmap。然而,一个主要的警告是,当使用分区和集群列时,您总是需要在查询中从左到右提供所有列,而不能跳过任何列。因此,在这种情况下,这意味着您无法在不知道 post_id 所属的 user_id 的情况下检索单个帖子。这在用户代码中是可寻址的(通过存储反向映射并在必要时进行查找,或者通过将 user_id 编码到在您的应用程序中传递的 post_id 中),但绝对是需要考虑的事情。

    【讨论】:

    • 有意思,所以主键既可以是user_id也可以是post_id?
    • 主键可以是分区键(任何 PRIMARY KEY 子句中的第一项集群键(该子句中的所有剩余条目)的组合。 PRIMARY KEY 子句。
    猜你喜欢
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2013-07-25
    • 2021-05-15
    • 1970-01-01
    • 2018-06-24
    相关资源
    最近更新 更多