本文整顿自 OpenMLDB PMC 张浩在 OpenMLDB Meetup No.6 中的分享——《OpenMLDB 进阶应用和高级个性介绍》。
大家好,我是 OpenMLDB PMC 成员 张浩。明天我来给大家分享 OpenMLDB 的一些高级个性以及具体实际时的应用形式。
分享内容会笼罩三局部内容:首先是介绍线上高可用的机制是如何实现的。接下来是解说 OpenMLDB 的双机房容灾技术架构。最初会为大家展现在线引擎中,数据量很大的状况下,咱们是如何通过预聚合技术达到性能优化的。线上高可用机制介绍和实现线上引擎整体架构
首先让我带大家回顾一下 OpenMLDB 线上引擎的整体架构。OpenMLDB 线上引擎次要由几局部组成。第一个模块——Zookeeper,负责元信息的存储和治理。第二个模块——Tablet Cluster,由多个节点成的。其中的 Tablets 次要是用于存储数据以及执行SQL引擎。第三个模块——Nameserver,次要负责 Tablet 治理和故障迁徙。高可用-数据长久化
目前,OpenMLDB 提供两种存储模式,一种是基于内存的,一种是基于磁盘的。在基于内存的存储模式中,咱们通过 snapshot 和 binlog 两种形式保证数据的长久化。binlog 大家可能比拟相熟,一些传统的数据库会通过写 log 的形式使数据长久化。OpenMLDB 在这里提供了一些参数,不便大家依据应用场景进行调配,包含 binlog同步到磁盘的距离。咱们还应用了 binlog offset 的机制。对于某一个表中,binlog offset 是惟一的,所以 offset 会在某些节点挂掉之后用于选主。之后我会介绍这部分的具体内容。另外一个放弃长久化的形式是 OpenMLDB 会定期的生成一次 snapshot。Snapshot 当于是一个全局内存状态的备份。当 snapshot 生成,就能够删除旧的binlog,从而节俭磁盘的空间。snapshot 的生成参数也能够改变,有须要的用户能够在 tablet.flags 里配置。比方咱们能够设定 snapshot 的生成工夫,例如在每天凌晨一点生成snapshot,也能够设置 interval 等等。所以 snapshot+binlog 能够残缺复原出整个的零碎状态。高可用-分片与多正本
分片是 OpenMLDB 另一个比拟重要且通用的技术。为了晋升分布式性能,咱们会把一个表分成多个 partition,称作分片。分片的数目能够在创立表时进行指定。而 partition 和 partition 之间,大部分是独立的。通过分片,当须要对表进行并行查问时,咱们能够落到不同的分片,并行地执行查问工作。除了在磁盘上设置 snapshot 和 binlog 之外,咱们还有一些正本。当咱们在创立表时,能够申明此表是单正本,两正本或三正本,这个设计是为了达到高可用。大家能够看到右侧的示例图中的表设计了两正本、四分片。咱们会尽量把分片平均地散布在不同的 tablet 下面,同时不同的正本也会均匀分布在不同的 tablet 下面。不论是数据迁徙还是数据同步,分片始终是咱们的最小单位。不同的 tablet 之间做主从之间进行同步的时候,其实也是以 Partition 的力度去做同步的。
在这里,咱们用示例展现一下在 OpenMLDB 外面能够如何进行操作。大家可能对咱们创建表格的 SQL 曾经比拟相熟了。察看这个表格的红色局部能够看到,咱们在提供了一个 options 的选项,选项中能够申明咱们须要的分片个数格局。能够通过连贯 ns client,咱们能够查到以后表的情况,就像截图里能够看到咱们有创立 4 个 partition,每个 parition有两个正本。高可用-主从同步
正本之间有一个要害的问题是——如何做到主从同步。binlog 就能够用来实现主从同步。如图,数据写到 binlog 后会有一个后盾线程异步的把数据从 binlog 中读出来而后同步到从节点中。从节点收到同步申请后同样进行写内存和 binlog操作。Snapshot 能够看作是内存数据的一个镜像,不过出于性能思考,snapshot 并不是从内存 dump 进去,而是由 binlog 和上一个 snapshot 合并生成。在合并的过程中会删除掉过期的数据。OpenMLDB 会记录主从同步和合并到 snapshot 中的 offset, 如果一个 binlog 文件中的数据全副被同步到从节点并且也合并到了 snapshot 中,这个 binlog 文件就会被后盾线程删除。高可用-failover
因为咱们有多正本,那么如果一个 tablet 挂掉,OpenMLDB 会怎么做呢?当主节点的主分片不可用时,零碎会在从节点的从分片中抉择一个成为主节点。方才咱们提到OpenMLDB 选主的逻辑和其余零碎选主逻辑稍有不同。其余零碎的大都是通过 Vote 的形式选主,而咱们是抉择 binlog offset 里最大的节点作为主节点。这次要是为了防止数据失落的问题,比方某主节点挂掉的话,会造成局部数据的失落。针对 nameserver,也存在多个 nameserver 同时 standby 的状况,此时当某主 nameserver 挂掉,其实咱们也是通过抉择备用 nameserver 间接转为主 nameserver 的形式。nameserver 的 failover 机制比较简单,因为它是无状态的,所以零碎能够任意抉择一个备用 namesrever 晋升为主 namesrever 就能够了。在真正的实操中,OpenMLDB 有筹备好一些配置。咱们的高可用 failover 有两种形式应用。一个是 auto_failover,相当于咱们把 failover 交给 OpenMLDB 零碎来做。当 OpenMLDB 监测到某些节点挂掉时,它会主动地实现 failover 全流程,而后咱们能够通过 confset auto_failover true 来实现配置。另外一个策略是咱们能够把 auto_failover 设为 false。这时候当某一个节点挂掉时,零碎不会做任何操作,须要用户手动染指,通过一些运行命令把节点复原进去。操作手册:https://openmldb.ai/docs/zh/m...双机房容灾技术架构下面次要是介绍的是高可用的实现。接下来我将次要介绍 OpenMLDB 双机房容灾的技术架构。
假如我有两个集群,一个主集群,一个从集群。每个集群中,所有 nameserver,tablet,zookeeper等组件都是残缺的。散布在不同机房的集群次要有两个信息须要同步,一个是元信息的同步(比如表的创立分片、增删更改),另外一个数据的同步。另外一个值得关注的是,依据业务场景的需要咱们能够设置多个从集群。从集群只承受读申请,写进申请全都导入到主集群。双机房架构原理
元信息的同步次要通过 nameserver 进行。通过 nameserver,主集群向从集群同步表信息,而从集群更新的拓扑信息会定期同步至主集群。数据同步和备份之间的同步相似。咱们认为从集群分片是主集群分片的备份。所以数据同步大略是分为两个独立的局部,一个是集群外部的同步,另外是一个是集群之间的同步。遵循刚刚所讲的不同分片同步策略,leader 给 follower 同步。集群之间同步是由主集群的leader 把收集的数据更新给到从集群的leader,从集群的leader再去把这些数据同步到从集群的follower下面,使得咱们所有的备份数据都是 in sync 的。不过,尽管咱们的从集群中有一个分片 leader的概念,但它作为从集群的 leader,不参加选主。这次要是说当咱们主集群的leader挂掉的时候,从集群的leader不参加主集群的选主。这外面跟一个概念比拟类似。zookeeper 有一个 observer 的概念,它只把数据给进行备份,但并不参加选主。同样的,etcd 中咱们有个 raft learner 的概念,它也只是对于数据进行一些备份,但不参加就是选主过程。业界罕用架构比照
咱们在这里列举了两个业界罕用的两个架构 TiDB 和 MySQL,看看它们怎么做的。这两个架构比拟类似,TiDB 将数据从 TiKV 传到 TiFlash 也是通过相似形式实现的。TiFlash 有一个Learner的概念相似于OpenMLDB 从集群的leader。TiKV会把数据会同步到 learner 下面,而后再由 learner去做一些数据的同步。MySQL的主备复制,跟咱们做法也是相似的。它通过一些binlog,将更新的信息同步到 MySQL 下面。
OpenMLDB 是如何构建双机群的主从备份的呢?首先咱们在主集群外面,连贯主集群的nameserver,而后咱们能够通过addrepcluster的命令把另外一个集群增加成为从集群。这里咱们须要提供从集群的zookeeper地址和主从备份双机房的cluster名字。如需把双机房关联关系解除,也能够通过removecluster的形式实现。实现上述筹备后,集群外部咱们能够设成auto_failover,能够通过auto_failover机制保障集群的高可用。而集群之间的 auto_failover 目前还须要用户去判断主集群是否可用,当用户判断主集群不可用时,须要手动晋升从集群为主集群,当然晋升实现后 OpenMLDB 零碎会把读写流量切换到新的主集群上。当咱们挂掉老的主集群又在复原后重新加入,新的数据仍然会通过新集群去同步到原集群。但这整个过程目前还需人工操作。双机房限度条件
目前的技术计划还存有一些限度条件。第一,咱们双机房是一个集群力度的主从关系,不反对表级别的力度,就是说不反对某一个表的主从关系。另一个限度是 auto_failover 须要用户做检测加手动切换。最初还有一个比拟通用的问题。当咱们做主从切换时,如果一直有写流量进入,可能会造成数据失落。因为在切换之后,原主集群的数据可能会多于新的主集群,这时候咱们还是以新主集群的数据为准,所以局部数据可能会失落。预聚合技术原理和性能优化体现最初一个局部我会次要介绍当在线引擎表数据量很大时,如何通过预聚合技术进行优化。应用预聚合技术也比较简单的,只有在创立 deploy 的时候增加一个 options 的选项,去申明咱们某一个窗口是一个长窗口。例如图中指定 w1 为长窗口,1d 指的是一天的概念,代表预聚合的一个力度。预聚合原理介绍
假如最右边为原始数据。申明了某一窗口为长窗口后,咱们进行数据插入时,OpenMLDB 就会去做预聚合操作,把原始数据中一天的数据聚合成一条预聚合数据,生成一个预聚合表。然而咱们目前实现的是一层预聚合表,之后可能会反对多层。多层预聚合就相当于在第一层的根底上进一步做预聚合。如果咱们须要实时线上计算一年的窗口数据时没有预聚合,则要查问一整年的大量数据,可能造成较大的提早。当咱们有了预聚合之后,就能够将之前的预聚合后果和最新的数据相加,更低提早地生成最终须要的后果。所以防止了大量数据的计算,使性能晋升两个数量级。预聚合技术也能同时实用于内存和磁盘表。
预聚合是在一个数据插入的过程中提前做聚合操作,并把后果更新到预聚合表外面。应用预聚合前,当咱们做线上的特征提取时,原始数据齐全是从原始表中做聚合。应用预聚合后,咱们领有了两个输出渠道,一个是预聚合表,一个是原始表,OpenMLDB 会先把能用的预聚合数据读取进去,再把缺失的数据读出来,最初做一个Reduce操作,节俭了咱们数据读取及计算的工夫。
预聚合测试数据
这两张图是预聚合相干的测试数据,应用了预聚合技术的是橙色线,未应用预聚合的是蓝色线。能够比照看出预聚合技术应用后大略失去两个数量级的晋升,无论是提早还是吞吐。残缺试验测试报告见:https://openmldb.feishu.cn/wi... 预聚合应用限度条件
预聚合其实是比拟新的一个技术,在应用中会有肯定限度条件,比方:目前只反对一个物理表,不反对蕴含 Join,Union 的 Selectstmt。算子咱们当初只反对一些通用的常见函数,如sum, avg, count,min,max 等。还有一些限度,包含deploy的时候,表中不能有数据,*_where的算子,只能反对内存表以及简略的条件语句。长窗口应用阐明:https://openmldb.ai/docs/zh/v...
分享就到这里,谢谢大家。
相干链接
✦
OpenMLDB 官网
https://openmldb.ai/
OpenMLDB github 主页
https://github.com/4paradigm/...
OpenMLDB 微信交换群