为您详细讲解Greenplum 5 智能化运维

1. 背景介绍

Greenplum是近年来非常受关注的开源分布式MPP数据库。它基于PostgreSQL内核,可以将几十、几百甚至上千个PG实例部署到分布式环境下,形成一个单独的数据库实例。在GP上,每个数据表被切分(Sharding)到多个小的PG数据库实例中(这些PG实例称之为Segment)。GP的结构将数据化整为零,每个Segment负责存储、计算一部分数据,称之为Shared Nothing架构。在执行查询时可以高度并行执进行扫描、聚集和连接,这个特点使得GP在解决大量数据的问题时特别有优势。同时GP有着跟PG一致的SQL语法支持力度,再加上丰富的GIS、图数据、文本分析、半结构化、非结构化数据、机器学习库的支持,因此GP非常适合大数据的分析和机器学习的场景。

在2017年的PostgreSQL用户大会上,来自Pivotal的技术专家分享了GP开源后第一个正式版本,Greenplum5的一些特点和新功能。这一年来Pivotal继续稳定增加对GP的研发投入,在即将到来的Greenplum6上我们将能够看到更多最新的进展。包括GP内核使用的PG版本已经从8.3升级到了9.4,用一年的时间跨越了PostgreSQL五年多的集成,对GP来说是一个非常大的进展;另外还有很多亮点功能正在持续研发和交付中,例如进一步支持混合负载、在线扩容、Master自动切换、更多高可用技术、全局死锁监测、流式数据加载、备份升级迁移工具的完善、K8S的云上部署支持等等。

 可以说2018年对于GP是里程碑式的一年。在这一年来为了推动GP进一步从成熟走向完善,Pivotal对自治数据库、智能化运维领域也做了积极探索。这部分工作主要是Greenplum Command Center团队主导进行的。 Greenplum Command Center,或者简称GPCC,是Greenplum原生的图形化运维管理工具。在最近3年来的开发中,基于全新的界面和用户体验,陆续推出了监控、历史数据、管理的功能,在众多商业用户上得到了广泛的应用和认可。与此同时,产品和研发团队也得到了大量用户的反馈,很多DBA都反映数据库学习曲线长,工作负担重、压力大,他们希望GP能具备更加自动化、智能化的运维手段。针对这些需求,为了能让GP门槛更低、更好用,帮助用户更轻松地学习和使用GP,我们对GPCC项目的视野进行了调整,准备让GP成为智能化运维领域的领先产品。

2. 智能化运维第一步

在长期与用户的交流和接触我形成了一个非常深刻的体会,就是数据库运维与企业传统的IT运维有一个最大的区别,同时也是难点,就是SQL查询的性能问题很难分析。我们说一个数据库最核心的功能就是执行SQL查询,但是查询的性能分析、调整又是如此难以学习和掌握,这给数据库技术的推广和应用带来了很大的障碍。如何能帮助用户科学有效地定位和分析查询的问题,是一个非常独特的挑战。GPCC团队将这个问题作为Greenplum智能运维的第一步,尝试提供更有效的手段帮助用户和DBA分析处置查询的问题。对于查询性能的分析,我们先回顾一下已知的手段。其实无论是GP还是PG的用户,选择并不多。EXPLAIN命令可以获得一个文本的查询计划,包括完成一个查询所执行的步骤(算子),算子之间的关系通过缩进表示;EXPLAIN ANALYZE可以在获得文本的同时还让查询真正执行一遍,能够获得一些额外的执行状态信息,但EXPLAIN ANALYZE的执行时间受到查询速度的影响,查询速度很慢时,用户就必须等待很久才能得到结果;除此之外我们还经常尝试更新统计信息、VACUUM消除数据臃肿、甚至调整参数等等手段试图改善数据库运转效能。这些方式在有些场景下有效,但并不保证一定能行,而且学习起来门槛很高,很难精通。在我身边有一些对内核非常熟悉的大牛,他们是PG和GP内核组件的作者和代码贡献者。对他们来说,来到客户现场解决问题时候,分析性能问题也是非常困难的。他们甚至会采用调试的方法,直接分析进程内存里的一些数据。但对GP这样的复杂分布式结构来说,一个查询涉及多个主机上成百上千个进程,定位一个问题耗时耗力,代价非常高,却未必一定能解决问题。 那么症结在哪?其实主要问题就是数据库对我们来说是一个黑盒,在这个黑盒里影响性能的技术细节很多、很琐碎,我们缺少通用的手段精确定位问题,就更没有通用的自动化手段解决它。可视化查询计划以一个OLAP场景下的查询为例,TPC-DS 23号查询在GP上生成的文本执行计划打印到A4纸上一共71页。面对这样的查询,该如何入手找到问题,对于常人来讲是几乎无法完成的。

