IoTDB 常见问题 QA 第四期
关于 IoTDB 的 Q & A
IoTDB Q&A 第四期来啦!我们将定期汇总我们将定期汇总社区讨论频繁的问题,并展开进行详细回答,通过积累常见问题“小百科”,方便大家使用 IoTDB。
Q1:Java 中如何使用 SSL 连接 IoTDB
问题
Java 中如何使用 SSL 连接 IoTDB?
方案
SSL(Secure Sockets Layer)是一种安全协议,用于在网络通信中提供加密、认证和数据完整性保护。它主要用于在互联网上保护数据传输,确保数据在传输过程中不被窃听或篡改。
IoTDB 支持 SSL 协议,但是在配置文件中相关参数是默认关闭的状态,如下:
# Does dn_rpc_port enable SSL
# effectiveMode: restart
# Datatype: boolean
enable_thrift_ssl=false
# SSL key store path
# linux e.g. /home/iotdb/server.keystore (absolute path) or server.keystore (relative path)
# windows e.g. C:\\iotdb\\server.keystore (absolute path) or server.keystore (relative path)
# effectiveMode: restart
key_store_path=
# SSL key store password
# effectiveMode: restart
# Datatype: String
key_store_pwd=
因此,我们需要开启 SSL,并配置 key_store 相关参数(可使用 Java 提供的 keytool 工具生成 SSL 证书),然后重启 IoTDB 服务。
enable_thrift_ssl=true
key_store_path=/iotdb/ssl/.keystore #keystore的完整路径
key_store_pwd=password #keystore的密码
重启成功后,可以先通过 CLI 窗口验证一下 SSL 是否配置成功。进入到 sbin 目录下,通过 ./start-cli.sh 命令启动,此时需要注意,开启 SSL 后,需要在执行命令的时候添加相应的参数:
./start-cli.sh -h 127.0.0.1 -p 6667 -u root -pw root -usessl true -ts /iotdb/ssl/.truststore -tpw 123456
# -usessl <use_ssl> use_ssl statement
# -ts <trust_store> trust_store statement
# -tpw <trust_store_pwd> trust_store_pwd statement
验证通过后,可以通过 IoTDB 提供的 Java 原生接口创建 SSL 连接。
Session 方式
useSSL:是否开启 SSL
trustStore:trustStore 的证书路径
trustStorePwd:trustStore 的证书密码(秘钥库口令)
session =
new Session.Builder()
.fetchSize(int fetchSize)
.host(String host)
.port(String port)
.username(String username)
.password(String password)
.useSSL(true)
.trustStore("/iotdb/ssl/.truststore")
.trustStorePwd("password")
.build();
SessionPool 方式
useSSL:是否开启 SSL
trustStore:trustStore 的证书路径
trustStorePwd:trustStore 的证书密码(秘钥库口令)
sessionPool =
new SessionPool.Builder()
.nodeUrls(List<String> nodeUrls)
.user(String username)
.password(String password)
.useSSL(true)
.trustStore("/iotdb/ssl/.truststore")
.trustStorePwd("password")
.build();
备注
使用 keytool 工具生成 SSL 证书的简易步骤如下:
1. 生成密钥对:
keytool -genkeypair -alais mykey -keyalg RSA -validity 7 -keystore .keystore
# -alias:为你的密钥对指定一个别名,示例中为 mykey。
# -keyalg:指定密钥算法,示例中为 RSA。
# -validity:证书有效期,示例中为 7 天。
# -keystore:指定密钥库文件的名称,示例中为 .keystore。
2. 导出相应的证书:
keytool -export -alais mykey -keystore .keystore -rfc -file certificate.cer
# -alias:指定要从密钥库中导出的证书的别名,示例中为 mykey。
# -keystore:指定密钥库文件的位置和名称,示例中为当前目录下的 .keystore 文件。
# -rfc:指定导出证书的格式,示例中导出证书时使用 RFC 格式,这是一种更加通用的格式
# -file:指定导出的证书文件的名称,示例中导出的证书将被保存为当前目录下的 certificate.cer 文件。
3. 将该证书导入客户端信任库:
keytool -import -alais mykey -file certificate.cer -keystore .truststore
# -alias:指定导入证书的别名,示例中为 mykey。这个别名在信任库中必须是唯一的。
# -file:指定要导入的证书文件的路径和文件名,示例中为当前目录下的 certificate.cer 文件。
# -keystore:指定信任库文件的位置和名称,示例中为当前目录下的 .truststore 文件。
Q2:IoTDB 1.2 升级 1.3 后 Pipe 插件失效
问题现象
客户使用 Pipe 功能将数据从 IoTDB 系统传输至 Kafka 集群,以便进行后续的数据处理与分析。在从企业版 1.2.5 升级至企业版 1.3.3.6 后,客户反馈 Kafka 的 consumer 无法接收到数据。经检查日志,发现存在以下报错:
问题原因
IoTDB 1.2 版本与 1.3 版本的 TsFile 包引用存在差异,导致插件中原本引用的 1.2 版本 TsFile 包下的 Tablet 类无法找到,进而使得 Kafka 插件无法正常发送数据,影响了数据从 IoTDB 系统到 Kafka 集群的传输流程。
解决方案
1. 停止并删除原 Pipe;
2. 删除原 Pipe 插件;
3. 升级 Kafka Pipe 插件包:将 Kafka 插件包升级至匹配 1.3 版本 TsFile 的版本,确保其正确引用 1.3 版本的 TsFile 包,从而恢复数据传输功能;
4. 注册新的 Pipe 插件:完成插件包升级后,需注册新的 Pipe 插件;
5. 注册新的 Kafka Pipe:使用新注册的 Pipe 插件,创建并注册新的 Kafka Pipe,建立新的数据传输通道;
6. 检查新 Pipe 可用性:启动新的 Pipe 后,检查其是否能够正常运行并成功将数据发送至 Kafka。
Q3:Pipe 数据同步 InsertNode 内存结构过多导致 DataNode OOM 问题
现象
在使用 IoTDB 1.3.3.5 及以下版本时,开启 Pipe 数据同步功能后,发送端 DataNode 频繁遭遇 Out of Memory(OOM)异常,而接收端节点(DataNode)却能正常运行。
通过 Grafana 监控发现,发送端 DataNode 的 Heap Memory 中老年代存在部分内存无法随垃圾回收(GC)过程释放,随着运行时间的推移,最终导致 OOM 并使 DataNode 节点崩溃。
进一步分析 dump 的内存文件,观察到 PipeInsertNodeTabletInsertionEvent 实例数量异常庞大,由此推测 OOM 问题与 Pipe 功能紧密相关。
原因
经深入剖析,问题根源在于待同步的 InsertNode 请求实例在内存中大量堆积,却未能成功触发数据同步机制降级为 TsFile 同步,以释放占用的内存资源。由于内存无法得到有效释放,堆内内存持续被耗尽,最终引发 OOM 异常。
解决方案
为彻底解决该问题,建议将 IoTDB 升级至 1.3.3.6 及以上版本。新版本针对 Pipe 数据同步内存管理进行了定向优化,有效避免了因 InsertNode 请求实例堆积导致的 OOM 问题,确保系统运行的稳定性和可靠性。
Q4:想从 IoTDB 中读取大量数据经过一定程度的分析再写入 MySQL 或 SQLServer,在这种需求下,哪一种 ETL 方案最适合
问题
在需要从 IoTDB 读取大量数据,经过一定分析后写入 MySQL 或 SQL Server 的场景下,寻求最适合的 ETL(Extract,Transform,Load)方案。具体需求为定时查询一段时间内的数据,统计某些字段后写入 MySQL。同时,询问业界常用的 ETL 工具以及是否有无需编写代码的推荐方案。
解答
自主开发方案
若采用 IoTDB 的查询语句,可考虑自行开发程序,结合流处理(Pipe)功能将数据推送至目标数据库。此方案具有高度灵活性,可根据具体业务需求进行定制化开发,但需要一定的编程基础和技术能力。
无需编写代码的 ETL 工具方案
对于不想编写代码的用户,推荐使用 DataX 或 Kettle 这两款 ETL 工具。
Kettle:可直接通过 JDBC 连接 IoTDB 进行操作,实现数据的读取、转换和加载。Kettle 提供了丰富的图形化界面,用户可通过拖拽组件的方式完成 ETL 流程的搭建,无需编写复杂代码,易于上手和使用。
DataX:需借助特定插件实现与 IoTDB 的连接。可参考以下 GitHub 仓库中的插件:https://github.com/alibaba/DataX/pull/2167。DataX 同样具备图形化界面,支持多种数据源之间的数据同步,能够满足从 IoTDB 到 MySQL 或 SQL Server 的数据迁移需求。
无论选择哪种工具,都建议先熟悉其使用方法和配置流程,以确保能够高效、准确地完成数据的 ETL 操作。
Q5:Pipe 数据同步提示内存不足,如何调整
问题
在使用 IoTDB 1.3.3 版本进行 Pipe 数据同步时,数据发送方出现内存不足报错,具体信息为:“failed to allocate because there's too much memory for tablets, total memory size 4939212390 bytes, used memory for tablet size 1975791992 bytes”。即便在不同步历史数据的情况下,依然存在内存不足的问题。
询问是否存在专门控制 Pipe 占用内存的配置,或者是否可以通过调整其他参数来解决此问题。
解答
有两个方向进行调整:
1. Sink 插件参数调整
修改 Sink 插件的 batch.size-bytes 参数值。该参数控制每次批量发送数据的字节数大小。减小此参数值可降低每次发送数据时占用的内存,从而缓解内存压力。
2. 系统属性参数调整
在 iotdb-system.properties 配置文件中,进行以下两项参数设置:
pipe_all_sinks_rate_limit_bytes_per_second:该参数用于限制所有 Sink 的数据传输速率,单位为字节/秒。通过合理设置该参数值,可控制数据同步的速度,避免因数据传输过快导致内存消耗过大。可根据实际业务需求和系统资源情况,适当降低传输速率,以平衡内存使用和数据同步效率。
datanode_memory_proportion:此参数为内存控制的分配比例,用于调整 DataNode 分配给不同功能模块的内存比例。适当调整该参数值,可为 Pipe 数据同步功能分配更多的内存空间,但需注意不要过度分配,以免影响其他功能模块的正常运行。
在进行参数调整时,建议先在测试环境中进行验证,观察调整后的内存使用情况和数据同步效果。根据测试结果,逐步微调参数值,直至找到既能满足数据同步需求,又能有效控制内存使用的最佳配置。同时,建议密切关注系统运行状态和日志信息,以便及时发现并解决可能出现的其他问题。
规上企业应用实例
能源电力:中核武汉|国网信通产业集团|华润电力|大唐先一|上海电气国轩|清安储能|某储能厂商|太极股份
航天航空:中航机载共性|北邮一号卫星
钢铁、金属冶炼:宝武钢铁|中冶赛迪|中国恩菲
交通运输:中车四方|长安汽车|城建智控|德国铁路
智慧工厂与物联:PCB 龙头企业|博世力士乐|德国宝马|北斗智慧物联|京东|昆仑数据|怡养科技|绍兴安瑞思