首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Cassandra,并发写入的模式和流程设计

Cassandra,并发写入的模式和流程设计
EN

Stack Overflow用户
提问于 2014-12-01 01:20:34
回答 1查看 458关注 0票数 2

这是个冗长的问题。这是关于Cassandra模式设计的。我来这里是为了从你尊敬的专家那里得到关于我正在研究的用例的意见。欢迎所有的意见、建议和批评。我的问题来了。

我们想收集评论,从我们的用户,关于一些论文,我们即将发表。对于每一篇论文,我们寻求3篇评论。但是我们向3*2= 6用户发出了评论邀请。所有6个用户都可以向我们的系统提交他们的评论,但只有前3次统计;而这前3名评审者将得到他们的工作的奖励。

在我们的Cassandra中,有三个表格:用户表、纸张表和评论表。用户表和纸质表很简单:每个用户对应于具有唯一USER_ID的用户表中的一行;类似地,每张纸在纸质表中都有一个唯一的PAPER_ID。

审查表如下所示

代码语言:javascript
复制
CREATE TABLE REVIEW(
    PAPER_ID uuid,
    USER_ID uuid,
    REVIEW_CONTENT text,
    PRIMARY KEY(PAPER_ID, USER_ID)
    );

我们使用PAPER_ID作为评审表的分区键,以便将给定纸张的所有评论存储在单个Cassandra行中。对于我们所拥有的每一篇论文,我们收集了6个用户,在评审表中插入了6个条目,并向这些用户发送了6个邀请。因此,对于论文"P1",审查表中有6个条目如下所示

代码语言:javascript
复制
----------------------------------------------------
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“为例):

  1. 使用分区键"P1“从审查表中提取所有6个条目。
  2. 在REVIEW_CONTENT列中找出这6个条目中有多少是非空值(非空值表示相应的用户已经提交了他的评论)。例如,在上表中,用户"U6“提交了他的评论,而其他5个尚未提交)。
  3. 如果这个数字是>=3,我们已经有足够的评论,返回到当前的评论员,例如:“谢谢,我们已经有足够的评论了。”
  4. 如果这个数字< 2,请将当前评审保存到评审表中相应的条目,然后返回给审阅者,并提供一条类似于“您的评审已被接受”的消息。(例如,如果当前审阅者为" U1“,则用当前的审阅内容填充"P1,U1”条目的REVIEW_CONTENT列。)
  5. 如果这个数字=2,这是最复杂的情况,因为当前的提交是我们接受的最后一个。在这种情况下,我们首先将当前的审查保存到评审表中,然后找到提交了评论(包括当前用户)的所有三个用户的In,然后将他们的In记录到事务表中,以便稍后支付奖励。

但是这个过程不起作用。问题是它不能正确地处理并发提交。考虑以下情况:两个用户已经提交了他们的评论,同时还有三个用户正在通过上面所示的三个并发过程提交他们的评论。在步骤5中,三个人都会认为他是第三个也是最后一个提交者,并将新记录插入到事务表中。这就导致了重复计算:一个用户可能因为提交的相同的评论而得到不止一次的奖励。

这个过程的另一个问题是它可能永远达不到第5步,假设在评审表中没有提交,并且有4个用户同时提交他们的评论。他们都在第4步保存他们的评论。在此之后,以后提交者将始终被拒绝,因为已经有4个接受的评论。但是,由于我们从未达到第5步,因此没有ids将被记录到事务表中,并且用户将永远得不到任何奖励。

因此,我的问题来了:如何使用Cassandra作为后端DB来处理我的用例?卡桑德拉会反击吗?如果是这样的话,是怎么做的?我还没有想过如何使用计数器,但这个博客(http://aphyr.com/posts/294-call-me-maybe-cassandra)警告说,卡桑德拉计数器是不安全的(引用“因此,卡桑德拉计数器将在一个网络分区期间超出-或少计数”)。卡桑德拉的比较和设置(CAS)功能会有帮助吗?如果是这样的话,是怎么做的?保存博客再次警告说,"Cassandra轻量级事务甚至都无法纠正。“

EN

回答 1

Stack Overflow用户

发布于 2014-12-03 17:57:50

与其在您的评审表中创建空条目,不如将其保留为空,并且只在提交评审时填充它。要处理并发性,添加一个timeuuid字段作为排序键:

代码语言:javascript
复制
CREATE TABLE review(
  paper_id uuid,
  submission_time timeuuid,
  user_id uuid,
  content text,
  PRIMARY KEY (paper_id, submission_time)
);

当用户提交时,将条目添加到表中。然后,在写入成功之后,查询表(仅在paper_id上),并确定用户的id是否是前三个表中的一个。相应地响应用户。由于您致力于一小部分审阅者,所以获取所有评论的额外开销应该是最小的(特别是因为您不需要在查询中包含内容列)。

如果您需要跟踪谁正在查看论文,请将一组用户ids添加到纸质表中,并在那里编写六个用户ids。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27220485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档