我的应用功能与Cassandra集成时遇到了一些问题。我正在尝试为users
创建内容Feed。用户可以创建帖子,而帖子又包含字段user_id
。我将Redis用于整个社交图,并仅将Cassandra列用于对象。在Redis中,用户1有一个名为user:1:followers
的集合,其中包含所有他/她的关注者ID。这些跟随者id与users表中的Cassandra id和posts表中的user_ids对应。
我的目标最初是简单地将此Redis集中的所有user_id
插入到将使用FROM posts WHERE user_id IN (user_ids here)
的查询中,并从二级索引user_id
中获取所有帖子。问题是Cassandra故意在辅助索引中没有support IN
运算符,因为该索引会强制Cassandra在其所有节点中搜索该值。我只剩下两个我可以看到的选项:为帖子ID创建user:1:follow_feed
的Redis列表,然后在单个查询中搜索Cassandra的主要索引,或者保留它我现在拥有它并为user_id
集合中的每个user:1:follower
运行单独的查询。
我真的倾向于第一个选项,因为我已经在Redis中拥有大量的图形数据,并且此选项会为每个用户添加一个新列表。第二种方式更糟糕。我会对Cassandra进行大量的读取操作,并且需要很长时间才能为一组id运行单独的查询。据我所知,我有点卡在岩石和坚硬的地方之间。有没有办法用多个值查询二级索引?如果没有,与更多Redis列表或多个Cassandra查询的选项相比,是否有更有效的方式加载这些内容源(RAM和速度方式)?提前谢谢。
答案 0 :(得分:1)
如果不知道posts表的架构(最好是其他人的架构),那么很难提出任何有用的建议。
我不清楚为什么你需要让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。这就是为什么它可能
实际上,这将成为hashmap查找的hashmap。但是,一个主要的警告是,当使用分区和群集列时,始终需要在查询中从左到右提供所有列,而不会跳过任何列。因此,在这种情况下,这意味着您无法在不知道post_id所属的user_id的情况下检索单个帖子。这在用户代码中是可寻址的(通过存储反向映射并在必要时进行查找,或者通过将user_id编码到在应用程序中传递的post_id),但绝对值得考虑。