Apache IoTDB 及云上部署实践
各位朋友下午好,我是来自天谋科技的开发工程师,我叫张金瑞。今天我给大家分享一下我们 Apache IoTDB 的一些基本内容,以及我们在云上做的一些部署的实践。今天的主要内容分为三个部分,我首先会给大家介绍一下我们 Apache IoTDB 的一些基本内容以及原理。同时我会讲一下我们全新发布的基于云原生架构的分布式版本 1.0。同时我也会给大家演示一下我们在 Kubernetes 上云部署方案的基本实践。好,首先是第一个内容,Apache IoTDB 的基本介绍,Apache IoTDB 它是一个面向物联网场景的时序数据库,主要用来解决比如说工业界或者是其他场景下的存储时序数据的场景。我们的项目发展经历了非常长的时期。我们首先是在 2011 年经历了我们的这个孕育期,在 2016 年我们开始进入自研期,就是我们提出 TsFile,我们做物联网数据模型。在 2018 年的时候,我们进入了 Apache 基金会作为孵化项目,然后在 2020 年的时候,我们从 Apache 基金会毕业,成为 Apache 的一个顶级项目。然后在 2021 年的时候,Apache IoTDB 获得了北京市科技进步一等奖,同时我们也从开源社区孵化出了我们的商业公司,叫做 Timecho 天谋科技。然后在 2022 年的时候,就是去年的 12 月份,我们发布了基于全新端边云协同架构的分布式版本 1.0。
Apache IoTDB 它有自己的一些核心的优势。首先就是这是我们自己独立自研,从底层文件格式一行一行代码写出来的一套产品;然后他现在是 Apache 基因会的一个顶级项目;同时也有这个产学研结合的一种优势,我们团队里面很多同学都是来自于清华大学软件学院的同学,我们有非常强、深厚的科研基底;同时我们的架构是一个端边云协同的架构,为物联网而生;当然我们肯定是要给大家提供极致的性能。首先我想给大家介绍 Apache IoTDB 这个物联网时序数据库它的数据模型。提到数据模型,如果了解时序数据库的同学可能会想到一些,比如说树状模型,比如说 tag 模型,比如说我们在当前国际上,时序数据库占主流的 InfluxDB,他们采用的就是 tag 模型,我们叫做标签模型。然后我们 IoTDB 采用的是我们自己提出的树形模型,在很多应用场景下也得到了客户非常好的反馈。树形模型在很多场景下能够更清晰的去表达时序数据库,他们这个元数据的基本的关系,在对存储和查询的时候能够带来更好的体验。同时我们 IoTDB 基于 LSM 这种基本特性的存储引擎,当然我们是在 LSM 的基础上做了一些针对时序数据的优化。我们可以支持顺乱序数据的写入,我们在底层存储的时候也是通过这种分离存储,然后再进行后台合并,这样的基本的策略来完成的。我们对乱序数据的写入能够有非常好的支持,这也给我们在数据存储的场景下,能够提供非常好的一些特性。比如说我们很多场景,虽然说用户说我的这个数据大部分都是顺序的,但是因为由于当前时序数据的规模都是很大的,这个设备也是很有可能是在端边的设备,它的这个时间跟 Server 端也有可能产生不同步的情况,所以这个乱序数据是一个非常会容易产生的一个场景。那我们在这个处理乱序数据的场景下,也做了非常大的工作,保证在这个场景下能有非常好的这个存储的效果。
同时我们其实在最早的时候做的是一个面向于时序数据的列式存储的文件格式,我们叫做 TsFile。提到这个列式存储的格式,大家可能也会想到很多,比如说 ORC、Parquet 等等之类的。我们做的这个 TsFile 也是类似于一种把数据按列来组织存储、编码、压缩,这样的一种专门针对物联网场景优化的文件格式。这种文件格式能够带来一种什么样的效果?能够非常大的去节省我们硬件的存储资源,因为它在数据存储的时候能够按列式数据的特性对他们进行进一步的编码。因为每一列的数据它们是有一些很强的共性的,那我们在以这种方式来存储的时候,就可以利用它的这种共性来存储。在查询的时候我们相应的也会,由于我们的数据量、在磁盘上的这个数据变少了,那我们读取的 IO 或者是磁盘的这个 IoTs 对它的压力都会减少,所以从而提升我们的这个产品性能。同时,列式存储也是这个能够对我们用户很多的查询场景是非常友好的,因为我们在实际的场景中我们会发现,使用时序数据、物联网场景的这些客户他们更多是一种分析型的需求。他们比如说统计过去一个月,某些序列它的一些报表数据等等,这种需求其实是更适合用这种方式来存储的。
那我们进入第二个部分,我主要给大家介绍一下我们去年发布的基于云原生的一种全新的分布式架构。这个分布式架构是我们当前 Apache IoTDB 1.0 版本的实现,我主要会从它的云原生的架构、秒级扩容,存算分离、MPP 框架,还有它的一些部署的灵活性上给大家做全面的介绍。首先在我们的集群当中,我们会有两种角色,第一种叫做 ConfigNode。ConfigNode 就是来存储我们整个集群的一些系统的数据,包括比如数据分区,维护集群里节点的状态等等,可以看作是整个集群的大脑。它本身也是一个多节点的部署,来完成这种高可用以及强一致这样的特性,因为我们集群的大脑,我们要保证它能够一直在线,所以我们采用这样的一种方式。它的内部协议我们采用当前非常流行的 Raft 协议来保证数据的强一致。集群的第二个角色就是 DataNode,其实从名字上大家应该也能看得出来,DataNode 就是用来进行数据存储的,同时它也是来进行数据计算的节点,一个 DataNode 里面会包含一个或者是多个数据的存储引擎,那这个存储引擎就是我在前面介绍的我们自研的基于 LSM 的这样的存储引擎。因为当前大家在使用分布式系统的时候,大家各自的配置都是不一样的,那有的客户是节点更多,但是单机的配置会低一点;那有的用户是节点总量不多,但是单机的性能很高,比如说它有很多的核、很大的内存或者很强的磁盘性能等等。所以我们的 DataNode 它会和一个机器做一个绑定,但是它的内部会根据机器的性能动态的分配一个或者多个这样的存储引擎,那这些事情都是由我们的 ConfigNode,也就是由集群的大脑决定的。那在这两种角色下,我们就是可以非常灵活的去支持云部署。因为我们的计算节点是独立的,存储节点也是相对独立的,然后所有的信息都是存储在 ConfigNode 里面,每个人都可以去拿到这个信息,都可以进行计算,所以这是非常适用于当前我们经常提到的这种云原生的架构。
那基于这个角色我们就可以在上面建立应用层,做数据的查询或者是存储,那具体的架构我可以给大家再详细的介绍一下。比如说我们的 ConfigNode,它作为一个集群管理的这样的一个角色,他首先是能够做节点的管理、数据的分区、负载均衡以及一些操作的调度,比如说我们的系统的扩容或者缩容等等。DataNode 它承担的角色功能就更多了,首先它是需要跟 ConfigNode 做通信,其次他本身要做查询的处理,比如他要做 SQL 解析、查询规划,然后查询的优化以及查询的执行。那当然查询肯定是要基于这个数据来的,那他自己本身也有基本的数据的存储引擎以及元数据的存储引擎。那我们下面分为两块儿,这里提到两个新的概念,一个叫做 SchemaRegion,一个叫做 DataRegion。然后 SchemaRegion 是用来存储这个元数据的一个基本存储的单元,那 DataRegion 就是我们刚才提到的,用来存储数据的基本存储单元。那 DataRegion 内部就是我们自己做了数据的存储引擎,它可以做文件的整理,做顺乱序 TsFile 的合并以及写前日志这些功能。那基于此我们中间还要做一个高可用的共识协议的框架,来满足我们的多副本、高可用这样的一个特性。那共识协议我们也做了可以插拔,用户可以选择的一种方式。比如用户的场景如果是非常强的数据一致性的要求,那么他可以选择用 Raft 协议,我们有 Raft 协议的实现。那如果用户的场景是对于数据的吞吐量要求很高,但是他又不要求实时的数据一致性,我们也提供了这种最终一致性的、我们自己做的针对于物联网场景的这个共识协议,我们叫做 IoTConsensus。然后基于这样的一个框架,我们就可以再做出来一些对于我们系统运维更加方便的一些功能。比如说系统的监控,能够让我们看到整个集群的状态。同时在整个系统的运行过程中,我们也做了一些跟当前大数据计算平台相互关联的一些连接的一些插件,比如说我们跟 Spark、Flink 或者 Kafka 做连接,我们会做一些他们的 Connector,或者是我们做一些可视化工具、控制台,或者是一些周边的备份工具或者数据迁移工具等等。好,介绍完了我们这个 IoTDB 的基本的集群的角色以及它的架构之后,我想给大家结合今天的主题,着重介绍一下我们的数据分区这样的一个概念。因为大家可能提到云原生这样的分布式的存储系统,大家肯定最关心的问题就是数据分区的问题了,那不管是我们以前用的 HBase、Cassandra 等等这些集群,还是现在大家主流其他的这种分布式的存储系统,那每个系统都会有自己数据分析的策略,当我们想把这样的系统部署到云环境的时候,那数据分区策略就决定了整个云环境下,这种分布式存储系统的它的运行压力以及部署的难度。那首先在我们的 IoTDB 里面,我们的数据分区采用的是这样的一种类似于分区表的方式。那刚才也提到了我们要管理的数据是分为两种,第一种是叫做元数据,第二种叫数据。那元数据是什么呢?就是说我们物联网场景下,大家肯定会说有很多的测点,或者说会有很多的时间序列,或者大家用其他名词说我有很多设备,那这些信息它本质上其实是元数据。那有的厂商他们的元数据量也是非常庞大的,他们数据的设备数、测点数可能是上千万,甚至有亿级别的数据管理。那这个其实也对分布式的物联网时序数据库提出了一些新的要求。那数据就是每个序列每天产生的数据本身了。那在我们的集群当中,我们的元数据是通过 SchemaRegion 来管理的,数据是通过 DataRegion 来管理的。当元数据在不断增多时,我们也会对元数据进行分区,元数据的分区是根据这个设备的 ID 做的这种哈希的分区。那数据本身它的分区有两个维度,第一个维度是这个设备的信息,就是这个数据是来自于哪个设备的、哪个测点的。那第二个维度是基于时间的,我们的时间分区可以是一天,可以是一周,可以是一个月甚至更长。那在这种两个维度的这种分区下,随着这个数据的增长,那新的分区可能就会被创建出来。然后数据分区和元数据分区,它本来也是一个逻辑的概念,那不同的分区它最终要落到我们真正的存储单元上,去进行数据存储。那么我们不同的分区就对应了图里面黑色的地方描述的 SchemaRegion 和 DataRegion,然后 SchemaRegion 和 DataRegion 是元数据和数据的基本的存算单元,那它们又会分布在我们实际的物理节点上,就叫 DataNode,所以这是我们这边的一个数据分区的一个基本的一个原理。好,讲完了我们这个 IoTDB 数据分区的这样的一个策略,有同学可能会问一个问题,说我们见过好多这个分布式的存储系统,大家用好多不同种类的这个数据分区的模型,其中有一种叫做这个哈希环,是大家都非常熟悉的,而且也得到大家广泛认可的一种方式。那我们 Apache IoTDB 为什么没有采用这种哈希环的这种一致性哈希的数据分区算法呢?首先这个哈希环的一致性哈希它有自己很多的优势,但同时它也有自己的一些弱项,就是说它对这个集群也带来一些相应的压力。那不同的存储系统他们关注的这个点是不一样的,每个系统都有自己强调的点,然后同时也有自己适应的场景。一致性哈希它带来的一个最大的问题就是当我们集群里面的节点增加或者是减少的时候,数据需要进行频繁的迁移。在我们的物联网场景下,这个数据量其实是非常庞大的,而且数据是按照这个时间维度不断不断往后增加的。用户关心的数据往往都是有这个冷热程度之分的,所以我们用这个时间分区来做这个管理。那用户关注的数据有可能是最近一个月的,有可能是最近半年或一年的,它其实很多程度上是不会去特别关心说我一个全量、过去所有数据的这样的一些聚合计算,他去做分析。所以基于这样的一些场景,我们没有选择哈希环来做我们的这个数据分区的策略。因为我们尤其是在云上部署之后,我们知道云上的环境其实计算资源的调度是更容易做到的,但是这个存储资源的这个重分配,这个事情带给整个云的环境的集群压力是非常大的。那我们如果采用一致性哈希的话,只要我们增加一个节点或者是一个 DataRegion,我们都要做这个数据的迁移,那这个给整个集群带来压力是很大的。
所以我们选择了这种查找表的方式,或者我们叫做分区表,这种方式会带来一些什么样的好处呢?我们可以根据这个图来看一下。比如说随着这个用户的这个序列数的增长,或者是用户数据的不断的增长,在这样的一个过程当中,我们只需要去增加相应的这个 SchemaRegion 或者是 DataRegion,用来存储元数据或者是数据。那 SchemaRegion 和 DataRegion 的增加势必会对这个硬件资源提出新的要求,或者直接的说就是它需要更多的 DataNode,那我们可以在整个集群中加入更多的 DataNode 这种计算存储角色。来对这个集群的整个负载进行一个均衡。那我们增加了这个 DataNode 之后,其实我们是不需要做数据迁移操作的,在不做这个数据迁移操作情况下,在我们的云环境下的这个扩容就会变得更加的简单。所以说在我们选用这种查找表的这种策略的情况下,我们可以其实是能够全面的接管,非常精确的去控制这个数据分片,以及它的这个数据的这个分区转移等等这样的操作的,能够在集群扩容的时候,尽可能的去避免这个数据迁移的出现,从而达到一种这个非常快的秒级扩容的这样一种特性,能够让我们的整个集群在云环境下也能够有非常好的这个表现和响应。说完这个数据分区,大家可能就会关注另外一个问题了,说这个数据已经存好了,也有分区了,那我们怎么去做这个数据的计算,做这个数据的查询呢?首先我们一会后面会给大家讲到我们的这个 MPP 的这个查询流程。那在讲到这个问题之前,大家可能也会关心另外一个当前非常火热的一个话题,就是存算分离。那存算分离基本上是对这个大型的数据库的这个存储系统,或者是各大厂商的这种 OLAP 的这个产品提到的一个概念。那大家经常会说存算分离,我就首先要做这个共享存储,那我的数据要存储在一个固定的地方,或者是一些固定的地方,然后我们的计算节点是独立出来的,所有的计算节点去共享这些数据的存储,然后来做这个数据的计算。但是我们其实也想问一个问题,就是说一定非得这么做吗?其实我们在 IoTDB 分布式的 1. 0 版本当中,我们其实是对这个事情做了一些新的探索,就是说在存算分离的这样的一个需求下,我们其实可以不用做到通过共享存储的方式来实现。比如说我们可以通过,用我们集群里面的角色来说,我们其实每一个 DataNode 这样的一个角色,它本身既是一个数据的存储单元,同时它也承担着数据计算的节点这样的角色。同时我们的 DataNode 它本身是可以存数据,也可以只做计算,就是说它上面其实是可以不用去做数据存储的这种负载均衡,它可以只去做计算。同时当我们整个集群的资源不充足的时候,我们去新增新的 DataNode 的时候,我们其实是有三种选项可以去对它进行调度的。第一种就是我们不做迁移数据,把它当做一个全新的 DataNode 来用。那当我们的集群里面的负载增加,我们的 ConfigNode,集群的大脑发现我们的负载需要做新的均衡,以及新的数据分区出现的时候,它会选择这个 DataNode,让它来承担这个新的角色。当然同时我们也可以说把集群现有的一些数据迁移过去,那这个是一个选项,并不是一个必须要做的事情。就是说我们集群现有的节点的压力已经很大了,比如说我们某一台 DataNode 它的上面的数据可能快要存满了,那我们可以选择性的做数据迁移。同时我们还有另外一种操作,就是说 DataRegion 它的一种数据分裂。这个分裂的意思其实就是说我们同一个 DataRegion 是一个我们最基本的存储单元,如果说它成为一个集群中的热点,它的写入或者是查询的压力非常大的情况下,我们是可以把它所承担的这个功能一分为二或者一分为三的,这在我们的数据分区下也是可以支持的。比如说同样一些数据分区本来存储在 DataRegion A 上,但 DataRegion A 成为了一个热点,那这个时候我们可以通过新增 DataNode 的方式来把 DataRegion A 的功能去向外分开一些,然后让其他的其他 DataRegion 来承担,这种我们也是可以做到的。那讲到这就是说我们的这个存算分离的实现,其实是可以不用去依赖于共享存储的。
后面我会详细的讲到这一点,我们的这个 DataNode,它在 Region 去新增的时候,它其实能够做到三种方式的选择,在我们增加节点的时候。第一种就是我们不迁移历史数据,仅做计算,那这个就做到了类似于共享存储同样的一种特性,就是说我可以只是作为一个计算节点加入整个集群。那同时我也可以去在不迁移历史数据的情况下,把现有 Region 的一些负载迁移到我身上来,这是第二种选项。那第三种就是。我既迁移历史数据,同时我也去承担一些新的数据存储和计算的这样的功能。那通过这种灵活的这种方式,我们其实可以做到我们的 DataNode 在整个集群当中,它的一种相对来说非常灵活的扩容方式。同时另外从一个反方向的角度来考虑,就是我们能做到这种扩容。在这三个选项当中我们去做缩容的时候,其实也可以非常方便的做到。那比如说一个 DataNode,它本身不是一个数据存储节点,它仅仅是一个计算节点,那它在缩容的时候它只需要向 ConfigNode,集群的大脑去报告一下自己下线了,或者说 ConfigNode 主动的去发现它下线了,那这个就可以了。那如果说它上面承担了一些数据存储的任务的话,那这就取决于我们集群的共识协议和副本数的要求。那当它承担的上面的数据的 DataRegion 不满足集群的,比如说副本数,比如说我们集群用三副本,它上面某一个 DataRegion 是一个三副本中的一个副本。那它下线之后我们有两种选择。第一种是可以做数据迁移,那如果这个节点已经不可用了,我们可以不用选择从它身上做数据迁移,我们可以去通过它对应的另外两个存货的副本做数据迁移在新的 DataNode 上,或者是现有 DataNode 上去分配一个新的副本这种方式来做。也就是说缩容,基于这样的一个特性,缩容其实也是能够非常方便的做到的。好,讲完数据的分区以及我们的存算分离的特性之后,那大家肯定就会非常关心我们整个集群在做数据计算的时候,它到底是怎么做的。在 Apache IoTDB 1.0 的版本当中,我们其实是设计并实现了一套全新的 MPP 的这样大规模并行处理的框架,来支持我们 IoTDB 的数据的查询。我们数据查询因为在分布式的存储系统下,大家现在经常会提到一些新的概念,比如说向量化的执行,或者是一些新的能够提高预算效率的方法。那这背后的这些新的技术,它其实本质要依赖于一些我们底层的支持。那么底层的支持首先我们要做到查询的一个算子化,能够让我们的数据查询能够做非常的灵活的分配,让我们整个集群的资源能够得到合理的调度。所以我们做了这样的一套 MPP 的框架。本身它是一个支持可拓展性,然后也是原生分布式,同时这个查询框架本身也是高可用的。同时我们也加入了一些对于整个查询监控的这样的一个可观测性的一个开发,就是说我们可以看到整个集群当前在运行这些查询任务的时候,它的状态。或者我们这个查询任务可以简单的称它为计算任务,我们可以根据集群的计算任务的负载,我们去分配查询的一些子任务等等这些操作,能够让我们框架变得更加的稳定。在我们的 MPP 框架当中,我们对于一个查询任务来讲,其实是有两种角色的,第一种叫做 Coordinator,就是一个协调节点。第二种就是 Worker,这个 Worker 我们就是运行一个子任务的节点。当我们一个查询任务到达的时候,它会由 Coordinator 去做查询任务的规划,包括 SQL 解析、逻辑计划的规划、物理计划的规划、一直到分布式查询计划的规划,然后再把它们切分成多个不同的查询子任务,交给 DataNode 上的 Worker 去执行。然后 Worker 在执行的时候,它本身也会有查询任务的调度,以及查询执行的一些控制等等一些具体的实现。在这种角色的划分之下,我们的整个框架运行的时候,一个查询任务它其实就可以变得更加的灵活。比如说它其实可以根据集群的资源以及 DataNode 的负载,然后做相应的切分。同时我们在这个数据库的查询当中,我们会有很多不同的查询计算,查询计算为了提升它的效率,我们肯定是要做一些相应的优化。比如说我们希望把这个数据,把这个计算分配到离数据更近的节点去执行,那么可能就会减少网络的 I/O 或者是磁盘的读取。或者是说我们根据任务执行的计算,我们把一些操作能够尽可能去下推,从而减少这个中间计算结果的这种传输等等。那基于这种框架我们这些事情都是可以做到的。我们通过一个具体的例子来讲,比如说我们要做一个聚合操作的查询。比如说我们 Client 发了一个 select count (s1) from 某一个表或者是某一个序列,我们做一个这种 count 的聚合查询。那这个查询到达之后,它其实会由我们的 Coordinator 做一个查询计划的规划,我们把它切分成不同的查询子任务。那在我们的系统当中,一个查询子任务用 Fragment 来去命名,Fragment 是一个片段的意思,就是查询的子任务。比如说我们会把它有可能切分成这样的四个查询子任务,那下面三个查询子任务,它们代表的是部分数据的聚合操作,它们会计算出聚合操作一个中间结果,它们会根据数据的分片被分发到不同的 DataNode 上去执行。然后它们的中间结果又会需要一个中间的任务去计算出它的最终的结果,然后这个最终的结果就是我们 Fragment-0 表示的,然后它再会返回给客户端。那这是一个简单的例子,我们不同的查询是要做不同的这样的查询规划的,我们可以根据不同的查询来做不同的优化,以及它们计划的实现。
总的来讲,整个 MPP 框架它的执行流程大体上是分为这样的一些步骤。首先从最开始的解析器,然后到分析器,到逻辑规划,然后优化器,再到分布式规划,然后再分发到各个节点去执行。那在这整个过程当中,其中分布式规划就非常大的决定了我们查询任务的执行效率。同时在我们云环境下,如何去更好的利用云环境的特点以及它的性能,也取决于我们分布式规划做出来的查询任务的这种分片方法。那就是说我们在分布式查询计划规划的过程当中,我们是可以结合集群的算力的情况,动态的对查询的子任务进行切分。比如说我们涉及数据查询的子任务,我们可以把它分配到对应的 DataNode 当中。如果说我们仅仅是涉及到中间结果计算,但是不涉及原始数据查询的子任务,我们是可以根据集群的负载去把它分配到某一个相对来说计算资源更强的 DataNode 上去执行的。同时,我们在做分布式规划的时候,我们也可以有另外的一种特性,就是说我们一个查询任务是可以被切分成 n 个或者是 n+1 个、n+2 个这样的子任务的。那我们如何决定它的 n 的数量呢?或者说我们决定它到底要切分成多少个呢?我们是可以结合云环境下这个集群的整个计算负载来去实现的,包括我们的 DataNode 数量。
比如说我通过一个例子,我们表示的是查询计划的一棵树。那我们在左图当中,我们把这一个聚合查询的查询计划,我们把它切分成了三个 Fragment,我们用 FI 来表示, FI-1、2、3。这三个 Fragment 就是三个查询子任务,它可以被分配到不同的 DataNode 上去执行。那如果说我们发现这个集群的算力很强,或者是说我们整个云环境下计算资源更强,DataNode 数量节点部署很多的情况下,我们其实是可以结合这个信息,把这个查询任务切分成更多的这样子的任务。比如说我们可以切分成 5 个,我们新增两个查询的任务片段,然后我们再把上面的,本来叫做子任务一,它的一些计算需求分发到其他节点上去执行,来减轻它的压力。这样通过一种并行化的实现,能够达到整体的计算能力的提升,也就是说能够更快的得出我们计算的结果,能更好的利用我们的这种云环境下的一个资源。所以说在云环境算力充足的情况下,我们的 DataNode 就可以按照前面我们提到的,在这种云环境下能够更好的横向的扩容。那我们有横向扩容的能力之后,我们的查询也可以相应的去根据集群的特性,做一些子任务的更细致的划分。那在这种更细致的划分的情况下,我们就能够达到更好的计算性能,能更好的去利用云环境下的特性。OK,讲完这些之后,我想给大家看一看我们这个 Apache IoTDB 在云环境下的一些部署的实践,我会通过一些截图来给大家看一下我们当前 IoTDB 在云环境下部署的样子。首先我们在云环境下部署我们的分布式版本的 IoTDB 的时候,我们是可以进行灵活的配置去调整的。比如说我们可以指定 ConfigNode 的数量、DataNode 的数量,指定数据、元数据它们所采用的协议,以及它们相应的副本数等等。
我们可以通过 Helm Chart 做一键的部署。比如说我们去 Helm install 我们的 IoTDB Cluster,它就会把它安装到我们的某一个这个 K8s 集群当中。然后安装好之后,比如说这个例子给出的是 3 个 ConfigNode 和 3 个 DataNode 这样的一个集群,我们看到每个节点都会通过一个独立的 Pod 来执行,我们有 3 个 ConfigNode 和 3 个 DataNode。然后我们也可以通过 cli 连接到这个集群内部,查看集群的运行状态。比如说我们可以看到我们的 ConfigNode 和 DataNode,它们的 InternalAddress 其实都是采用 K8s 内部的 FQDN 的方式来命名的,来方便它们之间进行一个通信。
同时我们在 K8s 这种环境下,我们是可以非常好以及非常方便的去支持这种节点扩容的。比如说我们可以首先支持自动的扩容,比如大家熟悉 Kubernetes 的同学可能知道,我们可以通过 HPA 去定义一些,比如我们定义 DataNode 它的扩容的策略;比如说 CPO 紧张或者内存紧张的时候,我们就会增加它的数量;或者是空闲的时候我们就去减少它的数量。我们也可以通过手动的扩容,比如说我们直接用 kubectl 这个命令去 scale 一下 DataNode,比如说 DBA 同学或者运维的同学发现整体的算力跟不上,或者是需要更大的存储空间的时候,它可以直接通过它去改变 DataNode 的副本数量,我们在做这个事情的时候是不需要额外操作的。比如说我举个例子,我们在刚才 3C3D,就是 3 个 DataNode,初始数量为 3 的情况下,我们去手动的去把它扩容一下。我们使用 kubectl scale 命令把它的副本数设置成 5,那经过非常短暂的时间之后,我们就可以看到红框中标出的 DataNode-3 和 4 新增了两个 DataNode 的节点就会被扩容出来,同时也会自动的加入到这个集群当中,我们可以通过 cli show 集群的状态。我们可以看到当前的时候,这个集群已经是有 5 个 DataNode 了,同时他们的状态也是 Running,然后通过这种方式在我们云环境下可以非常方便的实现部署和扩容,然后有了这些非常方便的部署扩容能力之后,我们的 IoTDB 它的本身的功能,存储和计算,也能够得到更有效的性能的发挥,来给大家提升非常好的存储和查询的体验。
OK,时间关系我就不对更多的内容做细致的介绍了,有兴趣的同学可以到我们的官网或者是 GitHub,我们的群里面去了解更多的信息,谢谢大家。
版权声明: 本文为 InfoQ 作者【Apache IoTDB】的原创文章。
原文链接:【http://xie.infoq.cn/article/a0d15f0b882d7d8ae73f73eb4】。文章转载请联系作者。
评论