paper-outline
paper-outline copied to clipboard
Online Expansion of Largescale Data Warehouses
PDF:p1249-cohen.pdf
讲述大规模数据仓库如何扩展。由于扩展过程中不可避免的 dumping 和 reloading 操作,因此是一个复杂且易错的过程。本文的核心是提出 robust 和事务一致的原语,从而实现高效的数据移动。
1. Introduction
数据量增长的维度:
- 额外数据源
- 更长的数据保留时间
数据仓库的一个很重要的维度是 计算能力,因此数仓解决方案把扩展视为一等公民。本文讨论的基于 GreenPlum 的 MPP 数仓使用 shared-nothing 架构,由没有中心化瓶颈或对特殊硬件依赖的普通机器组成。这种架构下,扩展最大的挑战在于:
- 基本没有下线时间
- 可管理性和性能透明性
2. Desideata
成功的扩展策略需要满足以下要求:
- 容量扩展性:扩容后的容量 == 系统本身被实现为这么多容量的容量 (有点绕..)
- 性能扩展性:扩容后的性能 == 系统本身被实现为这么多容量的性能
- 不中断服务,下线时间与系统扩容前后的大小无关
- 扩容期间容错
- 副本与灾备在扩容期间继续有效
- 过程透明化
- 过程可控制:暂停/继续的能力 / 优先对部分数据扩容
- 支持数仓的数据特性:事实表会被经常扩展,并且基本是分区存放
- 利用已有的基础设施,降低复杂性
3. Architecture Overview
GPDB 是一个 shared-nothing 的 MPP 架构,构建在普通硬件之上。这样带来不同 OS 上的移植性,也带来对于硬件配置的低敏感性。
3.1 Basic
系统包含两种类型的 host:
- Master host:接收连接、优化、分发并行查询计划、收集结果返回客户端
- Segment host
系统中的 segment 被分类两种类型:
- Primaries
- Mirrors:primaries 的逻辑副本
Mirror 只有在 primary down 了以后才会开始 upgrade 为 primary 并接收读请求,其余时间只是同步回放 primary 的写操作,以保持与 primary 的同步。系统默认被配置为 N 个 primary 和 N 个 mirror,但也可以自行配置。
3.2 Data Distribution
除了 catalog 只位于 master 上以外,所有数据都被分布在 segment 上。GPDB 提供了几种数据分布模式。最常用的分布模式就是指定 distribution column 进行 hash 分区。GPDB 通过对语法进行扩展实现:CREATE TABLE xxx (...) DISTRIBUTED BY (...);。
除了 hash 分区,GPDB 还提供所谓 RANDOMLY 分布。这种分布可以处理表的规模不大,导致 hash 分布存在倾斜的问题。RAMDOMLY 通过将数据以 round-robin 的模式进行分布可以避免这个问题。
另外,在查询执行期间,GPDB 还会使用几种临时的数据分布类型 (下面会说)。
3.3 Query Processing
根据访问的数据不同,查询可以被分为:
- Master-only queries:对 catalog 的查询 / 在 master 上直接处理简单表达式
- Symmetrically dispatched queries:所有 segment 执行相同的计划,计划中可能包含运算符使数据在 segment 之间移动
- Targeted-dispatch queries:查询计划只被分发到一个 segment 上
查询类型与表的分布相关。每一个表的分区方式被记录在 catalog 中,供优化器在运行时查询。Join 或 agg 等操作需要特别的数据重分布以保证正确的结果,有以下几种:
- Redistribute N:N - 输入是一个关系,根据指定的几列被重新分布到各 segment 上;通常用于等值连接或 grouping
- Gather N:1 - 所有数据被聚集到一个单独的数据库上;通常被用在查询计划的 root 节点,或者操作不能被并行执行时
- Broadcast 1:N - 将数据发送到所有其它 segment 上;通常用于除等值连接以外的 join
优化器会根据表的分布类型选择上述重分布运算符。重分布会带来额外的运行时间和网络带宽。在优化器对两个以上表的 join 顺序进行决策时,表的分布方式成为一个至关重要的因素。
3.4 Fault-tolerance & Replication
GPDB 容忍任何组件的故障。所有的硬件组件都是冗余的,包括存储、网络设施。所有 segment 上的数据,包括 master,都是备份的 (mirror)。数据备份使用的是标准的物理备份技术。
Master 周期性运行错误检测算法,检查 segment 的健康。如果发现故障,则系统会重新将流量路由到节点的 mirror 上,并发出警告便于管理员排查。
错误检测系统与查询处理正交 - 没有任何组件意识到它们自身有替身。
4. Expansion
扩展整体方法:在系统中初始化一个空的 segment,随着时间逐渐重分布少量数据,直到所有数据都被重新分布。重分布过程对正在进行的查询的影响有限,并且是在后台发生。完整的过程被 gpexpand 工具借助 GPDB API 实现。三个主要阶段:
- 初始化:新 segment 被物理地加入
- 重分布:用户可配置优先级、监控、随着暂停/继续,同时不影响常规 workloads
- 结束:用于调度和优先级分配的临时表被移除
4.1 Provisioning and Initialization
- Provisioning:对新机器进行与已有系统类似的压力测试
- Initialization:安装数据库软件、初始化新的 segment host
原有的数据分布策略被保存,然后所有 table 的分布策略都被设置为 random。这样带来的效果是,所有的表都需要在所有的 segment 之间进行重分布,就好像目前它们是未知的倾斜分布一样。此时,系统会暂停连接和写操作,以保证各个 segment 之间 catalog 的一致性。另外,还会创建一个临时表,用于记录当前扩容的状态。此时,除了数据还留在原来的 segment 上以外,系统的其它部分都已经完成扩容,常规的查询已经可以继续。
4.2 Establishing Distribution Policies
简单且 robust 的机制,一次重分布一张独立的表。GPDB 扩展了 ALTER TABLE 语法,允许管理员修改表的分布策略:
ALTER TABLE xxx
SET DISTRIBUTED BY (...);
这个机制集成在了已有的 DDL 框架中,与其它 DDL 提供了相同的事务一致性。工作步骤:
- 创建一个与原表的 schema 相同的新临时表
- 表中所有数据被读取并插入到新表
- 所有索引被重建
- 在 catalog 中临时表和原表被交换
整个步骤是原子的,就像在一个事务内执行一样。在此过程中,将会持有该表的表锁以防止对表的修改。
如果将表的分布策略设置为随机分布,那么只是简单擦除了分布策略,并不移动数据;除非显式声明。
4.3 Query Processing
为了实现接近 online 的扩容,立刻恢复常规查询处理是非常重要的。对分布策略的修改并不影响查询优化器产生合法的查询计划,虽然可能会有一些性能上的影响。对于优化器和执行器并不需要进行一些与扩容相关的修改。
4.4 Scheduling
在扩容期间,查询性能将会下降:
- 表不是以最优的方式分布
- 部分系统带宽被用于数据重分布
然而由于并不是所有数据都是 hot 的,因此可以优先重定向 hot 的数据。gpexpand 提供以下选项:
- 重分布优先级
- 并行度 (可以同时进行重分布的表数量)
- 暂停 / 继续重分布
- 显示进度
所有与扩容状态相关的信息被保存在临时表中,每个表占据一行。gpexpand 通过对这张表进行查询,决定下一个进行重分布的表,然后发起 ALTER TABLE。整个过程是事务一致的。如果数据库或者 gpexpand 失败,重分布可以被重启,整个数据库随时都是保持事务一致的。当临时表中所有行的状态列都被设置为 FINISHED 时,扩容结束。
在命令行工具中,管理员还可以设置 gpexpand 可以用于重分布数据的最大时间。超时后,正在进行的命令将会回滚,也不会有更多新的命令被发起。这使管理员可以设置严格的策略来使用业务低谷期来进行数据重分布,并在业务高峰期暂停。这使得长时间运行的扩容操作更加 robust。
5. Performance Evaluation
5.1 Scalability of Approach
关心扩容后性能的增长与集群大小的增长是否线性。
Scale-up of N:N Redistribution
将数据从 N 个 source segment 重分布到 N 个 target segment 上。使用了三种配置,两种数据来源,三种数据量:
- 2 segment,50GB TPC-H 数据
- 4 segment,100GB TPC-H 数据
- 8 segment,200GB TPC-H 数据
- 2 segment,120GB customer 数据
- 4 segment,240GB customer 数据
- 8 segment,480GB customer 数据
总之,segment 数量翻倍,那么数据量也翻倍。另外还比较了不同数据压缩等级的情况:压缩等级越高,CPU 占用越多,但重分布时占用带宽越少。

在不同配置下,查询执行时间基本是线性的。
Scale-up of N:2N Redistribution
类似。

5.2 Query Performance
关心扩容过程中对查询性能的影响。
扩容 4 segment 至 8 segment 的 TPC-H 查询,区分两种重分布模式:
- 完全重分布每个表的所有分区,一次一张表
- 同时重分布一张表的几个分区,一次一张表
重分布的顺序:从 事实表 开始,从大表开始。可以看到,一开始查询性能都有所下降。随着表数据逐渐被重分布至最优,查询时间也逐渐下降,直至收敛为原来查询时间的 50%。其中,对于不同表但相同时间范围内的分区同时进行重分布,使得查询时间有了更快的下降。

更加复杂的查询可能能够减弱扩容中数据随机分布带来的复杂性,因为查询中更容易产生使数据重分布的算子。
6. Discussion
- 扩容过程中的透明性和可配置性
- 扩容过程需要的额外空间不超过总数据量的 5%
ALTER TABLE过程中会持有表锁,但对大量被分区的表以及很少被更新的数据来说,锁冲突不会很多- 可以避免在峰值时间重新组织表