近期,2017中国应用性能管理大会(简称APMCon 2017)圆满落幕。阿里巴巴数据库事业部高级技术专家乔红麟发表了题为《数据库智能优化系统的探索与实践》的演讲,现场解读了过去几年阿里巴巴数据库团队在面对数据库规模急速增长以及业务变化越来越快的情况下在智能数据库诊断优化方面的一些探索和实践经验。
乔红麟:谢谢主持人,大家下午好。今天给大家分享一下我们团队在数据库优化方面做的一些事情。阿里的数据库场景与其他公司可能会有一些不同,所以今天的分享更多是基于阿里的场景和规模所做的一些思考和实践。
先简单介绍一下我自己。我在2015年加入阿里,目前负责阿里数据库智能优化产品CloudDBA的开发。我今天的分享主要有这几方面:
首先讲一下在阿里对数据库优化服务的诉求。我相信大家在数据库性能优化方面都有很多的经验教训,不同公司对优化的具体做法也不太一样。在方式上大部分企业应该还是重人工模式,就是由数据库能力比较强的人,比如DBA,来解决数据库性能问题。但阿里今天的数据库规模非常大,不管我们有多少DBA,我们的人员增长速度都无法跟上业务发展的速度,单纯依赖DBA已经无法满足业务发展需求。
第二方面讲一下我们的CloudDBA是如何做的,里面涉及到哪些技术,希望把这些技术分享给大家。如果大家所在的公司也在做类似的事情,希望能够提供一些参考和帮助。
第三方面大概讲一下目前正在探索的一些事情。现在人工智能技术比较火,数据库相对来说是比较传统的领域。如果我们将机器学习、深度学习这样的技术引入到数据库领域,它到底能做些什么,具体到数据库优化领域又能做什么,这是我们正在探索的一些事情。
一、阿里数据库优化服务诉求
首先从整个阿里数据库的角度看一下对于数据库优化服务的业务诉求,这也是我们做这个产品最大的驱动力。
1、服务产品化。阿里业务发展速度远远超过了DBA团队发展的速度,单独依靠DBA重人工支持模式变得越来越困难,因此我们在几年前开始尝试通过产品来完成DBA人工做的一些工作。通过产品解决DBA人工服务的扩展性问题,是我们最直接的诉求,希望能把DBA人工服务产品化。
2、全局规模优化。站在全局角度来看,数据库规模迅速增大的同时也带来了巨大的成本压力。成本这块怎么理解呢?只要业务有需求,理论上可以通过增加更多的机器来满足业务需求。但是从另外一个角度来讲,这些机器是不是一定要加,是不是有一些机器可以通过优化节省下来给新的业务服务。当规模非常大的时候,所做的一小点规模化优化,所节省的成本可能都是很可观的。因此我们需要有全局规模优化的能力,仅仅一个数据库实例内部做的优化都是一些局部优化,以全局角度来看是不够的。
3、主动诊断。从运维的角度来看,阿里同其它公司一样,就是要尽量避免故障的发生。在阿里的业务场景下,大部分业务跟数据库有着非常紧密的关系。数据库一个微小的抖动,都可能对业务造成非常大的影响,所以如何让数据库更稳定是非常重要的业务诉求。比如一个最常见的情况,有很多线上SQL性能是有问题的,这些SQL会给业务稳定性带来一定的风险。那么我们能不能通过产品主动对线上有问题的SQL进行主动诊断,提前做优化,而不是SQL引起故障后才去优化。
4、智能异常发现。线上业务负载不断地变化,业务行为、用户行为也在不断地变化。传统基于阈值设置报警的方式无法可靠、及时地发现数据库故障或者异常。如何可靠地去发现数据库异常,甚至是提前预测到故障的发生并进行及时干预,是有很强的业务需求的,但同时也有非常大的技术挑战,尤其是在阿里这么大数据库规模场景下。
- 容量预估。还有一些业务诉求是容量预估的需求。比如什么时候需要扩容,如何更精准地对数据库容量做出预估,这些方面后面我会稍微展开一下。
另外一部分诉求是使用数据库这些人的诉求,也就是我们的开发人员。每个公司数据库服务方式有所不同。这里我列了一些开发人员经常会问到的一些问题,这些问题背后的诉求让我们思考我们的产品站在开发者的角度,要解决什么问题。在业务发生异常的时候,需要快速定位到整个链路到底哪块出了问题。之前DB对于开发者来说是一个黑盒,不管是信息透明方面,还是大家对数据库领域的知识方面,对于DB的了解程度可能都不够,不知道DB是什么状态,发生了什么问题。具体来讲用户诉求主要有:
1、信息透明,自助优化。我们期望用户能够自助发现和解决数据库的性能问题,并非发现问题先去找DBA,这样整个流程会比较长,时间成本也比较高。但做到自助化,首先用户能够全面了解数据库的运行情况。
2、持续优化。只要业务在线上运行就会不断的变化,业务负载不断变化、用户行为也会不断变化。所以数据库优化是个持续的过程,并不是今天发现一个问题解决了,以后就不出现问题了。尤其是互联网的应用,持续优化尤其重要。
3、量化跟踪,流程闭环。开发人员经常会问到一个问题,上次帮他做的优化,结果到底怎么样。我们知道并不是每个优化都是实际有效的,因为很多优化方案是基于当时的信息和场景做的一个判断,实际优化结果只有当应用之后才能真正去做评估、做衡量,所以我们要提供量化跟踪和评估的能力。另外,我们期望整个优化流程,从发现问题到最终解决问题在产品内能够闭环,开发人员能够自己完全自助化走完整个流程,而不需要DBA的参与。流程闭环也是产品必须具备的能力。
4、输出产品,而不是人。不断有新的业务上线,而我们的DBA就这么多人,并且每个人有不同的侧重。对于一些快速发展的业务,在早期我们可能没有DBA去做特别支持的,但这些业务的数据库反而是容易出问题的。开发人员如果能够通过产品解决问题,而不是凡事都去找DBA,解决问题的效率会更高。将我们DBA的能力通过产品进行输出,更好去支持我们的业务。
所以今天我们做CloudDBA产品,是希望我们能够通过产品的方式把DBA专家服务提供给业务开发同学,实现DBA人力的扩展。同时我们需要具备全局规模优化能力,这是在阿里对数据库优化服务的业务诉求和用户诉求,也是我们做CloudDBA这个产品的动机。
二、CloudDBA关键技术
首先简单介绍下CloudDBA在阿里的发展历程。早期我们团队有很多非常牛的DBA,经常是一个人当千军万马的感觉,那个阶段优化更多依赖于DBA人工完成。之后我们开发了一些工具,让工具来完成简单的优化操作。几年前我们的理念转变为所有数据库服务都应该由产品来做,所以我们在数据库运维,管理,优化等方面都有相应的产品,开始进入自动化阶段。
未来数据库优化服务会从自动化发展到智能化,这是我的判断。今天仍然有很多问题是解决不了的,比如精确的容量预估,智能的异常发现,故障提前预警等。现在我们有非常多的数据,也有数据加工分析的技术,所以我们开始进行一些探索,通过数据分析和机器学习等技术手段来解决之前解决不了的问题。比如最简单的容量预估,每年都会做预算,做容量预估。至少我现在还没有看到特别多的公司去用很科学的方式,完全基于业务目标以及历史数据的分析来做容量预估。很多时候容量预估是靠拍脑袋决定的,但是今天有了大量的数据和加工数据的技术手段,我们是不是可以做更精准的容量预估。举这个例子来说明一下,未来很多的优化应该向智能化方向去思考,去探索。
CloudDBA在阿里大概是这样的一个发展历程,我们今天还处于自动化阶段,但同时也有一些智能化的实践。未来我的判断是我们一定向智能化去走,后面会在这方面尝试更多的探索。
说了这么多,那么CloudDBA到底是什么?PPT上面有一句话,“CloudDBA是一个数据库智能优化产品,面向开发人员提供自助化诊断优化服务,致力于成为用户身边的数据库专家。” CloudDBA不是给DBA开发的工具,CloudDBA从一开始我们的用户定义就很明确。我们是面向使用数据库的开发人员提供这种自助化的诊断优化服务,我们的用户不是DBA,而是真正使用数据库的开发同学。面向DBA和面向开发同学对产品来讲是完全不同的概念。比如开发同学没有太多数据库背景知识,我们即使做简单的信息透明,也需要做一些翻译,能够让开发同学理解。用户定义不同,数据的加工、分析以及最终的呈现,都是完全不一样的。
接下来讲一下CloudDBA到底能做什么。这是我们简化版的整体架构,涉及的面比较广。从下到上分为四层:
1、最下面是我们的采集层。对所有数据库进行实时的秒级数据采集,包括性能指标,日志数据、SQL流水,DB内部的一些信息等等
2、采集完之后数据到达计算层,计算层分两大块。一部分是实时计算,对于SQL流水,监控指标等,都会做实时计算和展示。另一部分是离线分析,比如性能基线,读写热点,统计报表等。
3、再往上就是数据库诊断服务层。如果大家做过系统的数据库优化,就清楚数据库优化会涉及到很多方面。最常见的就是SQL优化,SQL是不是很慢、有没有走到最优路径、SQL写法是否合理等等。SQL相关问题是我们开发经常会遇到的。还有其他一些问题,比如说空间,会话,锁,安全,配置等,CloudDBA能够对DB的每一个方面提供相应的专家诊断服务。
4、最上面是接入层,在阿里内部通过企业数据库服务平台iDB作为入口向开发同学提供数据库优化服务。
接下来跟大家分享一下我们做这个产品的一些产品设计原则。如果大家也在做类似的产品,希望能够给大家一些参考。
之前我们数据库优化主要是DBA来做,但DBA人工优化不具备扩展性,CloudDBA第一个设计原则就是要提供自助化服务,希望整个优化过程只有开发参与,并且整个优化流程能在CloudDBA里实现闭环。
由于业务负载会不断地变化,需要对所有线上数据库进行持续的主动诊断,及时发现和解决数据库性能问题。
另外这个产品需要有全局的视角,能够从全局角度发现规模优化点,具备规模优化能力,并且能够量化规模优化的收益。
还有最后两点非常重要,首先就是数据驱动。从我个人理解,今天要做这样一个优化产品,首先要有足够的数据,然后用数据分析和挖掘的技术手段,再结合数据库领域知识,给出更合理的诊断优化建议。智能化是我们对于数据库优化产品未来发展方向的判断,也是我们一直在坚持探索的。
时间关系今天无法全部展开,接下来重点展开几个方面。一个是CloudDBA的SQL优化怎么做的,还有一个是空间优化,另外就是CloudDBA全量SQL采集和分析。最后会分享一下我们在智能化方向的探索。
SQL诊断
先说一下SQL优化,不知道大家平时做SQL优化时是怎样的流程。大家回想一下,你是怎么发现哪些SQL需要优化的?要知道优化什么,为什么要优化它,然后再考虑怎么去优化。还有一个问题是优化完之后效果到底怎么样,是不是真的有效。整个优化过程不管是开发还是DBA做,都需要形成一个闭环。
CloudDBA产品实现了这么一个闭环。第一步决定哪些SQL需要优化,第二步是如何优化,第三步是优化后效果如何,要做量化跟踪,确认是不是有效。如果发现没有效果,再次重复这个优化流程,直到问题被解决。
这是CloudDBA里SQL优化的大概流程。我们实现了一个类似MySQL优化器的What-if optimizer。举个例子说明一下What-if optimizer是什么。比如一条SQL查询有10个可选的访问路径,MySQL优化器目标是要从这10个路径选择访问代价最低的一个路径。而What-ifoptimizer要做的事情是如何规划出第11条路,让这条路比现有的10条路都快。难点在于这条路是不存在的,这个路怎么修,修完之后是不是真的更快,这些是What-if optimizer要解决的问题。
比如一个常见的SQL优化手段是索引,那建什么样的索引会比当前所有执行路径都好?这是我们的SQL优化引擎要解决的问题,也是我们产品比较核心的部分。大家可以看一下这个流程,前面几步跟MySQL或者其他优化器类似,但后面的候选索引生成,代价评估,优化建议合并等都不一样。我们的输入是一条SQL或者一个SQL workload,输出是对应的优化建议,比如新建索引,SQL改写等。
SQL优化最关键的是要有全面准确的统计信息作为输入,另外就是它不能是规则式的,因为SQL的执行路径与数据分布有很大的关系。同样一条SQL,数据分布不一样,实际执行路径可能会完全不一样。SQL优化这块有几个关键点需要强调一下:
1、全局视角。如果业务SQL非常多,假设有100类SQL(模板化后),挑选哪些SQL来优化是非常关键的。是对这100类都做优化,还是选出其中一些重要的SQL?通常会选择性能有问题的SQL优化,但怎么选呢?CloudDBA有全量SQL性能统计数据,会分析出查询效率低且有优化空间的SQL Workload来进行优化。
2、代价评估(Cost-based Optimizer)。比如一条SQL可能会有多个索引建议,哪个建议是最优的?候选索引生成阶段确定某列是不是可以放到候选索引里,也需要结合统计信息来评估。这些过程都需要基于代价进行评估,而不是规则。
3、动态采样。优化器在做路径选择时很重要的一个输入是统计信息,对于我们的What-if optimizer也一样。我们通过动态采样来获取代价评估所需要的统计信息,包括Cardinality, Frequency还有Histogram等。数据倾斜比较严重的时候,Histogram对做出准确的代价评估非常关键。为了更准确的代价评估,所以我们实现了一个动态采样系统。
量化跟踪
CloudDBA的SQL诊断在阿里内部怎么使用呢?我们选择出要优化的SQL之后会有一个优化按纽来发起诊断流程。对单条SQL来讲,诊断结果包括SQL文本,现在的执行计划大概是什么样子,以及我们针对这条SQL给出的优化建议。比如这个SQL给出一个新建索引的建议。这个建议我们目前直接给到了开发,开发同学会可以应用这个建议,自助去创建这个索引。
那如何判断索引建议是否有效?前面提到优化流程闭环很重要的一环就是量化跟踪。这里有一个例子,是CloudDBA推荐的索引被开发采纳后24小时的性能量化跟踪情况。这两个框圈出来的时间点是索引生效的时间点,下面两个图表示优化建议被采纳前后的性能对比。会分析这个优化建议对直接优化SQL,以及该索引可能影响到的SQL,以及整个实例的性能影响,来量化判定和评估这次这个优化的建议是否有效。
能够发现问题,找出问题根本原因,给出问题解决方案,并且可以应用到线上,然后完成量化评估,整个优化闭环在产品里做到闭环。只有这样,开发自助优化才能真正实现,我们才能拿到最终的优化结果,中间少任何一环都很麻烦。比如说没有量化评估手段,用户采纳建议的动力就会小很多,因为即使应用了之后,也无法知道到底是不是有效。今天SQL诊断在CloudDBA可以做到整个流程闭环。
空间优化
接下来简单说一下空间优化。不知道大家平时有没有关注过自己DB空间使用情况。过去大多时候数据库空间不够首先考虑就是扩容,加机器。在阿里当然也有这样的扩容需求,但今天我们首先考虑的是优化现有存储空间。比如有的表数据有十列,但索引就建了二三十个,这个是不合理的。有的开发同学根据自己的SQL上去就建一个索引,他并没有看有没有建相关的索引,他可能只会建一个对他有用的索引。有些索引自从建了之后从来没被访问过,也有的索引是和其他索引只是索引名字不同但完全重复的,这些都造成了空间的消耗。因此CloudDBA在空间优化方面做了非常全面、深入的分析,也花了很大力气去做,因为对阿里今天的数据库规模来讲空间成本非常高。
1. 存储优化。通过数据存储方式的优化来节省存储空间。比如分析出来有些数据表字段占用空间较大且可以做压缩时,我们会建议用户做压缩。对于数据量特别大,但访问量又不是特别高的实例,我们会建议数据库做存储引擎的迁移,从InnoDB切换到RocksDB, 以获取更高的压缩比来节省空间。
2.空间回收。通过回收无用数据对象占用空间来优化存储空间,包括对表碎片进行分析和回收,重复索引/无用索引删除,无流量表删除等。业务不断变化,业务相关SQL也会变化,有些表或者索引在业务变化后可能就再没有人访问了,但还占了非常昂贵的在线存储空间,这些空间都是可以回收的。
3.数据迁移。把数据库里存放时间过久且不被访问的数据迁移到更低成本的离线存储上。CloudDBA会分析一张表的数据存储时间分布情况,比如有百分之多少的数据是3个月以内,多少数据是3个月到6个月,多少数据是6个月到1年等等。开发同学根据自己的业务需求结合数据生命周期来判断哪些数据可以做迁移或者清理。
CloudDBA会对线上所有数据库空间进行主动诊断,并且提供一键优化功能,开发同学可以自助化完成数据库的空间优化。
数据驱动
前面提到CloudDBA产品的设计原则,有一个很重要的核心理念就是数据驱动。数据驱动的前提先得有数据。阿里的数据库规模下数据采集处理还是很有挑战的,因为规模太大了。今天我们所有数据都是秒级采集,分析和展现。过去几年我们花了很多精力建设了一个可靠的数据通道,对采集上来的数据进行实时分析和离线分析。因为我们坚信未来CloudDBA产品一定向数据化、智能化的方向走,虽然数据通道和计算花了很多的精力,但是产生的数据价值很高。
数据驱动这块今天重点说一下全量SQL分析。如果要对数据库性能进行诊断,单纯看慢SQL是不够的。有些业务对latency很敏感,尽管SQL没有达到慢SQL标准,比如MySQL里默认的1秒,但业务已经感觉到明显的异常,因此需要对数据库实例上的全部SQL进行分析,了解当前实例正在执行哪些SQL,性能如何。CloudDBA对全网数据库实例上全部SQL进行实时采集、分析和展现,并且基于这些数据来驱动整个诊断优化流程。
先看一下全量SQL分析的数据通道。我们的AliSQL内核实现了非常轻量级SQL流水采集,包括SQL来源,SQL文本,执行时间,锁等待时间,扫描行数/返回行数、逻辑/物理读等信息。这些信息会实时地上报到Kafka, 然后利用JStorm对全量SQL进行各种维度的实时计算和分析。另外,对实时计算完的数据我们还会进行很多离线分析。目前全量SQL流水采集在阿里基本上全网覆盖,实时计算数据量达到千万级SQL/秒,离线计算数据量达到百TB/天。
这里列出了一些我们基于全量SQL分析进一步做的一些事情。首先用户通过CloudDBA可以实时查看当前实例正在执行的全部SQL信息以及性能趋势,这些信息能够更全面了解业务SQL的健康情况,比如对执行耗时占比较高但执行效率较低,执行频繁但索引缺失,执行性能有明显波动以及新增SQL等进行了识别。对于有分库分表的业务,我们能够识别是否有读写热点。对线上的优化操作可以更好地进行性能优化度量。还有从安全的角度,可以进行全面的SQL审计,还有我们也进行一些实际业务模型的分析。
前面讲业务诉求提到了需要有全局规模优化的能力,全局优化方面我们也构造了一个闭环。基于海量数据分析,从“发现规模优化点”,“估算预期收益”,到提供全局“优化决策输入”,开始“规模优化”,然后进行“实际收益量化跟踪”,以及最后的“规模优化效果评定”,整个流程在CloudDBA内部形成闭环。比如我们的全网空间优化,基于上就是通过这个闭环流程完成,同时CloudDBA会给出空间规模优化的实际收益。
全局优化方面,我们期望能够真正做到数据驱动,包括建立全网性能成本模型,建立性能成本基线等,能够基于数据分析发现收益较大的规模优化点。这方面我们还在持续地做更多的事情。
三、数据库智能优化探索
最后分享一些我们在智能优化方向的一些探索。利用数据分析和机器学习的一些技术,我们尝试去解决数据库领域之前较难解决的一些问题。这块有很大的想像空间,目前我们主要是在以下几个方面进行探索:
1、异常检测/关联分析。上午我听了一个分享讲在其他领域的异常发现/关联分析,异常检测不仅是数据库领域,在其他运维领域也有需求,是一个共性的问题。运维同学做监控,异常现在怎么发现?通常的做法是依赖报警,但报警的阈值怎么定?定高了到时候故障发生了报警还没出来,定低了收到一堆报警,都是误报。能不能做到智能的异常发现?比如说某个数据库实例跟之前的历史行为有比较大的不同,但并没有触发报警,我如何能第一时间知道?因为发现的越晚,线上的损失就会越大,在阿里的场景这个是有直接的业务诉求。及时发现异常,快速定位原因,减少业务影响。
昨天清华的裴老师也讲了,异常发现对于分钟级的数据, 目前一些现有算法是适用的,稍微做一些加工就会有比较明显的效果。但是我们的数据都是秒级的,对我们来说分钟级太长了。一个问题如果在分钟级别发现,损失可能已经非常大了。基于秒级数据的异常发现,今天业界的大部分算法效果都非常差,因为秒级数据抖动非常频繁,怎么在这种抖动中区分出来是真正的异常还是正常的抖动,这个挑战比较大。这里我也列举了一些其他方面的挑战,目前对于这些问题我们有一些初步的突破,有时间再分享这块的细节。
2、主动预警。异常发现都是事后的,因为异常已经发生了,损失也已经造成了,快速的异常发现是尽量减少损失。但我们希望做到更进一步,从被动诊断发展为主动诊断。在数据库故障真正发生之前,根据历史行为特征来对即将发生的异常进行提前预警。因为很多数据库故障发生前已经有一些特征是异常的了。这个之前基于传统阈值报警的方式是没有办法发现的。如果可以提前做预警,就有机会能更早的介入,避免故障的发生。
3、容量预估。我们每年都有双11,双11之前都要对数据库系统做容量预估。如果拍脑袋加1万台机器,但可能根本用不了这么多,那就造成大量的浪费。怎么能够更靠谱的做出容量预估,给出更合理的预算是很重要的。另外一方面,数据库实例什么时候要进行扩容,之前比较难预测的事情。我们最近在这方面做了一些尝试,举一个数据库空间增长预测的例子。
我们基于空间增长历史数据分析来对线上实例空间增长趋势进行预测,预测的结果作为实例自动扩容的输入。数据库实例什么时候需要扩容,CloudDBA会把这个信息透明出去,CloudDBA也可以基于这个预测对实例进行自动扩容。根据我们目前的预测结果,对线上>90%的实例空间增长预测误差都可以做到<5%, 我们还在不断地优化算法把这个数字做到更好。
4、自诊断,自优化。这是未来CloudDBA智能化阶段要具备的能力。整个系统可以基于大量的基础数据,通过标注把人的经验注入然后利用一些模型或者算法进行训练,分析出目前的性能问题,自动从优化操作集选择最合适的优化方案,在全局代价评估后自动应用到线上。整个过程是自动的,而且可以根据线上优化结果反馈反复进行优化。这块的探索我们还刚刚开始。
最后简单总结一下今天分享的内容。首先分享了在阿里我们为什么要做CloudDBA,背后的业务诉求和用户诉求是什么。其次分享了CloudDBA的一些关键技术,时间原因对SQL优化、空间优化以及全量SQL分析进行了展开。最后跟大家简单分享了一些我们在智能优化方向的一些思考和实际探索。智能化方向是CloudDBA的未来,这块我们还在不断地尝试,也期望有兴趣的同学能够加入我们一起去探索。