Cassandra 中的动态模式更改

Dynamic schema changes in Cassandra

我有很多用户(150-2 亿)。每个用户有 N(30-100) 个属性。该属性可以是整数、文本或时间戳类型。属性未知,所以我想动态添加它们。

解决方案 1 - 通过更改 table

添加新列
   CREATE TABLE USER_PROFILE(
    UID uuid PRIMARY KEY,
    LAST_UPDATE_DATE TIMESTAMP,
    CREATION_DATE TIMESTAMP
   );

对于每个新属性:

    ALTER TABLE USER_PROFILE ADD AGE INT;
    INSERT INTO USER_PROFILE ( UID, LAST_UPDATE_DATE, CREATION_DATE, AGE) VALUES ('01f63e8b-db53-44ef-924e-7a3ccfaeec28', 2021-01-12 07:34:19.121, 2021-01-12 07:34:19.121, 27);

解决方案 2 - 固定模式:

CREATE TABLE USER_PROFILE(
    UID uuid,
    ATTRIBUTE_NAME TEXT,
    ATTRIBUTE_VALUE_TEXT TEXT,
    ATTRIBUTE_VALUE_TIMESTAMP TIMESTAMP,
    ATTRIBUTE_VALUE_INT INT,
    LAST_UPDATE_DATE TIMESTAMP,
    CREATION_DATE TIMESTAMP,
    PRIMARY KEY (UID, ATTRIBUTE_NAME)
);

对于每个新属性:

INSERT INTO USER_PROFILE ( UID, ATTRIBUTE_NAME, ATTRIBUTE_VALUE_INT, LAST_UPDATE_DATE, CREATION_DATE) VALUES ('01f63e8b-db53-44ef-924e-7a3ccfaeec28', 'age', 27, 2021-01-12 07:34:19.121, 2021-01-12 07:34:19.121, 27);

就性能而言,哪个是最佳解决方案?

我个人会选择第二种解决方案——为所使用的每种数据类型设置列,并将属性名称用作主键的最后一个组成部分(参见我之前关于该主题的回答中的示例:

  • Cassandra dynamic column family
  • How to handle Dynamic columns in Cassandra
  • How to handle Dynamic columns in Cassandra
  • How to understand the 'Flexible schema' in Cassandra?

第一个解决方案存在以下问题:

  • 如果您从代码进行架构修改,则需要协调这些更改,否则您将得到 schema disagreement,必须由管理员通过重启节点来解决。协调的更改要么会减慢数据插入速度,要么会造成单点故障
  • 存在许多列会对性能产生重大影响。例如,根据 this very good analysis by The Last Pickle,拥有 100 列而不是 10 列会使读取延迟增加 10 倍以上
  • 如果需要,您不能更改属性类型 - 在将属性作为聚类列的解决方案中,您可以开始将属性作为另一种类型。如果您将属性作为列,则不能这样做,因为 Cassandra 不允许更改列类型(不要尝试删除列并使用新类型将其添加回来 - 您会破坏现有数据)。因此,您需要为该属性创建一个全新的列。