作者介绍:
刘常良:Apache Doris Contributor,SelectDB 存储层研发工程师。
吴迪:Apache Doris Committer,SelectDB 生态研发工程师。
在 OLAP 的业务场景中,Schema Change 是一个相对常见的业务需求,当上游数据源维度发生变化时,通常需要将数仓中的表结构进行相应的变更。相对于业界其他 OLAP 数据库,Apache Doris 对于 Schema Change 的支持非常友好,可支持 Online Schema Change,进行加减列或修改列类型时无须停服,保证了系统的高可用和业务的平稳运转。但在部分场景下,Schema Change 也存在一定的瓶颈,例如:在面对大数据量宽表场景下, Schema Change 执行效率相对较低、耗费时间较长;另外基于 Flink 和 Doris 构建实时数仓时,因 Schema Change 是异步作业,一旦上游表发生维度变化,需要自己维护 Schema Change 的执行状态,并在完成后重启 Flink Job,无法做到自动化变更,冗长复杂的操作流程无疑增加了许多开发和运维的成本,且可能会带来消费数据的积压。
基于此,Apache Doris 将在 1.2.0 版本推出新功能 Light Schema Change ,我们将通过本文为大家揭秘 Light Schema Change 的设计与实现,并分享其如何提升表结构变更的执行效率、以及如何在 Flink + Doris 实时数仓场景中实现 DDL 操作的自动同步。
在正式介绍之前,需要认识一下 Apache Doris 1.2.0 版本之前支持的 3 种 Schema Change 方式,均是异步作业,分别为:
ALTER TABLE site_visit ADD COLUMN click bigint SUM default '0';
ALTER TABLE site_visit DROP COLUMN city;
ALTER TABLE site_visit MODIFY COLUMN username varchar(64);
而值得注意的是,1.2.0 版本新增的 Light Schema Change 新特性正是 替换了 加减列操作的 Hard Linked Schema Change 流程 。 在了解 Light Schema Change 的优势之前,我们需要先知道 Hard Linked Schema Change 的技术原理。
Hard Linked Schema Change 在作用于加减 Value 列时,当接收到加减 Value 列的 DDL,Doris FE(下文简称 FE)会发起一个异步的作业,并立刻返回。作业主要做以下事情:
在使用过程中,我们发现 Hard Linked Schema Change 存在几个明显的问题:
相较于 Hard Linked Schema Change 的作业流程,Apache Doris 1.2.0 新版本的 Light Schema Change 的实现原理就要简单的多,只需要在加减 Value 列的时候,对 FE 中表的元数据进行修改并持久化。在设计过程中,需要考虑到以下实现细节:
由于 Light Schema Change 只修改了 FE 的元数据,没有同步给 BE,而 BE 对读写操作依赖于自身的 Schema,这时候就会出现 Schema 不一致的问题。为了解决此问题,我们对 BE 读写流程进行了修改。主要包含以下方面:
由于 Rowset 的元数据一直存储在内存中,如果每个 RowsetMeta 都存储一份 Schema,会对内存造成较大的压力。为了解决这个问题,实现了一个全局的 Schema Cache 管理相同的 Schema,这样就算有成千上万个 Rowset,只要 Schema 相同,内存中只会存在一份 Schema。
Light Schema Change 也实现了对物化视图的支持。对读写流程修改之后,物化视图也可以正常读写。同时,如果要删除的列在物化视图中是 Value 列,则会与主表一起触发 Light Schema Change;如果主表的 Value 列是物化视图中的 Key 列,则需要发起异步任务,对物化视图进行 Sort/Direct Schema Change。
由于 Delete Predicate 绑定了 Rowset,且每个 Rowset 都绑定了Schema,当 Delete Predicate 所涉及的列被删除后,可以通过寻找到对应的 Rowset,Merge 该列的信息进当前的 Schema 中,这样对 Delete Predicate 之前的数据也可以正常过滤。解决了数据中有 Delete Predicate 需要重写数据的问题。
以上就是 Light Schema Change 功能实现过程中对 Doris 进行的修改,在使用的时候只需在建表的时候指定参数即可打开 Light Schema Change 功能,如下所示:
CREATE TABLE IF NOT EXISTS `customer` (
`c_custkey` int(11) NOT NULL COMMENT "",
`c_name` varchar(26) NOT NULL COMMENT "",
`c_address` varchar(41) NOT NULL COMMENT "",
`c_city` varchar(11) NOT NULL COMMENT "",
`c_nation` varchar(16) NOT NULL COMMENT "",
`c_region` varchar(13) NOT NULL COMMENT "",
`c_phone` varchar(16) NOT NULL COMMENT "",
`c_mktsegment` varchar(11) NOT NULL COMMENT ""
)
DUPLICATE KEY(`c_custkey`)
DISTRIBUTED BY HASH(`c_custkey`) BUCKETS 32
PROPERTIES (
"replication_num" = "1",
"light_schema_change" = "true"
);
为进一步体验 Light Schema Change 的执行效率,我们在 1 FE 1 BE 的集群上对加减列操作分别在有导入任务时和无导入任务时进行了对比。硬件配置为 16C 64G,数据均在 SSD 盘,使用了TPC-H SF100 的 lineitem 表,数据量约74G,具体测试对比如下:
加列:
减列:
由上面测试可以看出,Light Schema Change 加减列速度远快于 Hard Link Schema Change,并且随着 BE 节点和表数据量的增多,Hard Link Schema Change 的耗时是远高于 Light Schema Change 的,原因是 Light Schema Change 只需要和 FE Master 进行交互,并可以实现同步返回。
加列
Light Schema Change: 耗时 3 ms
从上面测试可以看出,同样的加列行为,如果有导入任务,Hard Link Schema Change 需要等待导入的完成,才可以做 Schema Change,而 Light Schema Change 无需等待毫秒内即可完成导入。
欢迎读者尝试上手做一下有导入任务时的减列对比测试,也可以做一下在 Schema Change 过程中进行导入的情况下,两种 Schema Change 的速度对比。
之前在基于 Apache Doris 和 Apache Flink 构建实时数仓时,当上游数据源发生表结构变更时,Doris 在同步 DDL 操作时主要有以下痛点:
而在 1.2.0 新版本实现 Light Schema Change 后,DDL 的同步就变得非常简易。利用 Flink CDC 的 DataStream API,可获取到上游业务数据库的 DDL 变更记录,在 Doris 对应数据表中开启 Light Schema Change,即可实现 DDL 自动同步。核心步骤如下:
Light Schema Change 可以保证 DDL 在毫秒级执行完成,避免了双写以及阻塞数据的问题;
同时 Flink Doris Connector 封装了序列化类 JsonDebeziumSchemaSerializer,在作业启动的时候,只需指定序列化方式即可,无需关心 Schema Change 的底层逻辑,以及无需重启Job。
通过 Light Schema Change ,使得 Apache Doris 在面对上游数据表维度变化时,可以更加快速稳定实现表结构同步,保证系统的高效且平稳运转,具体体现在:
Apache Doris 1.2.0 版本即将发布,如果想体验最新特性欢迎大家扫码加入下方社群中,如有任何问题/建议可通过下方论坛进行反馈,社区专家将帮助你更快定位和解决问题。
|