现象
- 现象1:
- 现象2:时序数据库 IoTDB 系统遇到了一个持续增长的 schema_region 目录问题,导致频繁出现内存溢出(OutOfMemory)错误。在路径 data/datanode/consensus/schema_region 下,系统每分钟都会创建多个以“4747*”为模式的目录。目前有二十多个数据库,每次尝试重启数据库时,Java 虚拟机(JVM)就会报告内存不足的错误。
原因
- 自动扩展机制:在默认配置下,每个 DataBase 下的 Region 数量是在既定可控范围内的。默认配置下每个数据库将根据其数据量自动扩展 SchemaRegionGroup 和 DataRegionGroup。每个 DataNode 节点上最少会自动创建 1 个 SchemaRegionGroup ,而每个 DataNode 预期管理的 SchemaRegion 的最大数量为 1。每个 DataNode 节点上最少会创建 2 个 DataRegionGroup,预期管理的 DataRegions 的最大数量为 5。
- DataBase 数量与 Region 关系:DataBase 的数量直接关系到 Region 的数量。例如,在 1C3D 的集群中,在 1 个 DataBase 下创建 n100 个设备/测点,和在 n100 个 DataBase 下分别创建 1 个测点,所创建的 Region 数量会有显著差异。每个 Region 至少会保留 32 MB 的 WAL Buffer,因此 Region 数量的增加会导致内存开销增大。
- 合理控制 Region 数量:DataRegion 作为副本组的基本单位,绑定了固定数量的内存和 CPU 线程资源(例如 WAL 的堆外内存、Memtable 的 flush 线程等)。因此,IoTDB 集群需要控制 DataRegion 的数量适中,避免因为 DataRegion 太少导致写入并行度下降、资源利用不充分,或因 DataRegion 太多导致线程数量爆炸、写入性能下降。
方案
- 降低内存使用量:通过降低各个模块的内存使用量,启动服务删除部分 DataBase 来恢复正常运行。
具体配置参数如下:
wal_buffer_size_in_byte=8388608
schema_region_ratis_log_appender_buffer_size_max=4194304
配置时可根据系统中的 DataRegion 数、SchemaRegion 数进行计算:wal_buffer_size_in_byte * DataRegion 数 + schema_region_ratis_log_appender_buffer_size_max * SchemaRegion 数 < OFF_HEAP_MEMORY * 0.8。
其中,保留 20% 堆外内存用于各模块中的临时使用。
- 调整建模:修改建模方案,尽量保证所有的序列建立在一个 DataBase 下,避免 Region 数量过多。