Cassandra 查询灵活性

Cassandra query flexibility

我是大数据领域的新手,目前正为一个基本决定所困。

对于一个研究项目,我需要每分钟将数百万条日志条目存储到我的基于 Cassandra 的数据中心,这工作得很好。 (单数据中心,4个节点)

Log Entry
------------------------------------------------------------------
| Timestamp              | IP1         | IP2           ... 
------------------------------------------------------------------
| 2015-01-01 01:05:01    | 10.10.10.1  | 192.10.10.1   ...
------------------------------------------------------------------

每个日志条目都有一个特定的时间戳。首先应按不同时间范围查询日志条目。按照建议,我开始 "model my query" 大排行。

Basic C* Schema
------------------------------------------------------------------
| row key              | column key a         | column key b     ... 
------------------------------------------------------------------
|  2015-01-01 01:05    | 2015-01-01 01:05:01  | 2015-01-01 01:05:23
------------------------------------------------------------------

其他详细信息: column keys由timestamp+uuid组成,唯一性,避免重写; 特定时间的日志条目通过其相同的分区键存储在节点附近;

因此,日志条目以每行的短时间间隔存储。例如,2015-01-01 01:05 的每个日志条目都精确到一分钟。查询并没有真正作为使用 < 运算符的范围查询来执行,而是将条目 select 编辑为指定分钟的块。

基于范围的查询成功响应时间不错,这对我来说很好。

问题: 在下一步中,我们希望通过查询获取更多信息,这些信息主要集中在 IP 字段上。例如:select 所有具有 IP1=xx.xx.xx.xxIP2=yy.yy.yy.yy 的条目。

很明显,当前模型非常不适用于其他以 IP 为中心的 CQL 查询。所以问题不是找到一个可能的解决方案,而是可能的技术的各种选择可能是一个可能的解决方案:

  1. 尝试使用独立的 C* 解决方案解决问题。 (构建第二个模型并以不同的形式管理相同的数据)
  2. 选择其他技术,例如 Spark...
  3. 切换到 HDFS/Hadoop - Cassandra/Hadoop 解决方案...
  4. 等等

由于我在这个领域缺乏知识,很难找到我应该采取的最佳方法。尤其是感觉集群计算框架的使用是一个过度的解决方案。

据我了解您的问题,您的 table 架构如下所示:

create table logs (
  minute timestamp,
  id timeuuid,
  ips list<string>,
  message text,
  primary key (minute,id)
);

有了这个简单的架构,您:

  • 可以获取特定分钟内的所有日志。
  • 可以获取短的分钟间范围的日志事件。
  • 想通过IP查询数据集。

在我看来,有多种方法可以实现这个想法:

  • 创建 IP 地址二级索引。但在 C* 中你将失去按时间戳查询的能力:C* 无法合并主二级索引(如 mysql/pgsql)。
  • 非规范化数据。一次将您的日志事件写入两个 tables,首先针对时间戳查询进行优化(分钟+ts 作为 PK),其次针对基于 IP 的查询(IP+ts 作为 PK)进行优化。
  • 将 spark 用于分析 查询。但是 spark 每次都需要执行(完整?)table 扫描(以一种漂亮的分布式 map-reduce 方式,但它仍然是 table 扫描)以提取您请求的所有数据,所以您的所有查询都需要很长时间才能完成。如果您计划进行大量低延迟查询,这种方式可能会导致问题。
  • 使用 ElasticSearch 等外部索引进行查询,使用 C* 存储数据。

在我看来,C* 做这些事情的方法是为不同的查询设置一组单独的 table。它将使您能够执行超快的查询(但会增加存储成本)。