【问题标题】:Data Modelling in Cassandra for job queuesCassandra 中用于作业队列的数据建模
【发布时间】:2018-06-14 23:13:58
【问题描述】:

我正在尝试将所有调度程序作业存储在 Cassandra 中。

我设计了所有的锁定表,看起来还不错。我在创建作业队列表时遇到了困难。

我的要求是

1) 我需要查询所有未完成的作业。

CREATE TABLE jobs(
   jobId text,
   startTime timestamp,
   endTime timestamp,
   status text,
   state text,
   jobDetails text,
   primary key (X,X)) 
    with clustering order by (X desc);

在哪里,状态 - 开/关
状态 - 运行/失败/完成

我不确定要保留哪一个作为主键(因为它是唯一的),我还需要查询所有处于“开启”状态的作业。有人可以帮我在 Cassandra 中设计这个。即使您建议使用复合分区键,我也可以。

已编辑:

我想出了这样的数据模型,

CREATE TABLE job(
   jobId text,
   startTime timestamp,
   endTime timestamp,
   state text,
   status text,
   jobDetails text,
   primary key (state,jobId, startTime) 
    with clustering order by (startTime desc);

我可以这样插入,

INSERT INTO job (jobId, startTime, endTime, status,state, jobDetails) VALUES('nodestat',toTimestamp(now()), 0,'running','on','{
        "jobID": "job_0002",
        "jobName": "Job 2",
        "description": "This does job 2",
        "taskHandler": require("./jobs/job2").runTask,
        "intervalInMs": 1000
    }');

这样查询,

SELECT * FROM job WHERE state = 'on';

这会对性能产生任何影响吗?

【问题讨论】:

  • 队列是 Cassandra 中的反模式:datastax.com/dev/blog/…
  • 我编辑的模型是错误的,它不支持改变状态:(有什么想法吗?
  • 只有在表上创建二级索引时,您的查询才会起作用,但它会创建巨大的分区,如第二个答案中所述。但是您可以围绕状态本身对数据进行建模——例如,将完成的任务放入单独的表中?

标签: cassandra data-modeling cassandra-3.0


【解决方案1】:

您可能正在为 cassandra 实施反模式。

请参阅 https://www.datastax.com/dev/blog/cassandra-anti-patterns-queues-and-queue-like-datasets 的博客文章,讨论使用 cassandra 作为消息队列时可能出现的问题。

除此之外,还有一些信息如何在 Slideshare 上的 cassandra 中以“正确的方式”进行操作:https://de.slideshare.net/alimenkou/high-performance-queues-with-cassandra

有许多项目更适合调度和/或消息传递,例如http://www.quartz-scheduler.org/overview/features.html

更新您的上述编辑:

primary key (state,jobId, startTime) 

这将为每个state 创建一个分区 - 导致巨大的分区和热点。转换作业状态会将其移动到不同的分区 - 您将删除条目以及可能的兼容性和性能问题(取决于您的作业数量)。

所有 state='on' 的作业都将在一个节点上(它是副本),所有 state='off' 的作业都在另一个节点上。您的设计中有两个分区。

【讨论】:

  • 你为什么认为这些是队列,实际上我会编辑问题,它不是队列。想象一下,这只是存储作业并根据其中的某些字段检索的方式。你现在可以检查我的问题吗?
  • 请参阅我上面的答案
【解决方案2】:

由于您对模型的更改持开放态度,请查看以下模型是否适合您

   CREATE TABLE job(
   partition_key,
   jobId text,
   startTime timestamp,
   endTime timestamp,
   state text,
   status text,
   jobDetails text,
   primary key (partition_key,state,jobId, startTime) 
   with clustering order by (startTime desc);

这里partion_key列的值可以根据你的工作量来计算。

例如:

如果您的作业数量在一天内少于 100K 个作业,那么您可以将分区保持在单日级别,即 YYYYMMDD (20180105) 或者如果它是每小时 100K,您可以将其更改为 YYYYMMDDHH (2018010518) .根据您的过滤顺序更改集群列。

  • 这样您就可以查询状态只有在您知道何时要查询的情况下。
  • 避免创建过多分区或使用过多列爆炸分区
  • 它将负载平均分配到分区中。

如果您可以指定可以对查询进行哪些调整/添加,这将有助于更好地设计模型。

【讨论】:

    【解决方案3】:

    您需要在分区键中包含相等列,以便您的相等列是状态和状态。您需要检查这 2 个是否构成良好的分区键,如果不是,则需要使用自定义列或任何其他现有列作为分区键的一部分。由于 jobid 是为了使记录唯一,您可以将其保存在聚类列中。我假设您没有在工作 ID 上查询表。

    【讨论】:

    • 你能举个例子吗?
    猜你喜欢
    • 2018-03-24
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多