关注分享主机优惠活动
国内外VPS云服务器

Skywalking IoTDB存储插件设计步骤

摘要:提交给社区供社区审核。 代表统计数据。 这是通过脚本或硬编码对源数据进行聚合分析后生成的存储模型。 这种解决方案丢失了需要索引的内容,因此您必须对需要索引的记录进行硬编码。

该项目来自开源软件供应链写作计划 - Summer 2021 Apache IoTDB - Apache Skywalking Adapter 项目。 该项目已提交给 Skywalking 社区(IoTDB 存储插件 #7766),目前正在开发中。 社区审查。

实现思路

该项目的目标是为 Skywalking 开发一个适配器,使用 IoTDB 来读写相关数据。 了解 Skywalking 目前如何使用 InfluxDB、H2 和 E。Elasticsearch 的适配器。 Skywalking提供了存储扩展的开发指南和参考链接。 此外,需要 Skywalking 和 InfluxDB 调试过程才能完全理解 Skywalking 的界面和用法。

IoTDB 建议您使用其提供的本机客户端包(会话或会话池)与 IoTDB 服务器交互。

开发平台:Win10,IoTDB版本:0.12.2

相关概念

Skywalking存储模型

Skywalking 8.0+存储模型为如下: 它分为四类:Record、Metrics、NoneStream 和 ManagementData。 所有这些都实现了 StorageData 接口。 StorageData 接口必须实现 id() 方法。 下面分别介绍这四种存储模型。

记录:大部分记录是原始日志数据或任务记录。 应存储该数据而不进行进一步分析。 Record类的所有模型都有一个time_bucket字段,用于记录当前Record所在的时间窗口。 具体示例有 SegmentRecord、AlarmRecord、BrowserErrorLogs、LogRecord、ProfileTaskLogRecord、ProfileThreadSnapshotRecord、TopN。

SegmentRecord:跟踪段的详细记录模型。 TraceSegment是skywalking-trace-receiver-plugin插件接收并解析Skywalking Agent发送的链接数据后得到的。 AlarmRecord:报警详细记录模型。 当指标触发报警规则时,会生成对应报警的详细数据模型。 TopN:TopN是一个带有statement字段的采样模型(用于解释)。(采样数据的关键信息)、latency字段(用于记录采样数据的时延)、track_id字段(用于描述采样数据的关联分发链路ID)、service_id字段(用于记录采样数据的关联分发链路ID) ),(用于记录服务ID中的延迟)。 目前,采样模型默认仅包含TopNDatabaseStatement。 TopNDatabaseStatement:按延迟排序的数据库采样记录。

指标:指标代表统计数据。 统计数据是通过OAL脚本或硬编码对源数据进行聚合和分析而产生的存储模型。 它的生命周期由TTL(生存时间)控制。 Metrics 类中的所有模型都有一个 time_bucket 和一个entity_id 字段。 示例:NetworkAddressAlias、Event、InstanceTraffic、EndpointTraffic、ServiceTraffic、EndpointRelationServerSideMetrics、ServiceInstanceRelationServerSideMetrics、ServiceInstanceRelationClientSideMetrics、ServiceRelationServerSideMetrics、ServiceRelationClientSideMetrics

NoneStream:NoneStream 基于 Record,time_bucket 到 TTL 支持转换。 示例:ProfileTaskRecord

ManagementData:UI模板管理相关数据。 默认情况下只有一个 UITemplate 实现类。

部分参见 Apache Skywalking 实战,第 9 章:SkyWalking OAP。 服务器存储模型

p>

IoTDB数据模型

查看官方IoTDB数据模型介绍。 简单来说,是可以的使用树结构了解 IoTDB 的数据模型。 按级别,从高到低:存储组 -> (LayerName) -> 设备 -> 时间序列。 从顶层到下面特定层的路径称为路径。 最顶层是存储组,倒数第二层是设备,从第一层到最后一层是时间序列。 中间可以有很多层,每个层称为一个 LayerName。

请注意,每个存储组都需要一个线程,因此存储组过多会降低存储性能。 此外,LayerName 值存储在内存中,Timeseries 值及其下面的数据存储在硬盘上。

