从全球视角到K8s落地的Apache IoTDB实战

👨‍🎓博主简介

🏅CSDN博客专家

🏅云计算领域优质创作者

🏅华为云开发者社区专家博主

🏅阿里云开发者社区专家博主

💊交流社区: 运维交流社区 欢迎大家的加入!

🐋 希望大家多多支持,我们一起进步!😄

🎉如果文章对你有帮助的话,欢迎 点赞 👍🏻 评论 💬 收藏 ⭐️ 加关注+💗


文章目录

  • 一、为什么要重新谈"选型"
  • 二、"四维十问"选型框架
  • 三、全球主流产品横评(不点名竞品,仅聚焦指标)
  • [四、Apache IoTDB 核心优势拆解](#四、Apache IoTDB 核心优势拆解)
  • [五、K8s 部署实战](#五、K8s 部署实战)
    • [1. 环境准备](#1. 环境准备)
      • [1.1 准备 Kubernetes 集群](#1.1 准备 Kubernetes 集群)
    • [2. 创建命名空间](#2. 创建命名空间)
      • [2.1 创建命名空间](#2.1 创建命名空间)
      • [2.2 查看命名空间](#2.2 查看命名空间)
    • [3. 创建 PersistentVolume (PV)](#3. 创建 PersistentVolume (PV))
      • [3.1 创建 PV 配置文件](#3.1 创建 PV 配置文件)
      • [3.2 应用 PV 配置](#3.2 应用 PV 配置)
      • [3.3 查看 PV](#3.3 查看 PV)
      • [3.4 手动创建文件夹](#3.4 手动创建文件夹)
    • [4. 安装 Helm](#4. 安装 Helm)
    • [5. 配置IoTDB的Helm Chart](#5. 配置IoTDB的Helm Chart)
      • [5.1 克隆 IoTDB Kubernetes 部署代码](#5.1 克隆 IoTDB Kubernetes 部署代码)
      • [5.2 修改 YAML 文件](#5.2 修改 YAML 文件)
    • [6. 配置私库信息或预先使用ctr拉取镜像](#6. 配置私库信息或预先使用ctr拉取镜像)
      • [6.1 【方案一】从私有仓库拉取镜像](#6.1 【方案一】从私有仓库拉取镜像)
        • [6.1.1 创建secret 使k8s可访问iotdb-helm的私有仓库](#6.1.1 创建secret 使k8s可访问iotdb-helm的私有仓库)
        • [6.1.2 将secret作为一个patch加载到命名空间iotdb-ns](#6.1.2 将secret作为一个patch加载到命名空间iotdb-ns)
      • [6.2 【方案二】导入镜像](#6.2 【方案二】导入镜像)
        • [6.2.1 拉取并导出镜像:](#6.2.1 拉取并导出镜像:)
        • [6.2.2 查看并导出镜像:](#6.2.2 查看并导出镜像:)
        • [6.2.3 导入到k8s的namespace下:](#6.2.3 导入到k8s的namespace下:)
        • [6.2.4 查看镜像](#6.2.4 查看镜像)
    • [7. 安装 IoTDB](#7. 安装 IoTDB)
      • [7.1 安装 IoTDB](#7.1 安装 IoTDB)
      • [7.2 查看 Helm 安装列表](#7.2 查看 Helm 安装列表)
      • [7.3 查看 Pods](#7.3 查看 Pods)
      • [7.4 发现故障的排除方式](#7.4 发现故障的排除方式)
    • [8. 激活 IoTDB](#8. 激活 IoTDB)
      • [8.1 方案1:直接在 Pod 中激活(最快捷)](#8.1 方案1:直接在 Pod 中激活(最快捷))
      • [8.2 方案2:进入confignode的容器中激活](#8.2 方案2:进入confignode的容器中激活)
      • [8.3 方案3:手动激活](#8.3 方案3:手动激活)
    • [9. 验证 IoTDB](#9. 验证 IoTDB)
      • [9.1 查看命名空间内的 Pods 状态](#9.1 查看命名空间内的 Pods 状态)
      • [9.2 查看命名空间内的端口映射情况](#9.2 查看命名空间内的端口映射情况)
      • [9.3 在任意服务器启动 CLI 脚本验证 IoTDB 集群状态](#9.3 在任意服务器启动 CLI 脚本验证 IoTDB 集群状态)
    • [10. 扩容](#10. 扩容)
      • [10.1 新增pv](#10.1 新增pv)
      • [10.2 扩容confignode](#10.2 扩容confignode)
      • [10.3 扩容datanode](#10.3 扩容datanode)
      • [10.4 验证IoTDB状态](#10.4 验证IoTDB状态)
  • 六、常见坑与避坑指南
  • 七、小结与下一步行动

一、为什么要重新谈"选型"

过去五年,时序数据库(Time-Series DBMS)从边缘话题变成企业数字化建设的刚需。根据 benchANT 2025 年 8 月最新排行榜,在 10 亿数据点写入测试中,Apache IoTDB 以 1.38 GB/s 的峰值写入带宽和 18:1 的压缩率位居第一。

当数据量级从 GB 级跃升到 PB 级,传统"能跑就行"的 POC 式选型已无法应对生产环境的成本、合规与长期演进压力。因此,本文提出"四维十问"框架,并给出可落地的 K8s 部署方案,帮助企业在 2025 年及以后做出更科学的决策。

二、"四维十问"选型框架

  1. 性能维度

    • 写入:峰值能否超过千万点/秒?

    • 查询:P95 延迟能否低于 500 ms?

    • 压缩:磁盘节省能否超过 80 %?

  2. 场景维度

    • 工业物联网:协议繁多、层级深;

    • 车联网:高并发、乱序、断网续传;

    • 智慧能源:省地两级部署、合规审计。

  3. 运维维度

    • 是否具备云原生无状态扩缩?

    • 是否支持冷热分层、自动 TTL?

    • 故障恢复是否能做到 RPO=0?

  4. 生态维度

    • 与 Hadoop/Spark/Flink 的对接深度;

    • 与 Grafana、Superset 的即插即用;

    • 国产化信创适配:麒麟 OS、鲲鹏芯片。

三、全球主流产品横评(不点名竞品,仅聚焦指标)

在官方公开的 TSBS 基准测试中,IoTDB 的写入带宽达到 1.38 GB/s,压缩率 18:1;而榜单第二名写入 0.9 GB/s,压缩率 12:1。查询方面,在时间范围 + 聚合查询混合负载下,IoTDB P95 延迟 480 ms;榜单其他产品普遍在 1.2 s 以上。

功能层面,IoTDB 原生支持树形数据模型,可直接映射"集团-工厂-产线-设备-测点"五级结构,无需额外打标签,减少 30 % 建模工作量。

四、Apache IoTDB 核心优势拆解

  1. 架构:

    • ConfigNode 无状态,DataNode 存储计算一体,天然适配 K8s。

    • TsFile 列式存储 + IoTLSM 引擎,CPU Cache-Miss 率降低 40 %。

  2. 写入:

    • "InsertTablet" 接口批量列写,单机 16 核即可达 1800 万点/秒。

  3. 查询:

    • 内置时间索引、倒排索引双引擎,支持"降采样 + 滑动窗口"一条 SQL 完成。

  4. 压缩:

    • 自研 PLA、SNAPPY、Gorilla 混合算法,冷热分级后整体磁盘节省 82 %。

  5. 生态:

    • 官方提供 Spark-IoTDB-Connector、Flink-IoTDB-Connector,可直接作为流计算 Sink。

    • Timecho 企业版内置 DataStudio 可视化建模、双活集群、国密算法插件(满足等保 2.0)。

五、K8s 部署实战

1. 环境准备

1.1 准备 Kubernetes 集群

确保拥有一个可用的 Kubernetes 集群(建议最低版本:Kubernetes 1.24),作为部署 IoTDB 集群的基础。

Kubernetes 版本要求:建议版本为 Kubernetes 1.24及以上

IoTDB版本要求:不能低于v1.3.3.2

2. 创建命名空间

2.1 创建命名空间

注意:在执行命名空间创建操作之前,需验证所指定的命名空间名称在 Kubernetes 集群中尚未被使用。如果命名空间已存在,创建命令将无法执行,可能导致部署过程中的错误。

Bash 复制代码
kubectl create ns iotdb-ns

2.2 查看命名空间

Bash 复制代码
kubectl get ns

3. 创建 PersistentVolume (PV)

3.1 创建 PV 配置文件

PV用于持久化存储IoTDB的ConfigNode 和 DataNode的数据,有几个节点就要创建几个PV。

注:1个ConfigNode和1个DataNode 算2个节点,需要2个PV。

以 3ConfigNode、3DataNode 为例:

  1. 创建 pv.yaml 文件,并复制六份,分别重命名为 pv01.yamlpv06.yaml
Bash 复制代码
#可新建个文件夹放yaml文件
#创建 pv.yaml 文件语句
touch pv.yaml
  1. 修改每个文件中的 namepath 以确保一致性。

pv.yaml 示例:

YAML 复制代码
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: iotdb-pv-01
spec:
  capacity:
    storage: 10Gi # 存储容量
  accessModes: # 访问模式
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain # 回收策略
  # 存储类名称,如果使用本地静态存储storageClassName 不用配置,如果使用动态存储必需设置此项
  storageClassName: local-storage 
  # 根据你的存储类型添加相应的配置
  hostPath: # 如果是使用本地路径
    path: /data/k8s-data/iotdb-pv-01
    type: DirectoryOrCreate  # 这行不配置就要手动创建文件夹

3.2 应用 PV 配置

Bash 复制代码
kubectl apply -f pv01.yaml
kubectl apply -f pv-02.yaml
...

3.3 查看 PV

Bash 复制代码
kubectl get pv

3.4 手动创建文件夹

如果yaml里的hostPath-type未配置,需要手动创建对应的文件夹

在所有 Kubernetes 节点上创建对应的文件夹:

Bash 复制代码
mkdir -p /data/k8s-data/iotdb-pv-01
mkdir -p /data/k8s-data/iotdb-pv-02
...

4. 安装 Helm

安装Helm步骤请参考Helm官网

5. 配置IoTDB的Helm Chart

5.1 克隆 IoTDB Kubernetes 部署代码

请联系天谋工作人员获取IoTDB的Helm Chart

如果遇到代理问题,取消代理设置:

git clone报错如下,说明是配置了代理,需要把代理关掉 fatal: unable to access 'https://gitlab.timecho.com/r-d/db/iotdb-cluster-k8s.git/': gnutls_handshake() failed: The TLS connection was non-properly terminated.

Bash 复制代码
unset HTTPS_PROXY

5.2 修改 YAML 文件

确保使用的是支持的版本 >=1.3.3.2

values.yaml 示例:

YAML 复制代码
nameOverride: "iotdb"  
fullnameOverride: "iotdb"   #软件安装后的名称

image:
  repository: nexus.infra.timecho.com:8143/timecho/iotdb-enterprise
  pullPolicy: IfNotPresent
  tag: 1.3.3.2-standalone    #软件所用的仓库和版本

storage:
# 存储类名称,如果使用本地静态存储storageClassName 不用配置,如果使用动态存储必需设置此项
  className: local-storage

datanode:
  name: datanode
  nodeCount: 3        #datanode的节点数量
  enableRestService: true
  storageCapacity: 10Gi       #datanode的可用空间大小
  resources:
    requests:
      memory: 2Gi    #datanode的内存初始化大小
      cpu: 1000m     #datanode的CPU初始化大小
    limits:
      memory: 4Gi    #datanode的最大内存大小
      cpu: 1000m     #datanode的最大CPU大小

confignode:
  name: confignode
  nodeCount: 3      #confignode的节点数量
  storageCapacity: 10Gi      #confignode的可用空间大小
  resources:
    requests:
      memory: 512Mi    #confignode的内存初始化大小
      cpu: 1000m      #confignode的CPU初始化大小
    limits:
      memory: 1024Mi   #confignode的最大内存大小
      cpu: 2000m     #confignode的最大CPU大小
  configNodeConsensusProtocolClass: org.apache.iotdb.consensus.ratis.RatisConsensus
  schemaReplicationFactor: 3
  schemaRegionConsensusProtocolClass: org.apache.iotdb.consensus.ratis.RatisConsensus
  dataReplicationFactor: 2
  dataRegionConsensusProtocolClass: org.apache.iotdb.consensus.iot.IoTConsensus

6. 配置私库信息或预先使用ctr拉取镜像

在k8s上配置私有仓库的信息,为下一步helm install的前置步骤。

方案一即在helm insta时拉取可用的iotdb镜像,方案二则是提前将可用的iotdb镜像导入到containerd里。

6.1 【方案一】从私有仓库拉取镜像

6.1.1 创建secret 使k8s可访问iotdb-helm的私有仓库

下文中"xxxxxx"表示IoTDB私有仓库的账号、密码、邮箱。

Bash 复制代码
# 注意 单引号
kubectl create secret docker-registry timecho-nexus \
  --docker-server='nexus.infra.timecho.com:8143' \
  --docker-username='xxxxxx' \
  --docker-password='xxxxxx' \
  --docker-email='xxxxxx' \
  -n iotdb-ns
  
# 查看secret
kubectl get secret timecho-nexus -n iotdb-ns
# 查看并输出为yaml
kubectl get secret timecho-nexus --output=yaml -n iotdb-ns
# 查看并解密
kubectl get secret timecho-nexus --output="jsonpath={.data.\.dockerconfigjson}" -n iotdb-ns | base64 --decode
6.1.2 将secret作为一个patch加载到命名空间iotdb-ns
Bash 复制代码
# 添加一个patch,使该命名空间增加登陆nexus的登陆信息
kubectl patch serviceaccount default -n iotdb-ns -p '{"imagePullSecrets": [{"name": "timecho-nexus"}]}'

# 查看命名空间的该条信息
kubectl get serviceaccounts -n iotdb-ns -o yaml

6.2 【方案二】导入镜像

该步骤用于客户无法连接私库的场景,需要联系公司实施同事辅助准备。

6.2.1 拉取并导出镜像:
Bash 复制代码
ctr images pull --user xxxxxxxx nexus.infra.timecho.com:8143/timecho/iotdb-enterprise:1.3.3.2-standalone
6.2.2 查看并导出镜像:
Bash 复制代码
# 查看
ctr images ls 

# 导出
ctr images export iotdb-enterprise:1.3.3.2-standalone.tar nexus.infra.timecho.com:8143/timecho/iotdb-enterprise:1.3.3.2-standalone
6.2.3 导入到k8s的namespace下:

注意,k8s.io为示例环境中k8s的ctr的命名空间,导入到其他命名空间是不行的

Bash 复制代码
# 导入到k8s的namespace下
ctr -n k8s.io images import iotdb-enterprise:1.3.3.2-standalone.tar 
6.2.4 查看镜像
Bash 复制代码
ctr --namespace k8s.io images list | grep 1.3.3.2

7. 安装 IoTDB

7.1 安装 IoTDB

Bash 复制代码
# 进入文件夹
cd iotdb-cluster-k8s/helm

# 安装iotdb
helm install iotdb ./ -n iotdb-ns

7.2 查看 Helm 安装列表

Bash 复制代码
# helm list
helm list -n iotdb-ns

7.3 查看 Pods

Bash 复制代码
# 查看 iotdb的pods
kubectl get pods -n iotdb-ns -o wide

执行命令后,输出了带有confignode和datanode标识的各3个Pods,,总共6个Pods,即表明安装成功;需要注意的是,并非所有Pods都处于Running状态,未激活的datanode可能会持续重启,但在激活后将恢复正常。

7.4 发现故障的排除方式

Bash 复制代码
# 查看k8s的创建log
kubectl get events -n iotdb-ns 
watch kubectl get events -n iotdb-ns

# 获取详细信息
kubectl describe pod confignode-0 -n iotdb-ns
kubectl describe pod datanode-0 -n iotdb-ns

# 查看confignode日志
kubectl logs -n iotdb-ns confignode-0 -f

8. 激活 IoTDB

8.1 方案1:直接在 Pod 中激活(最快捷)

Bash 复制代码
kubectl exec -it -n iotdb-ns confignode-0 -- /iotdb/sbin/start-activate.sh
kubectl exec -it -n iotdb-ns confignode-1 -- /iotdb/sbin/start-activate.sh
kubectl exec -it -n iotdb-ns confignode-2 -- /iotdb/sbin/start-activate.sh
# 拿到机器码后进行激活

8.2 方案2:进入confignode的容器中激活

Bash 复制代码
kubectl exec -it -n iotdb-ns confignode-0 -- /bin/bash
cd /iotdb/sbin
/bin/bash start-activate.sh
# 拿到机器码后进行激活
# 退出容器

8.3 方案3:手动激活

  1. 查看 ConfigNode 详细信息,确定所在节点:
Bash 复制代码
kubectl describe pod confignode-0 -n iotdb-ns | grep -e "Node:" -e "Path:"

# 结果示例:
# Node:          a87/172.20.31.87
# Path:          /data/k8s-data/env/confignode/.env
  1. 查看 PVC 并找到 ConfigNode 对应的 Volume,确定所在路径:
Bash 复制代码
kubectl get pvc -n iotdb-ns | grep "confignode-0"

# 结果示例:
# map-confignode-confignode-0   Bound    iotdb-pv-04   10Gi       RWO            local-storage   <unset>                 8h

# 如果要查看多个confignode,使用如下:
for i in {0..2}; do echo confignode-$i;kubectl describe pod confignode-${i} -n iotdb-ns | grep -e "Node:" -e "Path:"; echo "----"; done
  1. 查看对应 Volume 的详细信息,确定物理目录的位置:
Bash 复制代码
kubectl describe pv iotdb-pv-04 | grep "Path:"

# 结果示例:
# Path:          /data/k8s-data/iotdb-pv-04
  1. 从对应节点的对应目录下找到 system-info 文件,使用该 system-info 作为机器码生成激活码,并在同级目录新建文件 license,将激活码写入到该文件。

9. 验证 IoTDB

9.1 查看命名空间内的 Pods 状态

查看iotdb-ns命名空间内的IP、状态等信息,确定全部运行正常

Bash 复制代码
kubectl get pods -n iotdb-ns -o wide

# 结果示例:
# NAME           READY   STATUS    RESTARTS         AGE   IP             NODE   NOMINATED NODE   READINESS GATES
# confignode-0   1/1     Running   0                75m   10.20.187.14   a87    <none>           <none>
# confignode-1   1/1     Running   0                75m   10.20.191.75   a88    <none>           <none>
# confignode-2   1/1     Running   0                75m   10.20.187.16   a87    <none>           <none>
# datanode-0     1/1     Running   10 (5m54s ago)   75m   10.20.191.74   a88    <none>           <none>
# datanode-1     1/1     Running   10 (5m42s ago)   75m   10.20.187.15   a87    <none>           <none>
# datanode-2     1/1     Running   10 (5m55s ago)   75m   10.20.191.76   a88    <none>           <none>

9.2 查看命名空间内的端口映射情况

Bash 复制代码
kubectl get svc -n iotdb-ns

# 结果示例:
# NAME             TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
# confignode-svc   NodePort       10.10.226.151   <none>        80:31026/TCP     7d8h
# datanode-svc     NodePort       10.10.194.225   <none>        6667:31563/TCP   7d8h
# jdbc-balancer    LoadBalancer   10.10.191.209   <pending>     6667:31895/TCP   7d8h

9.3 在任意服务器启动 CLI 脚本验证 IoTDB 集群状态

端口即jdbc-balancer的端口,服务器为k8s任意节点的IP

Bash 复制代码
start-cli.sh -h 172.20.31.86 -p 31895
start-cli.sh -h 172.20.31.87 -p 31895
start-cli.sh -h 172.20.31.88 -p 31895

10. 扩容

10.1 新增pv

新增pv,必须有可用的pv才可以扩容。

注意:DataNode重启后无法加入集群

原因 :配置了静态存储的 hostPath 模式,并通过脚本修改了 iotdb-system.properties 文件,将 dn_data_dirs 设为 /iotdb6/iotdb_data,/iotdb7/iotdb_data,但未将默认存储路径 /iotdb/data 进行外挂,导致重启时数据丢失。

解决方案 :是将 /iotdb/data 目录也进行外挂操作,且 ConfigNode 和 DataNode 均需如此设置,以确保数据完整性和集群稳定性。

10.2 扩容confignode

示例:3 confignode 扩容为 4 confignode

修改iotdb-cluster-k8s/helm的values.yaml文件,将confignode的3改成4

Shell 复制代码
helm upgrade iotdb . -n iotdb-ns

10.3 扩容datanode

示例:3 datanode 扩容为 4 datanode

修改iotdb-cluster-k8s/helm的values.yaml文件,将datanode的3改成4

Shell 复制代码
helm upgrade iotdb . -n iotdb-ns

10.4 验证IoTDB状态

Shell 复制代码
kubectl get pods -n iotdb-ns -o wide

# NAME           READY   STATUS    RESTARTS         AGE   IP             NODE   NOMINATED NODE   READINESS GATES
# confignode-0   1/1     Running   0                75m   10.20.187.14   a87    <none>           <none>
# confignode-1   1/1     Running   0                75m   10.20.191.75   a88    <none>           <none>
# confignode-2   1/1     Running   0                75m   10.20.187.16   a87    <none>           <none>
# datanode-0     1/1     Running   10 (5m54s ago)   75m   10.20.191.74   a88    <none>           <none>
# datanode-1     1/1     Running   10 (5m42s ago)   75m   10.20.187.15   a87    <none>           <none>
# datanode-2     1/1     Running   10 (5m55s ago)   75m   10.20.191.76   a88    <none>           <none>
# datanode-3     1/1     Running   10 (5m55s ago)   75m   10.20.191.76   a88    <none>           <none>

六、常见坑与避坑指南

• 高基数:单个设备测点 >1 万会导致内存上涨,建议按物理意义拆分到多个逻辑设备。

• 网络抖动:启用 IoTDB 的 MQTT Broker 缓存 + 本地 WAL,断网 30 min 数据不丢。

• 大查询:避免 SELECT * 不带 WHERE time,改用分页或降采样。

• 版本升级:使用 Helm 的滚动升级策略,先在灰度 Namespace 跑 24 h 验证。

七、小结与下一步行动

选择时序数据库,不再是单一技术指标的 PK,而是"业务场景 + 成本 + 合规 + 未来演进"的综合博弈。Apache IoTDB 凭借硬核性能、云原生友好架构以及完善的国产信创生态,已在全球竞争中占据领先身位。

  • 官方地址:

下载地址

Apache IoTDB 官方发行版:https://iotdb.apache.org/zh/Download/

企业级服务

Timecho(天谋科技)官网:https://timecho.com

Github仓库链接

Github仓库链接:https://github.com/apache/iotdb

官方部署

安装部署与使用文档:快速上手
把测试集群跑起来,跑完 TSBS,再跑真实业务数据,你会发现------选型,其实可以很简单。

相关推荐
songjxin1 天前
离线部署kubernetes v1.34.3
云原生·容器·kubernetes
wuxia21181 天前
minikube的安装
kubernetes·云计算
熊出没1 天前
Kubernetes 实操命令大全
云原生·容器·kubernetes
闲人编程1 天前
健康检查与就绪探针
kubernetes·web·状态机·健康检查·codecapsule·存活探针·启动探针
WZTTMoon1 天前
Apache Tomcat 体系结构深度解析
java·tomcat·apache
fiveym1 天前
Apache HTTP 服务搭建全攻略
网络协议·http·apache
故事写到这1 天前
第一章 Ubuntu24.04环境下的K8S部署【入门保姆级】
云原生·容器·kubernetes
走路带_风1 天前
Ubuntu server 22.04 安装kubernetes
云原生·容器·kubernetes
Xyz996_1 天前
K8S-Configmap资源
云原生·容器·kubernetes
Warren981 天前
datagrip新建oracle连接教程
数据库·windows·云原生·oracle·容器·kubernetes·django