Cassandra:高容量传感器数据澄清

时间:2017-01-09 23:21:26

标签: cassandra time-series nosql

我们正在考虑将我们的时间序列应用程序从SQL Server转换到Cassandra,因为数据量太大而SQL Server无法处理。我们可以同时使用多达100个传感器(有时一整年,有时更短,但通常至少50个同时工作),每个传感器最多可以传输20个不同的测量值,最高可达60 Hz (未来可能有120个)。

大多数在线资源(例如DataStax)建议将其划分为“可管理的分区”,大概是1,000,000行以下(实际上,低于50MB的内容可能是实际的指标)。因此,对于1 Hz报告速率,将每个传感器数量划分一周将为每个分区产生(7 * 24 * 60 * 60) = 604,800个测量值:

CREATE TABLE measurements (
    sensor_id       TEXT,
    quantity        TEXT,
    start_of_week   TIMESTAMP,
    offset_seconds  INT,        -- offset from week start (0..604799)
    value           FLOAT,
    PRIMARY KEY ((sensor_id, quantity, start_of_week), offset_seconds)
) WITH CLUSTERING ORDER BY (offset_seconds DESC)

因此,当然,对于 60 Hz 报告率,我可能会按小时进行分区,以保持简单,并为每个分区进行(60 * 60 * 60) = 216,000次测量。当然还是几个小时。

但是,我对这在实践中如何运作存在一些不确定性。

到目前为止,我们有一个相当非规范化的SQL Server数据库,我们将单个传感器中的所有20个值放在一行中,并且服务器能够跟上(尽管CPU不断为~30%)最多50个设备(基本上每秒3000行,我们假设SQL Server最大可达10,000行/秒)。毋庸置疑,如果每台设备增加新数量,这根本无法扩展,同时报告少于20个数量的设备浪费了大量空间。

然而,采用上述C *方法,似乎每秒存储的键值对的数量(假设100个传感器,20个测量值,60 Hz)将每秒120,000

  1. 是否可以通过“base”3节点设置实现此目的?对于这样的插入率,实际上需要多少个Cassandra节点?

  2. 将单个数量的所有亚秒(60 Hz)值移动到单个 blob 会改善性能吗?这意味着总插入率将为2,000 blobs ,这似乎更易于管理(即使60个float32值的blob大小为240字节也不会那么大)。

  3. 大多数情况下,数据将从另一个表中显示,该表保存预先计算的最小/最大/平均聚合(用户可以随时创建全分辨率范围查询,但对于较小范围),因此我们的重点是最大化写入吞吐量。如果你认为任何其他模式可能提供更好的吞吐量(我没有线索,可能是多个表/一些其他分区/集群策略),请建议。如果能够更好地满足我们的要求,我们甚至可以切换到不同的NoSQL数据库。

1 个答案:

答案 0 :(得分:4)

  

是否有可能通过" base"来实现这一目标。 3节点设置?对于这样的插入率,实际上需要多少个Cassandra节点?

具有3节点集群的每秒120,000肯定是可能的,但它在很大程度上取决于您的硬件。我希望普通实例的速度为20k-30k / sec。我坚持的经验法则是4k / sec / core,但它依赖于硬件/负载。

  

将单个数量的所有亚秒(60 Hz)值移动到单个blob中会改善性能吗?这意味着总插入率将为2,000 blob,这似乎更易于管理(即使60个float32值的blob大小为240字节也不会显得那么大。)

是的,它有助于提高吞吐量。

一些注意事项:

确保使用此类负载,您的客户有效地执行查询,或者您可能会看到瓶颈。根据飞行请求进行插入异步并应用背压是一个好主意。有批处理,但只有当所有写入进入同一分区时才有效。因此,如果您有第二个读数并且将它们全部插入到同一个分区中,则执行未记录批处理会更快。记录的批次将大大减慢。有一点,这最终会使性能变差,但不同工作负载的数量会有所不同,所以可能想要使用它。

我建议为此工作负载制定定时窗口压缩策略(TWCS)。

在2.x版本中,每个分区100mb是一个很好的限制,试图保持不变。在以后的3.x版本和4.x版本的未来版本中,你会更安全更高(即gb)。那说分区仍然是最低级别,所以如果它们变得太大,它仍然可能导致热点,并且它使维修之类的东西效率降低。请关注监控中的最大/平均表分区大小。

使用offset_seconds实际上更适合作为完整时间戳。当您执行读取操作时,它会检查最小/最大群集密钥与查询的内容,以确定要读取哪个sstable。每个sstable都存储其最小/最大聚类键以优化这样的时间序列。如果您有TWCS并且您正在查询一段时间,那么它将能够将sstables缩小到相关的范围。否则它可能包含很多它们,因为偏移将在每个桶中重置并且具有重叠。布隆过滤器应该捕获具有不同分区键的一些但是它将具有误报并且需要检查所有sstables上的布隆过滤器(这是在从最小/最大值中拾取并且远非空闲之后完成的)。它似乎对空间来说有点浪费,但它会提高读数。