Skywalking的IoTDB-适配器存储解决方案

概念上的拆分

Skywalking中的每个存储模型都可以被认为是一个模型,一个模型可以有多个包含列。 每列都有一个 ColumnName 和 ColumnType 属性,分别表示列的名称和类型。 每个ColumnName下存储了多个ColumnType数据类型的数据值。 从关系数据库的角度来看,模型是关系表,列是关系表的字段。

方案一:类关系数据库存储方案(不可行)

将所有Skywalking存储模型写入IoTDB的存储组(例如root.skywalking存储组)。 模型对应于设备,列对应于时间序列。 也就是说,Skywalking 中的“数据库- > 模型- > 列”对应 IoTDB 中的“存储组- > 设备- > 时间序列”。 该解决方案只有4个IoTDB存储路径图层:root.skywalking.ModelName.ColumnName。 该方案的优点是逻辑清晰,实现难度较小。 但由于数据存储在硬盘上,查询效率比较差。

结果:该方案无法实现
原因:部分存储接口要求实现按entity_id查询分组的功能,但IoTDB仅支持按时间分组的功能。 解决方案2必须通过基于级别的小组来采用和实施。

选项 2:部署索引存储解决方案

IoTDB 中的每个 LayerName 都存储在内存中,因此可以被视为索引,使您可以利用它。 此功能提高了 IoTDB 查询性能。

继续将所有Skywalking存储模型写入IoTDB中的存储组,例如root.skywalking存储组。 Model对应一个LayerName,需要索引的Column也对应一个LayerName。 不过LayerName存储的并不是ColumnName,而是对应的Value。 这相当于为同一分支下同一层中需要索引的列存储不同的值。 不需要索引的列对应于路径的最后一级Timeseries。 最终,同一模型的数据将分布在多个设备上。

这种方案丢失了需要建立索引的ColumnName,因此需要通过硬编码的方式记录需要建立索引的ColumnName和ColumnType。 另外,还需要保证模型中多个索引列的顺序,避免存储混乱。 计划是对模型应索引的列的存储顺序进行硬编码。

本方案中IoTDB存储路径的长度是可变的。 索引中的列越多,路径就越长。 示例:

当前 model1(column11,column12)、model2(column21column22、column23)、model3(column31),下划线表示该字段必须建立索引。

需要索引的模型:root.skywalking.model1_name.column11_value.column12_nameroot.skywalking.model2_name.column21_value.column22_value.column23_name 不需要索引的模型索引 所需索引:root.skywalking.model3_name.column31_Name

插入:

[ k4]- 插入模型 1插入 skywalkingmodel1_namecolumn11_value (次tamp,column12_value);-- 插入模型 2插入  root .skywalking.model2_name.column21_value ">.column22_value (时间戳 , column23_name);

查询:

--查找model1中的所有数据select *来自skywalking .model1_name;-- 查找model2中column22_value="test"的数据选择 * .skywalking.model2_name.* .测试;--根据第21列对模型2第23列求和进行分组统计选择 总计(column23)来自  rootskywalkingmodel2_name** span>  级别 =  3;

该解决方案的优点重要的是,它实现了类似于InfluxDB标签的索引功能,但逻辑更加复杂且难以实现。 另一方面,您需要进一步决定哪些列应该用作索引列。 这方面可以参考Elasticsearch(StorageEsInstaller)、InfluxDB(TableMetaInfo)、MySQL(MySQLTableInstaller)以及ModelColumn的isStorageOnly属性的实现。

该解决方案通过 LayerName 将一些数据存储在内存中,这可能会导致大量数据产生显着的内存开销。 此外,同一模型的数据分布在多个设备上,因此查询通常需要跨多个设备运行。 不过,IoTDB 对跨设备聚合、排序、分页查询的支持在这方面还不是很完善。 在某些情况下,您可能需要使用强力技术来查找所有符合您条件的数据并自行实现聚合和排序。 、寻呼功能。 有关具体说明,请参阅下面提交给 IoTDB 社区的问题和讨论。