今天GPCC已经找到了一个方法改变这个现状,在GP推出了“可视化查询计划”这一新功能。通过数据可视化技术,我们可以将71页纸所涵盖的所有信息进行合理的提取、合并、布局,浓缩成一页的树状图。透过可视化查询计划,用户可以查询计划的结构、各个处理算子的类型、相互关系等细节信息。底部叶子结点是最先执行的数据扫描,中间部分包括数据分布、连接、聚合操作也一目了然,大大降低了用户理解查询计划的难度。

可视化查询计划的最大特点在于它能够同步显示查询的执行进展,不像EXPLAIN ANALYZE那样是在内部先执行完了最后只给一些结果的信息。这个可视化的进度,赋予了我们全新的能力,可以直接洞悉到数据库内部正在做的事,把黑盒变成了透明的白盒,使用者不用再依赖主观猜测和经验,直接看到查询作业的进度,从而快速定位问题。 在这个功能上,GPCC团队利用了对GP和PG内核开发上的优势,直接从数据库内部各个组件和进程,包括优化器和执行器上采集捕获了大量信息,因此能用比传统的EXPLAIN、EXPLAIN ANALYZE更小的开销获取更丰富的实时信息。查询的特征信息在进入案例前,我先简单介绍一下收集和展示的信息,统称为“查询的特征信息”,主要可以概括为三类信息。

第一个是查询的生命周期相关的基本信息。包括查询的开始、结束时间、用户、数据库、结果、错误日志等基本状态信息。

第二个是优化器产生的查询计划树。查询一旦提交到数据库里,优化器就会生成一个静态的计划树,从这个计划树上我们能够分析出即将执行的步骤(算子)、以及步骤之间关系。这使得GPCC就能够渲染出一个树状结构,反映出真实的执行计划。同时还包括每个步骤的预估行数、代价等信息。

第三个是当执行器开始执行这个计划树的同时,可以从执行器内部捕获到各个算子处理的元组个数,这个是GPCC能够跟踪查询执行进度的关键。特别是在GP分布式环境中,一个执行计划是由所有Segment并行完成的,因此GPCC同时收集了所有Segment上的进度信息,进行汇总才得到全局的进度状态。这样我们就能在计划树上渲染出每个算子的开始、执行中、已完成这些状态,展开每个算子还能看到具体处理行数、完成百分比等信息。

应用实例一:定位执行计划的问题

可视化查询计划是如何帮助用户解决查询性能问题呢?我们来看一些来自于生产一线的实际案例。注:实际的场景肯能非常复杂,为了方便理解,在保证原理不变的同时,我已经对问题做了抽象和精简。 SELECT count(*) FROM t1 INNER JOIN t2 ON t1.id2 = t2.id2;

这里是一个非常简单的查询,t1和t2进行内连接,数据量不大(t1一万条、t2 1000万条),这对于GP环境来说是非常微小的数据量,而实际执行时间达到了近30秒。

我们可以通过GPCC来分析一下这个查询执行的过程,找出问题出在哪里。提交查询后,在GPCC显示出这个查询开始执行了。我们展开它的可视化执行计划,一开始没什么异常,是一个很基础的hash join。执行了一段时间,突然醒目地将一个算子标记了红色,警示出这里发现问题。那我们点开这个算子的详细信息,可以看到这个结点上优化器给出的预估是10行,而实际扫描的行数已经远远超过预估。尽管查询正在执行中,我们已经可以通过GPCC非常便利地找到了这个问题点。

经过简单的分析,我们看到这个查询的两个表t1和t2,t1作为join的左树,t2作为右树。因为优化器预估这个t2表只有10行,因此将它作为右子树,但实际上t2表的数据量大于t1,这样把它作为右树,进行了一次复制,导致性能就非常差。

解决这个问题的方法也非常简单,我们只要更新统计信息,再次执行查询时,发现优化器已经正确预估两个表的规模,从而采取最优的join路径,将t2的t1的顺序交换了。较小的表放在右子树上,避免了对大表进行广播复制,查询的执行时间也从30秒降低到2秒。

应用实例二:定位运行时倾斜

上一个案例很简单,专业的PG/GP管理员都清楚及时更新统计信息的重要性,那么我们再看一个在GP上常见,却藏的比较深的倾斜问题。

