【发布时间】:2014-12-01 01:20:34
【问题描述】:
这是一个冗长的问题。它是关于 Cassandra 模式设计的。我来这里是为了从您尊敬的专家那里获得关于我正在研究的用例的意见。欢迎所有意见、建议和批评。这是我的问题。
我们希望收集用户对我们即将发表的一些论文的评论。对于每篇论文,我们寻求 3 条评论。但是我们向 3*2= 6 个用户发送评论邀请。所有 6 位用户都可以向我们的系统提交他们的评论,但仅限前 3 位;前 3 名审稿人将获得奖励。
在我们的 Cassandra DB 中,有三个表:USER、PAPER 和 REVIEW。 USER 和 PAPER 表很简单:每个用户对应 USER 表中具有唯一 USER_ID 的行;同样,每篇论文在 PAPER 表中都有一个唯一的 PAPER_ID。
REVIEW 表如下所示
CREATE TABLE REVIEW(
PAPER_ID uuid,
USER_ID uuid,
REVIEW_CONTENT text,
PRIMARY KEY(PAPER_ID, USER_ID)
);
我们使用 PAPER_ID 作为 REVIEW 表的分区键,以便给定论文的所有评论都存储在单个 Cassandra 行中。对于我们拥有的每篇论文,我们选择 6 个用户,将 6 个条目插入到 REVIEW 表中,并向这些用户发送 6 个邀请。因此,对于论文“P1”,REVIEW 表中有 6 个条目如下所示
----------------------------------------------------
PAPER_ID | USER_ID | REVIEW_CONTENT |
----------------------------------------------------
P1 | U1 | null |
----------------------------------------------------
P1 | U2 | null |
----------------------------------------------------
P1 | U3 | null |
----------------------------------------------------
P1 | U4 | null |
----------------------------------------------------
P1 | U5 | null |
----------------------------------------------------
P1 | U6 | This paper ... |
---------------------------------------------------
... | ... | ... |
用户通过网络浏览器使用 http 提交评论。在后端,我们使用以下流程来处理提交的评论(以论文“P1”为例):
- 使用分区键“P1”从 REVIEW 表中取出所有 6 个条目。
- 找出这6个条目中有多少在REVIEW_CONTENT列有非空值(非空值表示对应的用户已经提交了他的评论。例如,在上表中,用户“U6”已提交他的评论,而其他 5 人还没有)。
- 如果这个数字 >=3,我们已经获得了足够多的评论,请返回给当前评论者并发送一条消息,例如“谢谢,我们已经获得了足够多的评论。”
- 如果此数字
- 如果此数字 =2,这是最复杂的情况,因为当前提交是我们将接受的最后一个。在这种情况下,我们首先将当前评论保存到 REVIEW 表中,然后我们找到所有三个提交评论的用户(包括当前用户)的 id,将他们的 id 记录到事务表中,以便稍后向他们支付奖励。
但是这个过程不起作用。问题是它不能正确处理并发提交。考虑以下情况:两个用户已经提交了他们的评论,同时另外 3 个用户正在通过上面显示的三个并发过程提交他们的评论。在第 5 步,三个人中的每个人都会认为他是第三个也是最后一个提交者,并将新记录插入到事务表中。这会导致重复计算:单个用户可能会因为他提交的相同评论而获得多次奖励。
这个过程的另一个问题是它可能永远不会到达第5步。假设REVIEW表中没有提交,并且有4个用户同时提交了他们的评论。他们都在第 4 步保存了他们的评论。在此之后,以后的提交者将始终被拒绝,因为已经有 4 个接受的评论。但是由于我们永远不会到达第 5 步,因此不会将任何 id 记录到交易表中,用户将永远不会获得任何奖励。
所以我的问题来了:我应该如何使用 Cassandra 作为后端数据库来处理我的用例? Cassandra COUNTER 会帮忙吗?如果是这样,怎么做?我还没有考虑过如何使用 COUNTER,但是这个博客 (http://aphyr.com/posts/294-call-me-maybe-cassandra) 警告说 Cassandra COUNTER 不安全(引用“因此,在网络分区期间,Cassandra 计数器将在很大范围内过度计数或计数不足。” ) Cassandra 的比较和设置 (CAS) 功能有帮助吗?如果是这样,怎么做?保存博客再次警告说“Cassandra 轻量级事务甚至还没有接近正确。”
【问题讨论】:
标签: concurrency cassandra schema