圆点 快速发展的未来正在向你的城市举办的一场活动靠拢。

加入我们,参加 Redis 发布会

使用 Redis Streams 高效获取 IoT 数据

加入 Redis 之前,我曾供职于一家咨询公司,主要接触物联网 (IoT) 等技术。如果你不太熟悉这个概念,物联网与连接到互联网的各种智能设备息息相关。许多此类设备包括可产生现实世界指标的传感器。例如,值得注意的物联网用例之一是共享单车公司,共享单车本身连接到互联网,并会不断向其所有者通报其所在位置和其他状况。但物联网技术可能最大的用处莫过于工厂或工业物联网 (IIoT)。

尽管物联网开辟了广阔的可能性,市场预测将其市值达到数万亿美元,而一些 物联网连接设备预计可产生 79.4 个泽字节的数据,但实施基于物联网的服务仍面临着一些挑战,主要关于大规模处理物联网数据。

大规模处理物联网数据

回到我作为咨询顾问的经历,我记得曾与一家公司的某个数据科学团队会面,这家公司遇到过物联网解决方案相关的问题。该团队面临的主要难题是将数据存储在 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 中摄取物联网数据

如果你拥有一个杂乱的数据流且该数据流具有时间定向并本质上是不可变的(就物联网数据而言通常如此),那么 Redis Streams 可能为初始摄取而提供的正确的数据结构。

Redis Stream 键包含一个编制索引的条目列表。每个索引 ID 是一个精确到毫秒的时间戳,后跟在同一毫秒内发生的事件的序列号。每个条目都是一个字段-值对序列,与 Redis 哈希几乎相同。“几乎”相同,因为 Redis 哈希是用于对可以放入流中的内容进行可视化的一种好方法,但有一点小不同:一个 Redis Stream 条目可以包含同一字段的多个实例,而 Redis 哈希中的字段是唯一的。

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

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

Redis Streams 使用基数树数据结构进行索引,该结构压缩索引 ID,并允许恒定时间访问条目。 

字段名称的隐藏成本

Redis Streams 还采用了另一种明智的空间节省机制,该机制适用于字段名称。

你可能不经常想到,但你为条目字段选择的名称会影响每个条目占用多少空间。使用 SQL 数据库时,因为架构是固定在表级别的,所以这个问题不会出现,但缺点是会降低灵活性。使用 NoSQL 和基于文档的数据库时,灵活性更高,但此后文档在反复保存代表字段名称的字符串时会有开销。

在 Redis Streams 中,流中的每个条目可以包含一组不同的字段,因此,你可以拥有所需的灵活性,但如果保持字段集稳定,Redis 不会存储其名称的多个副本。根据字段的数量,此功能可以避免的大量开销可能很可观。

举例来说,假设你有 100 万个条目,每个条目包含 20 个字段,字段名称的平均长度为 15 个字节。这意味着大约可以为每百万个项目节省 300 兆字节的开销。

后续步骤

虽然 Redis 流非常适用于物联网用例,但几乎不限于物联网。相反,Redis 中还有许多数据结构可以帮助你在大规模摄取数据时节省空间,例如概率数据结构

掌握 Redis Streams 后,不妨考虑使用 RedisTimeSeries 模块,用于存储您摄取的原始数据派生而来的数字时间序列数据。如果您想了解有关 Redis Streams 和 RedisTimeSeries 的更多信息,请注册参加我们在 RedisConf 2020 外卖 的培训日,于 5 月 12-13 日在线举行。