首先先来了解一下什么是倾斜。对于GP这样的MPP数据库来说,各个Segment可以并行执行一个查询,这本身是GP的一个优势,特别适合对大量数据进行分析场景。然而,想要发挥出最优的性能,就需要各个Segment节点之间平均地承担数据存储、计算的任务。

当数据分布在各个Segments之间分布不平衡时,就是常见的存储倾斜。当某个表的分布键选择不合理,导致某个 Segment上存储了更多的数据,当需要扫描这个表时,这个Segment处理的行数就大于其他结点,导致查询变慢,这就是常说的存储倾斜。

另外一种情况就是,即便存储分布是平衡的,但在查询中由于连接或聚集算子的条件等原因,数据需要发生重分布,重分布后的数据不够均匀,导致大量计算工作由一个或少数Segment承担,这种叫做运行时的倾斜。

不论那种倾斜,都是MPP数据库的主要的性能杀手。存储倾斜比较容易检查和预防,而运行时的倾斜则跟每个查询的写法、数据特征以及业务相关,非常隐蔽,下面就看一个这样的例子。

SELECT count(t1.id), count(big2.id) from t1 join (select t2.id, t2.id2, t3.id as id3 from t2, t3) as big2 on t1.id2 = big2.id2;

这次做了3个表的关联,这三个表的数据量都不大,500到5000行不等,而且都是均匀分布存储的。实际执行时发现执行时间超过了3分钟,依然是通过GPCC检查发生了什么问题。一开始执行计划看上去没什么异常,虽然三个表关联比上一个例子的计划树复杂,但是也很常见。当执行到10秒时,可视化执行计划提示出一组计划节点发生了计算倾斜。 展开最下面的重分布结点,可以看到倾斜度达到了100%,这就意味重分布动作将所有行分发到同一个Segment上了,其他Segment都闲着,只有一个非常忙,就好比千军万马过独木桥。 这个问题用传统的EXPLAIN看执行计划是完全没法发现的,因为文本执行计划上没有任何关于数据倾斜的线索。而EXPLAIN ANALYZE能够返回一些执行时行数的信息,但是对于大型的分析型查询,在用户现场调试这个问题时,正是由于倾斜的存在,导致这样的查询执行一遍需要3-4个小时。EXPLAIN ANALYZE一次要等这么久,在加上结果的文本非常长,也不一定能确保找到问题。而这里可视化执行进度就非常直观了,不需要等查询跑完,在查询执行中就可以直接看到倾斜,一分钟就定位到了运行时倾斜的问题,甚至包括倾斜的表和条件。经过详细分析可以得出原因是join的条件,虽然两个表的数据虽然不大,但是作为join条件的t1.id2 = t2.id2,id2的全都是同一个值,因此造成重分布后的倾斜。

解决这个问题的方法有很多选项,这个例子里面我们通过一个调试参数将原先会重分布的计划改成会广播其中一个表到所有Segment,这样就解决了倾斜的问题,优化后执行时间缩短为不到半分钟。

通过以上例子可以了解到,GPCC的可视化执行进度优势很明显,一个是直观,一个是实时,适合于很多PG和GP的优化场景。这个技术的核心是能够采集到优化器和执行器内部的信息,让黑盒变白盒,从而准确定位问题。

3. 智能化运维下一步

这个功能与智能化运维有什么关系呢?接下来我们就进一步解读其中奥秘。前面我们介绍了三大类查询特征信息,GPCC接下来做的事就是将这些信息保存起来,形成历史数据。

Gpcc_queries_history这个表包括了每个查询的基本信息的历史。每个查询执行完后都留下一条记录,包括基本信息以及使用的系统资源的汇总信息。 执行计划和进度的相关信息保存到Gpcc_plannode_history历史表中。既包括优化器给出的结点类型、关系、条件、预估,也包括执行器的实际元组个数、资源消耗。具备了这些信息,我们就可以随时调取任何历史查询的计划树,甚至重放查询的执行过程。这个能力成为了开启智能化运维大门的敲门砖。

这些历史数据有多少信息呢?我这里有一个大致的概念,我们使用TPC-DS跑15遍,一共能记录了1545个查询、1800万条计划节点的执行信息。另一个实验中,我们执行小型OLTP的查询,每秒钟执行7500个查询,持续30分钟下来记录了超过1300万个查询,我们能够完全记录下每个查询的基本信息,执行计划个数超过9亿条。

4. 历史数据的的应用

