Cassandra多租户配置选项

3
我们正在评估是否要将基于PostGres的多租户EAV系统迁移到Cassandra,并希望就我们的模式方法征求意见,以确定是否有必要使用Cassandra进行测试。我们的多租户系统层次结构由账户->应用程序组成,其中一个账户可以运行多个应用程序。查询需要按应用程序或按账户进行分隔(汇总账户的所有应用程序数据)。在我们的EAV模型中,账户可以创建自己的数据对象和自己的自定义字段。
我考虑过两种使用Cassandra的方法。第一种是在一个列族中保存一定数量的应用程序(比如20个)(以减少使用的列族数量)。每行将由一个复合列accountid->appid->dataobjectid->recordid标识。对于每个应用程序所需的数据对象,列会根据需要动态添加。这意味着如果列族有两个应用程序,则第一个应用程序的一行可能定义了20个列,而第二个应用程序可能定义了30个列。这意味着这两个应用程序总共有50个潜在列。现在,一个应用程序的平均列数为19。这意味着列族中列的平均数量为400。这看起来很合理,并利用了Cassandra的宽列支持。实际上,我们可能可以轻松支持更多的应用程序。缺点是二级索引会很困难,因为我们不允许用户创建自己的索引,所以查询不能更有效地进行。
第二种方法是有两个列族来保存1000个应用程序的所有数据。第一个列族将具有与上述相同的复合列,但它将在JSON文档中保存该行的整个数据对象。第二个列族将具有相同的复合键,但会向键添加另一个值,即表示JSON文档中字段的fieldid(我们的应用程序元数据管理器存储UUID以标识JSON文档中的每个“字段”),但对于每种数据类型都会有一个“fieldvalue”列-字符串、数字、十进制数、浮点数(日期和布尔值转换为数字)。这里的好处是我们可以轻松地为每个列建立索引以进行搜索,并且我们正在最小化我们创建的列族数量。
以上两种方法的优缺点是什么?我是否遗漏了明显的内容或误解了Cassandra(例如,我是否可以在第一次使用时拥有如此宽的复合列)?是否有其他更好的模式建议适用于这种类型的应用程序?
1个回答

2
我认为在确定数据模型时,你需要回答的第一个问题是“我打算如何查询这些数据?”一般来说,在任何一种模型中,CFs、列或复合组件的数量都远未达到极限,因此我不会担心这个问题。
考虑到你关心第一个模型缺少次要索引,这告诉我按值查询功能可能很重要。如果是这样,第二个模型可能更适合你。但其中的警告是,次要索引最适用于基数低的情况,而你的数据可能不适合这种情况。如果不行,你可以很容易地创建自己的索引,在这种情况下,任何一种模型都可以使用。
我的建议是找出你打算如何读取数据,然后根据你的读取模式规划你的模型。如果你不确定,可以尝试两种模型,看哪一个效果更好。根据我的经验,通常需要多次迭代才能得出一个好的模型,你不应该害怕以不止一种方式写入你的数据。这里的目标不是规范化。如果想更深入地讨论你的模型,请查看freenode (#cassandra)上的Cassandra IRC频道。

实际上,对于我们所讨论的数据,基数往往非常高,这就是为什么我倾向于第二个选项的原因。因此,在复合键中使用4个UUID没有任何问题,这是一个好消息,因为这是我担心的其中之一。 - AlexGad
由于您正在考虑将数据存储为JSON并需要按值查询功能,因此您可能还可以将MongoDB列入您的短列表。它几乎是为这种用例量身定制的。 - rs_atl
是的,Mongo已经是这个项目的一部分了,但我正在寻找Cassandra为这个特定项目提供的线性可扩展性。 - AlexGad
Cassandra一定会扩展。如果您想编辑您的问题以包括您期望的查询,我可以提供更多帮助来完成它。 - rs_atl
我希望我能够解决这个问题。这是问题的核心(也是任何EAV模型的问题)-Cassandra对即将运行的查询类型非常敏感,但不幸的是,由于每个应用程序可以拥有完全不同的域模型和查询要求,因此没有标准查询。我们唯一确定的事情是,所有查询都必须按appid分隔,以便一个应用程序无法读取另一个应用程序的数据。 - AlexGad
如果是这种情况——并且您决定Cassandra是正确的选择——您可能需要构建针对每个客户的索引,以便为其特定的读取模式提供实时查询功能。此外,您可能需要使用Hadoop批量提取所需数据以回答您的查询。 - rs_atl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接