dot Redis 8 来了——而且它是开源的

了解更多

使用 Redis Streams 高效摄取 IoT 数据

在加入 Redis 之前,我曾在一家咨询公司工作,涉及物联网 (IoT) 等技术。如果你不熟悉这个概念,物联网 (IoT) 就是关于连接到互联网的智能设备。许多这些设备包括传感器,可以产生关于现实世界的指标。一个值得注意的物联网用例例如是共享单车公司,单车本身连接到互联网,并持续向其所有者通知其位置和其他状况。但也许物联网技术最大、最有前景的应用来自工厂,即工业物联网 (IIoT)。

尽管物联网开启了无限可能,市场预测几年内将突破 1 万亿美元,并且预计有 416 亿台物联网设备将产生 79.4 ZB 的数据,但在实现基于物联网的服务时,仍然存在一些挑战需要克服,主要集中在大规模处理物联网数据方面。

大规模处理物联网数据

回想起我的咨询经验,我记得曾与一家公司的数据科学团队会面,他们遇到了物联网解决方案的问题。该团队面临的主要难题是关于将数据存储在 NoSQL 文档数据库中。他们试图在两种数据模型之间做出选择,一种会优化查询速度,而另一种会优化空间效率。

第一个模型是将每个数据点存储为一个文档,像这样

{
    “Id”: “1-2-3”,
    “Time”: 123123123,
    “Longitude”: 0.123,
    “Latitude”: 0.123,
    “Battery”: 0.66
}

这种方法会带来最快的查询速度,但缺点是会占用大量存储空间。另一个旨在更有效地利用空间的模型看起来像这样

{
    “ChunkId”: “abc”,
    “ChunkStartTime”: 123123123,
    “Chunk”:[
        [
            “1-2-3”,
            123123123,
            0.123,    
            0.123,
            0.66
        ],
        [
            “4-5-6”,
            456456456,
            0.456,
            0.456,
            0.99
        ],
        ...
    ]
}

正如你所见,第二个模型更为复杂:每个文档在一个块中包含多个数据点。这个模型需要更复杂的查询来处理这些块,但作为回报,它节省了一些空间。

当时我没有找到解决这个问题的良策,但现在我意识到,有了 Redis Streams,这个问题根本就不存在了。

在 Redis Streams 中摄取 IoT 数据

当你拥有一个杂乱的数据流,它是面向时间的且本质上不可变(通常物联网数据就是这种情况),Redis Streams 可能是用于初始摄取的正确数据结构。

一个 Redis Stream 键包含一个索引的条目列表。每个索引 ID 是一个毫秒级精度的 timestamp,后跟同一毫秒内发生的事件的 sequence number。每个条目是一系列 field-value 对,几乎与 Redis Hash 相同。“几乎”是因为 Redis Hash 很好地可视化了你可以放入 stream 的内容,但有一个小区别:一个 Redis Stream 条目可以有同一字段的多个实例,而 Redis Hash 中的字段是唯一的。

以下命令展示了如何向 Redis Stream 添加一个条目。查看文档以了解更多信息。

> XADD mystream * time 123123123 lon 0.123 lat 0.123 battery 0.66

Redis Streams 使用基数树 (radix tree) 数据结构进行索引,该结构压缩索引 ID 并允许对条目进行常数时间访问。

字段名的隐藏成本

Redis Streams 还采用了另一种应用于字段名的智能空间节省机制。

你可能不常考虑这个问题,但你为条目字段选择的名称会影响每个条目占用的空间。使用 SQL 数据库时不会出现这个问题,因为模式在表级别是固定的,但缺点是你失去了灵活性。使用 NoSQL 文档数据库时,你获得了更大的灵活性,但文档会有重复存储代表字段名的字符串的开销。

在 Redis Streams 中,stream 中的每个条目可以有不同的字段集,因此你可以拥有所需的全部灵活性,但如果你保持字段集稳定,Redis 将不会多次存储它们的名称副本。根据你拥有的字段数量,通过此功能避免的开销可能会很大。

举个简单的例子,假设你有 100 万个条目,每个条目有 20 个字段,平均字段名长度为 15 字节。这意味着每 100 万个条目可以避免大约 300 兆字节的开销。

后续步骤

虽然 Redis Streams 非常适合物联网用例,但它们绝不仅限于物联网。反过来说,Redis 中还有许多其他数据结构可以帮助你在大规模数据摄取时节省空间,例如概率数据结构

掌握 Redis Streams 后,可以考虑使用 RedisTimeSeries 模块来存储从你摄取的原始数据中派生的数值时间序列数据。如果你想了解更多关于 Redis Streams 和 RedisTimeSeries 的信息,请报名参加我们于 2020 年 5 月 12 日至 13 日在线举行的 RedisConf Takeaway 的培训日活动。