在GP上最常见的查询是一些周期性执行的查询,比如每天、每周的报表任务。随着数据量的不断累积增加,某些有可能速度越来越慢。我们称之为查询性能的退化。 因为有了查询的历史,我们可以轻易分析出哪些查询的性能存在退化,从而有针对性地进行优化和预防。计划结点的历史数据甚至可以告诉我们因为哪些表数据的增加,导致查询的性能发生退化,这对我们正确地配置Partition非常有助益。

对于执行计划的历史,通过一些简单的分析,也能够拿到很多有用的信息。例如一段时期内每个表/索引被扫描的次数,同理也包括插入、更新的次数和行数,这帮助我们识别出冷热数据,进而可以存储介质相关的自动优化,还可以指导索引、分布键的合理选择。

5. 混合负载与智能化运维

这些都是很简单实用的例子,那接下来介绍一个比较重量级的用法。近年来混合负载成为一个新兴的热门话题。通俗来说,一个数据平台兼具OLTP,AdHoc和OLAP的能力,即一个数据平台多种实用场景。这对于大型数字化企业来说,无疑是非常有吸引力的,因为混合负载能够帮助企业极大地简化基础设施投资,规避多种数据产品的复杂性、不一致性的问题,降低购置、运维成本。

Greenplum作为一个分析为主的数据库,其实在混合负载方面早已有了领先的视野,如何让GP更好地支持OLTP场景呢?最大挑战在于如何有效地实施资源隔离。

没有资源隔离的时候,OLAP和OLTP的查询都进入到GP,这些查询需要竞争的各种资源,包括分布式环境下每个主机的CPU/内存/连接数等等。这时重且慢的分析型查询往往会长时间持有大量硬件资源,让小而轻的OLTP查询拿不到资源,必须等待。这导致一个本来只需要几毫秒的查询响应时间大大增加。 早在一年前GP5提出了资源组的新特性,作为老版本GP资源队列的升级版,可以将硬件资源,包括CPU的核、内存、连接数等资源切分。合理地配置资源组,可以让大查询、小查询各行其道,避免资源争用、挤占。使得大查询可以稳定地执行,保持高吞吐,同时小查询可以顺利获得资源快速执行。 在GP6 最新的PG内核上,我们进一步优化了分布式锁和分布式事务管理。Greenplum本身的ACID强一致性事务支持,加上基础架构上资源组的实现,使得GP具备初步的混合负载能力。 随着底层技术上的障碍被扫清,混合负载最后的挑战就落在了运维身上。如何能正确高效地配置资源隔离?是用户能够从容驾驶混合负载的Greenplum最后一公里,也是智能运维要解决的问题。

这里一个挑战就是资源组为了提供灵活的资源隔离,引入了很多参数供选择,例如划分几个资源组,每个资源组分配多少硬件资源,哪些用户的查询分配到哪个组,一些细节的参数如何配置等等因素都需要运维作出决策。如何能够兼顾资源隔离和整体资源利用率;如何能够衡量配置的效果;如何能够根据时间、工作负载强度等动态指标弹性配置?

对上述一系列问题,GPCC提供的数据的支持是非常重要的的。由于GPCC能跟踪记录下任何查询,我们就能够分辨不同规模的查询在时间、数量、资源利用上的特征,在加之Greenplum本身的数据分析、机器学习能力,我们就可以分析出优化的资源隔离方案,甚至实施智能的弹性自动配置。

6. 更多实用场景

近期发布的GPCC 4.5 中,已经开始提供一个基于实时收集的查询特征信息实现的告警系统。这个告警系统相比以往依赖于查询数据库元信息表的一些监控方式,具有开销低、监控信息丰富灵活、可靠性高等特点。 其他方面包括基于实时和历史信息,GPCC将会开发数据库健康体检,分布键、索引优化建议,安全风险监控等多方面的应用。

7. 总结

我们在过去一年里铺垫了GP智能化运维的基础设施,包括查询特征的捕获、提取、存储。在此基础之上,一些典型的功能包括可视化查询进度、告警等功能应运而生。下一阶段Pivotal将深入挖掘历史数据,通过GPCC发布更多智能化运维的功能。

查询特征信息这一内核新特性的出现,为基于Greenplum的服务咨询、应用开发、人才培养都提供了全新的机会。相信通过整个社区和生态各个行业的努力,GP在功能和性能日益强大的同时也可以越来越透明易用,成为广大用户和DBA爱用的数据库产品。

关注微信公众号

VMware 中国研发中心

Greenplum官方技术交流群

扫码添加小助手即可入群,添加时请备注 “GP网站”