【问题标题】:C* Modeling a timeLineC* 建模时间线
【发布时间】:2014-02-19 12:01:50
【问题描述】:

只是为了好玩,我正在构建一个高音扬声器克隆以更好地理解 C*

我见过的所有建议的 C* 方案都使用或多或少相同的建模技术。问题是我对以这种方式建模 twitter 时间线的可扩展性表示怀疑。

问题: 如果我有一个非常受欢迎的用户A(摇滚明星)或更多用户,并且有 10k+ 用户关注,会发生什么? 每次用户 A 发布一条推文时,我们都必须在时间轴表中为他的每个关注者插入 10k+ 条推文。

问题: 这个模型真的会扩展吗? 任何人都可以建议我另一种方法来模拟可以真正扩展的时间线吗?

C* 架构:

CREATE TABLE users (
 uname text, -- UserA
 followers set, -- Users who follow userA
 following set, -- UserA is following userX
 PRIMARY KEY (uname)
);
-- View of tweets created by user
CREATE TABLE userline (
 tweetid timeuuid,
 uname text,
 body text,
 PRIMARY KEY(uname, tweetid)
);
-- View of tweets created by user, and users he/she follows
CREATE TABLE timeline (
 uname text,
 tweetid timeuuid,
 posted_by text,
 body text,
 PRIMARY KEY(uname, tweetid)
);


-- Example of UserA posting a tweet:
-- BATCH START
-- Store the tweet in the tweets
INSERT INTO tweets (tweetid, uname, body) VALUES (now(), 'userA', 'Test tweet #1');

-- Store the tweet in this users userline
INSERT INTO userline (uname, tweetid, body) VALUES ('userA', now(), 'Test tweet #1');

-- Store the tweet in this users timeline
INSERT INTO timeline (uname, tweetid, posted_by, body) VALUES ('userA', now(), 'userA', 'Test tweet #1');

-- Store the tweet in the public timeline
INSERT INTO timeline (uname, tweetid, posted_by, body) VALUES ('#PUBLIC', now(), 'userA', 'Test tweet #1');

-- Insert the tweet into follower timelines
-- findUserFollowers = SELECT followers FROM users WHERE uname = 'userA';
for (String follower : findUserFollowers('userA')) {
INSERT INTO timeline (uname, tweetid, posted_by, body) VALUES (follower, now(), 'userA', 'Test tweet #1');
}
-- BATCH END

提前感谢您的任何建议。

【问题讨论】:

    标签: twitter nosql cassandra data-modeling cql


    【解决方案1】:

    在我看来,您概述的架构或类似的架构最适合该用例(查看用户 X 订阅的最新推文 + 查看我的推文)。

    然而,有两个陷阱。

    1. 我不认为 Twitter 使用 Cassandra 来存储推文,原因可能与您开始考虑的相同。提要在 Cassandra 上运行似乎不是一个好主意,因为您不想永远保留这些其他人推文的无数副本,而是为每个用户保持某种滑动窗口更新(大多数用户不从他们的提要顶部向下阅读 1000 条推文,我猜)。所以我们谈论的是队列,以及在某些情况下基本上实时更新的队列。 Cassandra 只能通过一些强制措施在规模的远端支持这种模式。我不认为它是为大规模流失而设计的。

      在生产中,可能会选择另一个对队列有更好支持的数据库——可能是像分片 Redis 那样支持列表。

    2. 对于您给出的示例,问题并不像看起来那么严重,因为您不需要在同步批处理中进行此更新。您可以发布到作者的列表,快速返回,然后使用在集群中运行的异步工作器执行所有其他更新,以尽力提供 QoS 推送更新。


    最后,既然您询问了替代方案,那么我可以想到一个变体。它可能在概念上更接近我提到的队列,但在底层它会遇到许多与大量数据流失相关的相同问题。

    CREATE TABLE users(
     uname text,
     mru_timeline_slot int,
     followers set,
     following set,
     PRIMARY KEY (uname)
    );
    
    // circular buffer:  keep at most X slots for every user.  
    CREATE TABLE timeline_most_recent(
     uname text,
     timeline_slot int, 
     tweeted timeuuid,
     posted_by text,
     body text,
     PRIMARY KEY(uname, timeline_slot)
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-26
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 2021-10-15
      • 2021-07-25
      相关资源
      最近更新 更多