Cassandra 数据模型指导

Cassandra data model guidance

我对 Cassandra 数据建模有疑问。抱歉有点长 post.

我在这里假设一个情况。假设我有一个主服务器,它从网络上的机器(一台或多台)收集数据。其他机器的数据以机器详细信息、状态、是否连接、启动或关闭、台式机或笔记本电脑等形式出现。我有这样的疑问

  1. 根据主服务器 ID 获取与其连接的机器列表
  2. 给定机器 ID,获取机器详细信息。
  3. 给定机器状态(仅此而已)获取机器列表(一台或多台)
  4. 给定标志 is_connected 获取连接到主服务器的机器列表?
  5. 给定标志is_up获取机器列表?

因此,根据 Cassandra,我们应该为每个查询创建一个列族(大约)。我担心的是上面的查询 #3、#4、#5,这些查询的 where 子句分别是状态 is_connected 和 is_up,因此为了满足这些查询,我必须创建 table将这些标志作为分区键或簇键。

CREATE TABLE server (
    server_id text,
    server_name text,
    status text,
    .
    .
    .
    .
    .
    other information,
    PRIMARY KEY (server_id))

CREATE TABLE machine (
    machine_id text,
    machine_name text,
    status boolean,
    is_connected boolean,
    is_up boolean,
    .
    .
    .
    .
    .
    other information,
    PRIMARY KEY (machine_id))

  CREATE TABLE machine_by_status (
      machine_id text,
      machine_name text,
      status boolean,
      is_connected boolean,
      is_up boolean,
      .
      .
      .
      .
      .
      other information,
      PRIMARY KEY (status, machine_id))

  CREATE TABLE machine_by_connected (
      machine_id text,
      machine_name text,
      status boolean,
      is_connected boolean,
      is_up boolean,
      .
      .
      .
      .
      .
      other information,
      PRIMARY KEY (is_connected, machine_id))

  CREATE TABLE machine_by_up_down (
      machine_id text,
      machine_name text,
      status boolean,
      is_connected boolean,
      is_up boolean,
      .
      .
      .
      .
      .
      other information,
      PRIMARY KEY (is_up, machine_id))

但是这些标志的值可能会随着时间的推移而改变。值可以是多个。如果这些是分区键或集群键的一部分,那么我无法更新或更改它。因此,一旦创建了我的列族并添加了带有某些标志值的记录,那么对于新值,我该如何更新该记录,或者如果我添加新记录,那么我该如何删除旧记录?我想避免先读再写。

数据收集的频率可能会有所不同,所以我不能使用固定的 TTL 值,以便 Cassandra 可以删除旧值。我知道上述模型存在问题,例如它可能会产生热点或可能会产生不平衡集群,这就是我需要指导的原因。我该如何处理这种情况。我的客户端应用程序只能在几页上基于这些标志进行查询。客户端没有其他数据可以查询。

那么如何创建列族来满足查询#3、#4、#5?在这种情况下,您的指导将帮助我提出良好的数据模型。

提前致谢。

标记statusis_connectedis_up都是低基数分区

假设所有机器都已启动,所以您的所有数据都将位于单个分区(在同一节点上),将创建热点,将无法扩展等。

所以不要将低基数列(statusis_connectedis_up)作为分区键。为每个标志值创建单独的 table。

示例is_up

CREATE TABLE up_machines ( 
    machine_id text PRIMARY KEY, 
    machine_name text, 
); 

CREATE TABLE down_machines ( 
    machine_id text PRIMARY KEY, 
    machine_name text, 
); 

现在,如果您需要上机列表,那么您可以 select 全部来自 up_machines table。类似地为其他标志创建 table。

另一件事,而不是 select 一个一个地记录所有记录,使用驱动程序分页系统

https://docs.datastax.com/en/developer/java-driver/2.1/manual/paging/

注意:如果机器状态发生变化,您必须从一个 table 中删除并插入另一个。删除记录创建墓碑。如果这种情况经常发生,就会生成巨大的墓碑。 About Deletes and Tombstones in Cassandra