代码之家  ›  专栏  ›  技术社区  ›  colesico

类别项目实体的Cassandra/Scylla最优存储模型

  •  0
  • colesico  · 技术社区  · 1 年前

    关于最大性能的Cassandra或ScyllaDB数据库模式的问题。

    有两个实体:类别1*项目(一个类别中可以有多个项目)。只能执行以下操作:

    1. 创建新类别
    2. 向类别中添加新项目。
    3. 阅读整个类别及其项目。(每个类别的项目总是很少,不超过50个)。

    哪种方案的性能最好?

    1. 两张桌子。类别表,项目表。项目键=(类别Id,项目Id)
    2. 一张表格用于分类和项目。项目以列表(集合)的形式存储在类别字段中
    3. ? 别的事

    在第一种情况下还是在第二种情况下添加新项目会更快? 当然,从一张桌子上阅读会更快。

    0 回复  |  直到 1 年前
        1
  •  1
  •   Mário Tavares    1 年前

    根据您描述的3种操作类型,我假设每个类别中的项目都没有更新或删除。

    简单的答案是,单个表在所需的操作中表现良好。以下内容将是一个很好的用例:

    CREATE TABLE mykeyspace.items_by_category (
        categoryId timeuuid,
        itemId timeuuid,
        ... 
        PRIMARY KEY (categoryId, itemId)
    );
    

    另一个需要注意的方面是每个分区内的预期卷。在这种情况下,每个类别都是一个分区,每个分区都会随着它存储的每个项目行中的数据量而扩大。最好将分区大小保持在100MB以下,以避免压缩和垃圾收集问题(不过,在ScyllaDB中GC不是问题)。根据您希望包含的其他列来表示每个项目,这种情况可能是可能的,也可能是不可能的。

    例如,如果你在一个集合中有50个项目,其中每个项目平均由3MB的数据表示,你可能已经遇到了一些性能问题——这可以通过分组分区或将项目数据移动到不同的表来解决。

    您还可以为items创建一个表,但只要您不希望items_by_category表中的分区大小失控,我就会将所有类别和项目数据保存在一个表中。否则,您将不得不在应用程序中管理引用完整性——Cassandra不支持连接,也不理解外键的概念。

    我通常会避免使用集合,尤其是列表。主要原因是列表在某些非幂等操作上执行读写操作。由于itemId是唯一的,如果必须使用集合,则使用集合比列表更可取。

    此外,如果将来需求发生变化,并且集合最终存储了50多个项目,那么使用itemId作为聚类列而不是集合条目可能更具可扩展性。

    在您提供的2个选项中,将项目作为条目添加到列表中可能比将其作为列值添加到2个表中需要更长的时间(可能是因为我们正在将2个简单的升级与写前读操作进行比较,这需要一些测试)。尽管如此,最有效的解决方案应该是将每个项目添加到一个表中,这比添加到两个表中更快,假设在任何一种情况下都是简单的升级。

    这就是理论,尽管我相当有信心1表选项(没有集合)将是最优的,但我仍然强烈建议设置一个 cassandra-stress 分析测试集群中不同工作负载模型的性能。