一种压缩数据的方法而不会丢失(几乎)任何数据
语境
这个故事是关于一个物联网项目,该项目托管在AWS上,摄取了某些设备产生的数据。
该系统是一个分布式体系结构,在摄入阶段之后,原始数据通过 Amazon Kinesis数据流。
此流是一堆服务的来源,每个服务都负责我们需要在数据上执行的不同处理。
Kinesis是系统的关键点,因为它允许每个消费者以速度读取事件并处理,从而使每个处理管道都独立于其他处理管道。运动型还可以吸收所有流量峰,并允许当一个或多个处理管道被暂时禁用时摄入继续。
交叉检查需要
在项目的演变中,验证在数据流上执行的处理变得重要。这个想法是找到一种方法来保存 原始数据,以便可以交叉检查结果,快速进行故障排除并验证处理。
当数据数量很大时,您不能简单地将其保存在关系数据库中,并以所有可能的方式,现在和将来查询它。但是OpenSearch(和 elasticsearch 当然也可以做得很好,也是查询和过滤数据,制作高级聚合和可视化结果的绝佳工具,从字面上看>几秒钟内 ,无需初步数据准备。
因此,我们添加了一种 sniffer组件,它开始在快速富集/否定过程后将其消耗到kinesis并将其保存到OpenSearch中。
结果是一个索引,其中包含来自所有设备的所有数据,并且OpenSearch已被证明是我们故障排除需求的绝佳工具。
绩效和成本考虑
OpenSearch非常好的数据非常好,但是在我们的情况下,每个文档约为2KB,我们每天必须存储4000万个文档。
我们开始使用每日索引。从性能的角度来看,OpenSearch运行良好,但是每个索引约为22千兆字节,这意味着每年的数据大约8台。对于一项服务而言,毕竟不是系统的一部分的一部分,而是“数据可观察性工具”。
成本很快就开始太高了,我们看到的第一个选择是删除旧数据并仅保留最后两个或三个月的尾巴。
可以肯定的是,这是一个选择,但是有时可以对长期数据执行查询可能很有趣,例如,只有一台设备的数据,但是很长一段时间,例如一年,甚至更多。
一个更好的选择是找到一种汇总数据,减少数据大小的方法,因此通过支付类似的成本来保留更多数据。
滚动工作
清洁剂的方式似乎正在使用Index rollups,该功能通过以完全透明的方式自动降低数据粒度。
经过一些测试,我们注意到有了数据,我们遇到了一些错误。可能与我们的数据中的某些问题有关,或者可能存在错误,因为Opensearch相对年轻。我们没有发现这些失败背后的原因,我们没有有用的日志,也没有时间花在调查上。
除此之外,此解决方案在聚合类型中受到限制,因为 crolups jobs 只能执行 all all , min , max , sum , avg 和 value count 。
在我们的情况下,它对我们在聚合逻辑上的自由可能很有用,例如,收集公制的分布。
因此,我们探索了使用index transform的选项,通过此功能,我们终于达到了目标。
转变工作
该解决方案基于具有不同需求的2组数据集的想法:
- A 滑动窗口未压缩原始数据 (在我们的情况下,被配置为最近两个月)
- A 历史集 压缩数据,尽可能长时间地进入过去
不久,这就是解决方案的工作方式:
- eventbridge 规则被安排每天执行并启动lambda函数
- lambda为压缩数据创建一个月度索引及其mapping(在OpenSearch中,这些操作是依据的)
- lambda删除了比配置的滑动窗口更古老的未压缩数据的每日索引(在我们的情况下,这意味着在执行时间之前将第61次每日索引删除)
- lambda创建每日转换作业,以立即执行
- 执行转换作业,并在前一天的数据上工作
- 每个设备的数据以1小时的块汇总
- 使用可用的标准聚合( min , max ,平均等)汇总某些指标等)
- 使用自定义scripted_metric aggregations处理其他指标,并利用MAP/COMBEIND/DYDES SCRIPSTING的灵活性,在我们的情况下,将数据简化为自定义分发报告
的优点和缺点
根据我们需要进行的调查,我们可以决定使用最新的原始数据或历史压缩数据更好。
例如,如果需要检查上周的特定设备确切发送了什么,我们可以使用未压缩的原始数据的每日索引。
取而代之的是,如果需要在去年研究趋势,则按月索引是正确的数据源。
该解决方案的一个负面方面是,当我们开始进行可视化时,我们必须预先确定我们要工作的两个数据源中的哪一个。模式不同,因此在每日索引上创建的可视化将无法在每月索引和反之亦然。
这并不是真正的主要问题,因为通常您非常了解什么来源适合特定需求。无论如何,从这个角度来看,索引汇总功能可以肯定更好,因为数据源是相同的,您不必处理此双重数据源。
一些快速计算
每天的原始数据未压缩索引
- 每个JSON文档约为1.6 kb
- 每个指数平均包含4000万个文件
- 平均每日指数大小 23 GB
- 一个月的数据大约是 700 GB
每月汇总索引
- 每个JSON文档约为2.2 kb
- 每个指数平均包含1500万个文件
- 索引每月的规模平均为 6 GB
最终考虑
很容易看到由此产生的压缩比大致 100:1 。
这意味着,即使为1副复制品配置历史索引,并使它们的尺寸增加一倍,但要处理一个月的原始数据所需的磁盘空间也使我们可以存储超过 4年 汇总数据。
除了该操作搜索之外,查询汇总索引的速度要快得多。
在实施此解决方案之前,我们存储了1年的原始数据,但是由于性能问题,我们必须将OpenSearch集群扩展到最高6个节点。对于计算和存储资源,这产生了相当大的成本。
使用此无服务器解决方案可以自动化数据聚合,我们能够将群集大小降低到只有3个节点,每个节点都具有较小的存储。
换句话说,由于数据的少量丢失,今天我们花费更少的钱,而我们负担得起保留所有历史数据。