3

我来自 RDBMS 背景并设计了一个以 Cassandra 作为后端的应用程序,我不确定我的设计的有效性和可扩展性。

我正在开发某种书籍/电影/等的评级/反馈应用程序。由于 Cassandra 有灵活列族(稀疏结构)的概念,所以我想到了使用以下模式:

user-id (row key): book-id/movie-id (dynamic column name) - rating (column value)

如果我这样做,我最终会拥有数百万列(这将是 RDBMS 中的行),尽管本质上与行键无关,例如:

user1: {book1:Rating-Ok; book1023:good; book982821:good}
user2: {book75:Ok;book1023:good;book44511:Awesome}

由于所有列族都存储在一个文件中,因此我不确定这是否是可扩展的设计(或根本不是设计!)。此外,可能会有类似的查询"pick all 'good' reviews of 'book125'"。我应该使用什么方法?

4

3 回答 3

2

这种设计是完全可扩展的。Cassandra 以稀疏形式存储数据,因此空单元格不会占用磁盘空间。

缺点是 cassandra 在按值索引方面不是很好。有二级索引,但它们应该只用于索引一两列,而不是每一百万列。

有两个选项可以解决此问题:

  • 物化视图(例如,在此处描述:http: //maxgrinev.com/2010/07/12/do-you-really-need-sql-to-do-it-all-in-cassandra/)。这允许构建一些预定义的查询,可能是相当复杂的查询。
  • 通过某种 map/reduce 作业可以进行临时查询,该作业有效地迭代整个数据集。这可能听起来很吓人,但它仍然非常快:Cassandra 将所有数据存储在 SSTables 中,并且这种迭代可能会实现以顺序扫描数据文件。
于 2012-09-13T22:55:55.977 回答
2

从一组所需的查询开始,并构建您的列族以支持这些视图。尤其是在涉及的字段如此之少的情况下,每个 CF 都可以廉价地充当自己的数据索引视图。在获取期间,密钥将最终将数据分区到一个特定的 Cassandra 节点,该节点可以以预先确定的顺序将一组宽行快速流式传输到您的应用服务器。这发挥了 Cassandra 的优势之一,因为与在 RDBMS 表的索引搜索中围绕各种轨道和扇区反弹相比,物理介质上的读取碎片(未缓存时)非常低。

一种有用的方法是选择您的键来分割数据,以便对该段中的所有列进行全面扫描是一个合理的提议,并且非常适合您的查询。然后,您过滤不需要的内容,即使该过滤是在您的客户端(应用服务器)中执行的。电影的所有评论都是一个很好的例子。即使您过滤正面评论或仅提供最近的评论或摘要,您仍然可以合理地获取该键的所有行,然后丢弃您不需要的内容。

于 2012-09-14T03:48:38.997 回答
0

另一种选择是,如果您可以弄清楚如何对数据进行分区(按时间、按类别),playOrm 提供了一种将 S-SQL 执行到非常快的分区的解决方案。它非常类似于 RDBMS,除了您对数据进行分区以保持可扩展性并且可以拥有任意数量的分区。分区可以包含数百万行(尽管在一个分区中我不会超过 1000 万行)。

后来,迪恩

于 2012-09-14T19:45:44.503 回答