问题:希望选择函数“top_k”和“bottom_k”能够支持“按级别分组” #3905 希望模糊查询能够支持多-个设备 #3945 “按级别分组”Group'无法获取节点name #4006 讨论:排序查询的问题(Issues with sort query) #3888 聚合查询的问题(Issue withaggregate query) #3907

要索引的字段已确定

id
entity_id
node_type
service_group
service_id
trace_id

此外,time_bucket可以转换并保存为IoTDB自带的时间戳。 单独保存time_bucket。

解决方案性能测试

开源软件供应链照明计划InfluxDB 协议或客户端兼容性参考项目设计文档 - 2021 年夏季,我们可以看到有索引和没有索引的查询时间有几倍的差异。

Skywalking-IoTDB适配器配置参数

host,IoTDB主机IP,默认127.0.0.1rpcPort,IoTDB监听端口,默认6667用户名、用户名、默认 root 密码、密码、默认 rootstorageGroup、存储组名称、默认 root.skywalkingsessionPoolSize 、会话池大小、默认16fetchTaskLogMaxSize,一次请求获取的TaskLog最大数量,默认为1000

遇到的问题及解决办法

问题一: Skywalking 中的某些存储接口需要 order by 查询,但 IoTDB 仅支持 order by time 。 这允许您使用选择函数 top_kbottom_k 过滤数据。 然而,当使用索引方案时,由于数据点分布在多个设备上,top_kbottom_k函数无法过滤数据,而group by level和类似的耦合设备也不可用。 代码>. 有关如何查询的详细说明,请参阅讨论#3888、问题#3905。

解决方案:目前除了暴力查询和排序所有文件的方法外,没有其他解决方案。

问题2:Skywalking中的一些存储接口需要group byentity_id的分组聚合查询,但IoTDB不需要group by time代码> 和 group by level

解决方案:采用方案二,将entity_id存储为LayerName,通过group by level实现分组查询。

问题3:使用索引方案时,数据点分布在多个设备上,因此正确使用聚合函数需要必须通过group by level。 统计数据。 但是,在这种情况下,同时使用 group by levelwhere 将不会产生所需的结果。 我需要添加 align by device 语义,但添加后出现 IllegalPathException。 我们推测这是因为 IoTDB 无法同时支持 group by levelalign by。 设备 语义。 有关详细说明,请参阅讨论#3907。

解决方案:使用按设备对齐。通过过滤和查询 where 上的所有数据,自己实现聚合函数的功能。

问题4:Skywalking的存储接口需要模糊查询,但IoTDB使用类模糊查询,不支持跨设备查询,所以选项2不适合 另外,IoTDB的字符串函数string_contains只能返回true/false,不会过滤数据。 有关详细说明,请参阅问题 #3945

。 解决方案:首先使用select *, string_contains获取查询结果,然后根据true/false循环进行过滤。 后来,@ijihang 提交的 PR#3953 启用了对跨设备查询和每设备对齐的支持。 因此,这个问题可以直接使用类似MySQL的模糊查询来解决。 再次感谢。

问题5:Skywalking的存储接口需要模糊和过滤查询。 由于索引方案,需要跨设备查询。 但是,使用 string_contains 函数的过滤查询无法正确过滤数据,因为它们使用多设备和跨设备语义。 如果数据是 or 的语义,现在可以正确过滤数据。 同时,string_contains不支持使用align by device。 在上述情况下,仅支持时间过滤。

解决方法:先使用select *, string_contains from root.skywalking.xxx.* where time > ?得到结果后自己过滤其他条件。 随后采用了与问题4类似的解决方案。 只需使用类似于 MySQL 的模糊和过滤查询即可。

总结

当前的存储解决方案仍然使用暴力技术进行查询。 即使通过了Skywalking社区的审核,由于数据传输开销较高,占用系统处理资源较多,性能也不足。 问题。 目前还没有好的办法解决。 您应该等待 IoTDB 针对此类场景添加不同语义的关键字或改进现有的查询语义。

未经允许不得转载:主机频道 » Skywalking IoTDB存储插件设计步骤

评论 抢沙发

评论前必须登录!