CassandraDB 结构的扩展问题

Posted

技术标签:

【中文标题】CassandraDB 结构的扩展问题【英文标题】:Scaling problem with CassandraDB structure 【发布时间】:2018-09-11 16:47:52 【问题描述】:

我正在尝试创建一个基于数据库的邮件服务器。为此,我选择使用 CassandraDB。主要问题是:我的表中的邮件越多,表中的答案就越长(这是正常的,但规模很大)。目前我只收到了 20000 封邮件,Cassandra 给我发送了一个超时(显然默认设置为 5 秒)。目标是让每个用户在我的表中找到包含超过 500k 邮件的邮件,并有可能过滤他们的邮件。

这是我的表结构:

CREATE TABLE mail__mail (
    accountid uuid,
    date timestamp,
    id uuid,
    attachment set<uuid>,
    categories set<uuid>,
    content text,
    dateadded timestamp,
    folderid uuid,
    hash text,
    isconfidential boolean,
    isdeleted boolean,
    isimportant boolean,
    isseen boolean,
    mailcc text,
    mailfrom text,
    mailid text,
    mailto text,
    size bigint,
    subject text,
    PRIMARY KEY (accountid, date, id)
) WITH CLUSTERING ORDER BY (date DESC,id ASC);

CREATE CUSTOM INDEX mailFromIndex ON mail__mail (mailfrom) USING 'org.apache.cassandra.index.sasi.SASIIndex' WITH OPTIONS = 'mode': 'CONTAINS','analyzed': 'true', 'analyzer_class': 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', 'case_sensitive': 'false';
CREATE CUSTOM INDEX subjectIndex ON mail__mail (subject) USING 'org.apache.cassandra.index.sasi.SASIIndex' WITH OPTIONS = 'mode': 'CONTAINS','analyzed': 'true', 'analyzer_class': 'org.apache.cassandra.index.sasi.analyzer.NonTokenizingAnalyzer', 'case_sensitive': 'false';

我很确定我的结构很糟糕,因为我在 CassandraDB 方面的技能很差。

这是我想用这个表实现的操作:

更新:isImportant、isConfidential、isDeleted、isSeen、mailId、folderId、类别 删除:按 id、按 folderId、按 accountId 选择:按 ID、按文件夹 ID、按帐户 ID

我想用这个过滤器进行选择:

ORDER BY:日期、大小、mailFrom(ASC 和 DESC) CONTAINS : 类别(我可以为我的邮件分配一些类别,并且我想过滤一个或多个类别中的所有电子邮件) LIKE '%search%' : mailFrom,主题过滤包含我的搜索的邮件 等于:isConfidential、isImportant、isDeleted、isSeen,用于获取所有机密、重要、删除或已查看的邮件。

我的表只需要几行即可(大约在 1000 毫秒内处理 7k 封电子邮件),但我认为它可以通过良好的结构和良好的查询(没有 ALLOW FILTERING)更快。

此外,我显然不能在同一个查询中使用 CONTAINS 和 LIKE '%text%',它给了我一个 1300 错误代码。所以我在 python 中做了这一步,但在我看来这是一场性能灾难,如果我能用 cassandra 做所有事情,那就太好了。

要查询我的 CassandraDB,我使用 Python3.5 Cassandra 驱动程序,但我认为这些信息不相关。

如果您需要更多信息,请告诉我, 提前致谢!

编辑:作为一种解决方案,我遵循你们告诉我的,我使用 Elassandra (ElasticSeach + Cassandra) 部署了一个新服务器。我会尽快给你我得到的结果。

【问题讨论】:

你需要退后一步来处理这个问题。不要为您的数据建模,而是为您的查询建模。我建议去 DataStax 学院学习数据建模课程,因为这个项目在 Cassandra 中非常重要。使用另一个数据库可能会更好。避免使用二级索引,除非绝对必要并且不要使用 ALLOW FILTERING。 @Lohfink 感谢您的回答,我很确定使用 Cassandra 数据库是可行的。但我真的很感兴趣你对我应该为这个项目选择哪个数据库的意见。无论如何,我项目中的所有内容都是基于 Cassandra 数据库的,我现在很难改变,所以我最好的选择是重构我的模型并使其工作。 “我现在很难改变” - 但这不会像必须围绕您的用例设计 Cassandra 并最终在以后更改和移动数据那样困难。 【参考方案1】:

我同意@Lohfink 关于建模 C* 数据库的不同观点的建议,从查询本身开始。但根据您的要求,C* 可能并不完美。您可以通过以下方式重新设计架构:

没有使用 ALLOW FILTERING 的查询,因为它会进行表扫描。 相同的 mail__mail 架构,但将 iddate 合并到 timeuuid 以简化操作。 不用创建大量二级索引(由于高基数数据的问题)和物化视图(由于数据复制),您可以使用外部 ElasticSearch 或使用它 as a plugin 用于 C* 来执行实际搜索。

【讨论】:

【参考方案2】:

我同意@shutty,您可以将 cassandra 用于您的数据存储以及 ES 用于搜索。

【讨论】:

以上是关于CassandraDB 结构的扩展问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 cassandradb 计数器表进行查询

索引 Apache Ignite 缓存与优化的内存 CassandraDB

有啥方法可以将 Symfony PHP 框架与 Bigtable / Cassandra DB 一起使用?

Cassandra 分区问题

通过 Spark SQL 查询 Cassandra UDT

Cassandra 多个键空间或列族?