编辑推荐: |
本文主要介绍完整的京东数科618大促备战的过程,解密京东数科在大流量的数据库应用场景下的应对策略,希望对您的学习有所帮助。
本文来自于Gdevops,由火龙果软件Alice编辑、推荐。 |
|
分享概要
1、运维概述
2、备战准备
3、618进行时
4、案例复盘
本次分享将围绕数据库运维,从四个部分进行:第一部分先介绍数据库团队运维的概况,接下来通过大促备战准备、618进行时、以及案例复盘这三部分分享,来介绍我们数据库团队完整的备战过程。
一、运维概述
1、运维团队
我们团队三个主要的工作方向:
1)数据库运维
我们负责京东数科所有业务的数据库运维工作,服务于整个研发团队,保证数据库平稳高效运行。
2)自动化智能化运维产品
这个产品有一个非常好的根基,所有的需求、功能点都来自线上运维需求,来自我们的痛点。它服务于我们DBA运维人员,致力于提高我们团队整体的运维效率,完善数据库周边的生态服务。
3)科技输出
把我们在公司内部生产的优质的数据库架构、分布式数据库解决方案,以及做得比较成熟的数据库产品输出给外部的公司,帮助客户快速建立一套完整的数据库架构体系。
2、运维目标
下图的七个关键词是我们日常运维最基本的目标,如果我们在以下这七个方面做得非常好,那么我们就能实现保障数据库平稳高效的目的。
1)海量数据
首先,海量数据运维。这是DBA必须要面对的话题。那么我们如何保证海量数据库平稳高效运行呢?我认为运维规范是最重要的,按照规范做好架构规划、做好冷热数据分离,做好变更规范等等。只有这样我们才能驾驭海量数据的运维工作。
2)架构转型
第二,架构转型。现在很多公司的业务都面临的架构转型这个难题,不管是业务发展战略的需要还是数据库出现了性能瓶颈的问题,很多人都在做去oracle,在做分布式数据库或者利用中间件进行水平拆分的相关工作。对于DBA来说,需要在这个过程中做好以下服务:一是异构数据库的迁移,二是数据库之间实时同步,三是在保证架构合理的前提下严格控制成本以及保证数据安全。
3)服务可用率
第三,服务可用率。关于这一点,我觉得“精细”是非常关键的。如何理解“精细”二字呢?现在很多公司都开始做自己的容灾系统,MySQL的高可用切换大都基于MHA进行二次改造开发,还有很多人用raft多副本写来一致性协议去保证数据一致性。总的来说,在切换效率上和数据一致性保障上都有所提升。
但是在我看来,切换之前的故障探测、故障场景的分析以及切换决策的逻辑,这些方面要远远比切换本身重要。我们要对故障的根因进行充分的分析,要非常清晰地涵盖所有极端场景,这样整个容灾系统才能保证排除掉所有异常情况,所以做好数据库故障场景精细化管理非常重要。
4)持续
第四,性能保障。这一点无需赘述,作为一个运营人员,我们要持续保障数据库性能。关于这一点,我想说一个很重要的现象,在我们团队中很多人不愿意去做性能保障的工作,他们更愿意做前瞻性的技术研究,做自动化、智能化的设计开发,以及科技输出的相关工作。
在我们团队有一段时间我发现我们的DBA把更多的精力投入到数据库的拆分迁移、投入到自动换运维产品的开发设计,投入到对外输出的项目当中去,忽略DB性能的管理优化,他们认为性能优化不容易出成绩,所以他们更愿意做新技术的研究,去开发数据库相关的产品组件,去做科技输出。其实这就偏离了DB运维的本职工作。性能优化要持续做下去,即便我们现在有很多自动化的优化手段,也要坚持做好性能优化保障,因为我们的运维产品还没有到达完全人工智能的那个阶段。所以这项工作我们要持续下去。
5)保障
第五,数据安全。数据安全对于我们而言就是“数据不丢失、不泄露”,具体内容为储存数据快速同步、分布式事务的一致性、在关键的敏感字段上进行数据加密、数据库备份和容灾。只有做到这些才能保证数据的安全。数据安全是安身立命之本,它就是那个1,如果没有那个1,后面再多0都是无效的。
6)高效
第六,水平拆分。现在很多公司都在做中间件的开发,实现数据库的水平拆分、实现类似业务透明、分库分表等等,但如何去衡量中间件产品的好与坏呢?在我看来就是高效,很多公司做了类似的工作,尤其是中间件支持分布式的事务,但是又有几家公司敢在自己核心业务上用这个东西呢,这里就涉及到效率的问题。好的产品组件都做到了服务高效、对业务透明、研发改造成本低、有很好的数据流控管理、自动的弹性扩容还有高效的分布式事务服务,这些都是分布式数据库追求的目标。
7)价值
最后,数据服务。在完成前面六项基本运维目标以后,如何保证数据在各个系统、各个层面之间的流转?如何保证数据同步?如何结合大数据平台进行分析、计算,帮助业务人员挖掘数据的价值?需要做好数据生态管控,通过复制平台,ETL管控平台做好增值的数据服务。
以上这些就是我们运维的基本目标。
3、运维体系
接下来介绍一下我们的运维体系,把刚才基本的运维目标再提升一下。
我们的核心目标是保证数据一致性、保证容灾可用性,还要符合安全合规的管控。基于这些方面,再通过运维自动化提升运维效率,保证数据治理,维护数据生态。
那么如何去实现核心目标呢?这就需要我们按照各个业务层面的业务需求,去做相关运维自动化产品的工作,而这些产品其实都是由人为手动阶段逐渐演变出来的产品。
1)应用层
首先在应用层,业务的需求有什么?
① 数据库建模
这个工作是非常重要的,现在好多人都在说大数据、数据标准、数据治理。其实自动化的数据建模才是数据标准管控的源头,只要把数据建模做好,后面大数据的事情就非常容易了。基于我们的需求,数据建模实现了这么一个平台DBCM。
② SQL自助查询
现在很多研发在开发调试过程中需要查询数据库,还有一些业务人员需要查询导出一些业务数据。在整个查询过程中需要管控,一些核心数据也要进行加密,事后还有一些查询审计的工作,最终这些需求形成了我们查询机的产品,它能够帮助我们进行线上运维,并帮助运营人员实现数据的快速查询。
③ SQL自助变更
以前我们做数据运维的时候,大多数数据变更都是手动操作的,这种方式不但误操作风险大,而且DBA的工作效率极低。所以我们做了一个工单系统MagicFlow。
这个工单系统包含三个功能:
第一,SQL审核。研发提上来的SQL是否合理?是否规范?是否有风险?通过SQL审核基本上就能够把它过滤掉。
第二,审批流。这一点很重要,研发做什么操作都要经过上级的审批,包括数据库做什么操作也需要经理或者总监做一层审批,尤其在一些大型银行或者企事业单位,这种审批还是非常重要的。
第三,自动执行。降低DBA手动执行的风险点。自动执行模块还能根据数据库性能进行调度调整。在性能压力比较大的时候,工单是会延后执行的。
2)中间层
中间层就是数据库中间件,刚才说了数据库中间件只要做到了高效的服务就OK了。通常包含水平拆分、读写分离、弹性缩扩容、分布式事务。我们ShardingSphere目前是Apache明星项目,具有业内影响力的开源数据分片中间件,建立了为上百家企业提供数据库解决方案的生态圈。
3)数据库层
接下来在数据库层,DBA日常的操作现在已经都归纳到数据库的自动化运营平台里了,日常的部署、高可用切换、备用等操作基本上都已经涵盖在自动化平台里。
还有数据库性能,以前数据库对于研发人员就是一个黑盒,如果研发想了解数据库的性能就要找DBA去咨询;现在我们通过数据库性能展示平台CleverDB,把所有数据库维度的信息都展现在平台上面,实现了数据库性能自助管理。在数据库出现故障的时候,我们也会进行分析,然后快速定位这个问题。
4)大数据层
最后在大数据层面,DBA做的是数据抽取和复制订阅,这一部分有两个工具:一个是数据复制平台DBRep,它可以做到实时数据的复制和解析;再一个是大数据计算与分析平台,它能够计算海量的逻辑运算。
二、备战准备
接下来讲一下618备战的具体情况,通过下图大家能够了解到,在备战这个阶段做的事情最多。我们要做备战巡检、容量的评估、优化改造、数据归档、压力测试、切换演练和变更管控,如果把这些点做到了,618时工作人员是特别轻松的,只需要做监控和应急处理。最后,每次618或者双十一后,我们还会对备战准备和当天出现的问题进行事件的管理,并结合案例进行总结。
1、备战巡检
① 自增主键
说到备战,首先要做的就是数据库深度巡检,首先是自增主键的问题,大家都知道自增主键为int类型时有一个上限值,有符号的时候是21亿,无符号的时候是42亿。当表中的自增主键到达这个上限时,会从1开始插入,结果表中已经有id=1的记录了,这个时候就会报主键冲突。
在这个点上我们曾经出现过两次比较严重的问题。第一个单表记录大概是7亿左右,当时研发同事要处理一部分数据,通过清洗后再写入这个表,为了不影响线上的正常写入,研发同事就提了一个工单,将自增主键改成了20亿,从7亿到20亿中间有足够的空间进行数据导入。结果过了一个多月,故障发生了,自增主键写满了,代码日志显示主键冲突,排查了好长时间之后DBA才意识到是这个21亿的问题,这是一个非常惨重的例子。
第二个故障是我们有一个数据库做了水平拆分,大概是10个库,每个库1000张表,而且这个表用了全局自增id,当时的情况就是每个表的记录条数远远小于21亿,但全局自增id的那张表已经到达21亿的上限,也就是所有分表的总记录条数到达了21亿。这个时候后续的数据就无法写进来了。当然解决办法也很简单,就是把全局自增id表删掉,然后快速建一个bigint表,让它从21亿之后继续自增,这样就解决了,但还是影响了一段时间写入和操作。
② 磁盘空间
第二个是磁盘空间的检查,磁盘空间的检查包含系统层面和数据库层面的检查。DB相关的就是binlog、errorlog、slowlog
generallog 还有数据文件,重点关注磁盘使用率、数据增长率、剩余空间预计使用时长。这里面强调两点:第一点,我们做了很多智能化的组件,在服务器经常会装各种client,产生一些日志,日志有时候非常大,如果运维人员不关注的话有可能会冲爆磁盘。第二点是在数据库,重点说的是general_log,有些DBA为了分析问题会把这个日志打开,结果打开之后问题分析完忘关了,隔了很长时间这个日志也会把整个数据库填满的。
③ 表分区
表分区这块,网络公司也是有做这种架构的,按照月、季度或者半年创建分区。618活动从6月1日到6月19日,所以6月份时间点非常关键,我们要检查一下分表或者分区都有6月份之后的表,要确保分区已经创建完毕。除此之外,按月水平拆分的分表也需要注意同样的问题。
④ 连接数
在连接数方面,我们也遇到很多问题。四年前,我在团队定过一个目标——不管什么样的活动,什么样大促的节日,我们都不能出现连接数的故障,只要不出现我们团队就去团建。结果四年过去了,这个目标还没有实现,大家就知道连接数的故障真的是层出不穷的。不过,虽然我们出现了很多问题,但并不代表我们没有应对方案。
首先在活跃连接数这部分基本上是从慢查询、事务逻辑和访问逻辑三个方面去优化。
第一,绝大部分活跃连接数高都是因为慢查询,一般情况下我们DBA通过添加索引或者研发改写SQL都可以解决;
第二,大事务、长事务引发的锁等待,一个事务包含很多逻辑步骤,有些逻辑可能会产生排它锁,因此而引起的和这个锁相关表得查询都被堵塞了。在高并发的场景下就显得格外突出。这种情况我们一般都会要求研发精简或者拆分事务逻辑。把大事务变成小事务;
第三,业务调用频繁,并发访问控制,写入量和查询量非常大,这个可能要从业务逻辑上去梳理,写的时候通过MQ去控制,读访问看看能否在前面添加redis缓存。比如说一秒执行1000个相同的SQL,同样,应用服务器由多台应用部署,打到数据库上的话,数据库很容易就满了,在这块如果写的操作就要加一些MQ。如果是只读操作就要通过缓冲或者优化调用逻辑。
其次最大连接数问题,研发在大促过程当中经常进行应用扩容,比如说扩容100台应用server,能够保证应用层面不出现任何压力问题。但大家想一下,如果扩容了200台服务器,每个应用的连接数是10,如果打到数据库连接是多少?之前这部分我们是没有进行有效监控的,后来我们把应用和数据库的元数据打通,就能知道任何一个应用服务器的台数是多少,连接的配置是多少,通过台数和连接数相乘,与最大数进行比较,这样能够在大促之前预判配置是不是合理的。
⑤ 慢查询
刚才也说到慢查询,这是一个持续优化过程,通过扫描的行数、返回的行数以及执行时间这些方面去分析。我们现在有一个自动化的运维平台,里面有慢查询的分析,所以这部分不仅有DBA在优化,每一个研发也会关注自己的数据库系统。
⑥ Top SQL和热点表
对Top SQL要有一个很清晰的了解,尤其是核心的数据库。高频的SQL通过审计获取相关的信息,对高频的SQL可以获得热点的信息,哪些表被频繁访问,哪些表数据量比较大,哪些表做了水平拆分之后分布不均匀,这些都可以通过表维度获取。
⑦ 备份
接下来是备份,在大促当天或者前一天,所有的数据库都是不备份的。为了避免从库的IO争用,原因很简单,把IO让给大促的业务压力,怎么去处理这个事情呢?我们要保证大促前几天所有的备份都是有效的,一旦出现问题时,我们可以通过前几天的备份和日志去进行快速的恢复。
⑧ 定时调度
不仅包含数据库运维层面的调度任务,还还包含业务层面的跑批任务。目的就是为了减少不必要的IO。例如数据库备份、业务跑批、ETL抽取、信息采集。这些都不能在大促零点这一刻发生,所以我们会把这些任务往后延,一般都是两个小时以后。我们要确保调度任务错开大促高峰时间,所以每个作业的开始和结束时间都需要我们梳理。
定时调度,这里不仅包含数据库运维层面的调度任务,比如信息采集 备份调度,更主要的是DBA要掌握业务跑批得时间和时长
、大数据抽取的时间和时长。我们要确保调度任务错开大促高峰时间。所以每个作业的开始和结束时间都是需要我们梳理的。
⑨ 容量评估
容量评估与磁盘空间的巡检不太一样,它包含硬件的使用容量和性能使用容量,容量评估的目的是为了评估数据库的架构、性能与资源是否匹配,以此推动硬件和架构的优化工作。后面会重点就讲这块。
⑩ 硬件&机房
硬件和机房的检查其实不是我们DBA来进行,但是像磁盘出现故障的地方一定要在大促的时候检查出来。这个每年都做,而且硬件的厂商也会在关键的时期排售后工程师协助我们完成这些巡检工作。
业务梳理
业务梳理也是非常重要的,比如核心业务对数据库的依赖程度,业务对数据的依赖程度是强依赖还是弱依赖,在我们公司内部要求弱依赖,数据库挂了,核心业务不能挂,不能影响到终端用户。在这方面做了很多架构上的弥补,比如说加了MQ,加了Redis。
事务逻辑的读写,尤其是核心业务,在核心业务支付主链路上,任何操作的事务我们都会去分析,保证每个事务的效果。如果数据库宕机,业务有没有熔断的保护措施来避免终端用户受影响?业务方之间有很多接口调用的逻辑,哪些接口可以做降级保护,哪些接口有严格的超时限制,在核心业务这个范畴里,这些都需要DBA去了解清楚。
接下来是上下游的调用,通过上下游接口调用的分析,我们要保证每一个接口效率都是高效的,如果说出现了接口上的故障,整个业务要有自动熔断的能力。
下图是我们巡检的通道,现在我们的数据库规模已经过万,现有DBA是完全不可能做到人工逐个巡检的,所以我们也是通过智能化平台把这个平台开放给研发和所有DBA,通过这个平台能够快速定位问题,这样前面所有的问题都能在很短时间内被发现。
2、容量评估
今年公司层面硬件服务器是零采购,在数据容量方面面临的压力是非常大的。业务发展需要服务器,但是我们没有新的机器,那么如何对资源进行合理的管控?如何甄别资源使用不合理的业务架构呢?我们通过以下几个维度来做。
首先是SQL质量,如何看待一个SQL的好坏呢?通过这三个维度:第一个叫CPU维度,单个CPU维度上面产生的QPS越大,说明SQL的效率越好。比如说消耗1%的CPU,QPS是2000,你就可以知道,当CPU打满的时候QPS最大能够支撑到多少。
接下来还有IO层面,也就是单个IO上面产生的QPS有多大,就说明查询的效率有多快。
通过QPS除以百分比,就能知道最大能够支撑QPS和TPS,通过这个方式做了几个分档,落在哪个档里就能得到多少分数。通过这种方式目的是督促研发去改造它的SQL,通过这个逻辑会给每一个数据库打分。分数如果合理,研发就可以继续去用;如果不合理,就会被扣分。这个分数和绩效是息息相关的,所以每个研发都非常注意SQL的质量。
第二个是磁盘使用率,比如说磁盘空间关注的是不是接近100%?容量这部分我们关注的是磁盘使用率是否合理,比如说超过了80%,这时候应该做什么呢?应该去做归档。如果这个数据库长期只有300G,但磁盘是7T的硬盘,我们认为严重浪费了资源,这个DB资源需要缩容处理。所以在这方面我们会对两头极端情况进行扣分,督促研发去改进架构。
此外,这里面会结合一些权重,比如说SQL的权重、主从库的权重、业务等级的权重,核心业务和非核心业务的权重比是不一样的。
通过上图,大家可以更好地理解容量评估要做什么,也就是说,在红框内我们认为服务器使用是合理的,在红框之外的大于70%扩容去做归档,小于30%则是资源被严重浪费,我们要求研发做缩容处理。通过这样的方式我们实现了今年服务器零采购,这是一个非常了不起的事情,因为京东每年的硬件采购费用非常高。
我们经常用这样的逻辑给研发解释为什么要做这个工作。首先,一个业务刚成立时,我们基本上会给到单机多实例的架构。也就是说,在物理机上面选择其中一个数据库实例去用(一般情况下一个物理机创建5-8个数据库实例),随着业务不断地发展,我们会弹性扩到物理机上面,如果物理机还不能满足它的访问需求,我们会通过CDS和SS去做水平的拆分。
通过巡检,通过容量评估,我们基本上能够快速定位数据库服务器资源使用情况,接下来基于这些信息我们可以在备战的时候清楚要做的事情,例如要优化哪些东西,是不是要做架构的调整等等。
3、优化改造
在自动化性能展示平台里面包含了优化的功能,SQL的优化是做一系列的采集分析,给用户优化建议,用户通过优化建议可以自动去做索引的添加或者SQL改写的工作。
配置优化也是,有些业务的数据库配置需要做一些动态的调整,比如说做一些促销活动时,某些数据库的参数需要微调,这个时候通过配置优化功能就能够快速地实现。
数据优化这部分在整个备战过程中消耗DBA的精力非常大,因为无论是数据的归档还是数据结构的变更,效率和时长都是非常长的。
比如说把7T的服务器里面30%的数据挪到另外一台机上面去,这个过程不能够一次性操作完成,要一点点去做,而且还要考虑数据库的性能,中间可能会有停顿。我们的数据库归档平台和数据库变更平台就是可以在数据库高并发过程中进行有效的管控操作节奏。
架构的优化,r2m是我们内部Redis集群,Hcenter就是HBase的集群。通过这种途径添加r2m缓存,添加MQ消息队列,把一些OLAP的查询挪到大数据上面去。代码这个层面的优化主要是基于前面巡检分析进行业务逻辑优化,比如说对一些事务要有逻辑的控制。以及关键接口添加降级熔断开关。
下图是扩缩容的逻辑图,在我们自动化平台实现所有环节步骤。把DBA的运维思想融入到自动化平台里面去。比如说你在做扩容的时候,到底是提高硬件服务器的配置,还是说去做垂直拆分,还是做水平拆分。这些逻辑都有一定的规范,整个扩容和缩容准备会进入到数据迁移的过程,在数据迁移里面会通过数据管道,类似数据复制相关的工具去帮你进行数据的搬迁,同时还会有一些数据一致性校验的工作,最后通过数据库切换实现缩扩容的动作。
4、数据归档
数据归档,有两个比较核心的点:
第一,在归档时对数据库的性能进行监控,如果性能很高或者压力很大时归档需要暂停。
第二,归档对冷热数据有很清晰的划分,这个也是根据SQL审计得来的,日常SQL访问都落在哪个区域之内,通过分析我们能知道数据在哪里。通过数据划分之后,我们就可以指导研发在归档平台去做数据归档的请求。
归档基本上有以下四大类:
第一,备份、删除。这些数据需要保留很多年,这时只需要把数据库做一个备份,把线上的数据删了。
第二,历史表。如果有足够的空间,可以创建一张历史表,把历史数据挪过去,减少业务表的数据体量,这样可以保证正常业务高效的访问业务表。
第三,归档库。根据用户归档的规则,把历史数据挪到另外一个归档库里面去。
第四,大数据平台。这个归档平台也可以做ETL抽取工作,可以把这些数据挪到大数据平台里面去。
5、压力测试
压测很简单,就是通过压测演练去寻找应用层面、缓存、数据库本身,以及应用接口是否有异常情况。基于预估的峰值压力,以及大促热点活动进行有针对性的压测。
6、切换演练
切换演练,这是网络公司每个月都要进行的,做这个的目的很简单,就是为了提升整个团队的协作能力。因为这里涉及到研发、数据库、应用运维,所以进行一次演练可以让很多团队一起协作。
最主要是提升团队应急故障的处理能力,还有做高可用系统的检查。因为高可用系统在初始化时有可能域名绑定的是物理IP,这时再去做切换就可能会出现问题,所以有些数据库高可用还是需要进行检测的。
7、变更管控
在大促之前我们都会进行封网的操作,尽量不让研发上线做数据库改动。正常的流程是研发提了一个工单,先通过自动的审核,再经过研发总监或者经理的审核,最后DBA审核,所有审核通过之后会通过自动执行模型到数据库里面来。
在真正大促开始的时候,我们会在研发Leader和DBA Leader之间会加一个VP的审核,也就是说会让更高层级的领导去管控变更的风险。
研发提工单最怕的是什么?他们害怕流程不清晰、流程繁琐、审批麻烦,要做的事情在流程上体现不清晰。DBA在审核工单的时候最怕什么?他们担心研发提交的数据源不准确、SQL语句有错误(尤其是很多语句中的其中一个是错误的)、没有where条件、需要回滚数据的工单。
所以基于这些痛点,我们开发了工单自助系统,这个系统包含两个部分,一个是流程管控,另外一部分是inception自动的审核系统。
其实我们是不提倡在大促中间去做变更的,我们当时有一个非常严重的故障,有一个SA做批量的装机,因为有一个应用想扩容,这哥们想扩100台虚机,在扩容的时候使用DHCP动态去分配IP,结果分配IP里面有几个是数据库的VIP。大家想一想,这个动作一旦真的执行下去,会产生很严重的问题,所以通过工单流程,我们还是能做一些管控的。
三、618进行时
在大促零点峰值到来之前,我们会做一些操作:第一,关闭数据库半同步,提高数据库的读写性能;第二,关闭所有的数据库信息采集。
我们要确保在大促峰值压力过程中,不会出现备份、ETL抽取、数据推送和业务跑批等不必要的IO压力。总的目标就是保证业务峰值的io容量。当然这样操作同样是有一定风险和代价的。比如核心业务数据的一致性风险、备份恢复时间长、任务跑批延后等。
618当天我们更多的是通过监控大盘去了解所有系统的运行状态。如图所示,数据是以业务的视角进行展示的,每一个框都是数据库集群,业务研发人员通过这样的监控大屏可以看到所有数据库的指标。如果他看不懂可以看水位图,如果整个集群压力到达像右上角红色的部分那样的程度,则说明有问题。
DBA要关注每一台机器的性能,0点时刻我们把上图称为“大促心跳”,所有的压力会直线上升,通过这个图可以看到哪个机器是异常的,哪个没有心里预期的压力大。哪些机器的性能波动不在预期范围之内,这些是我们之后要复盘、总结的地方。
还有真的出现故障的时候,下图是性能分析的页面。也就是说,从页面层面和问题解决层面,我们有三种不同的视角监控数据库的状态。
在应急预案保障方便,我们在大促之前都做了梳理,硬件层面、性能故障、服务组件故障,不管哪个层面出现问题,我们都有相应的应急手册做指导,规范运营人员的应急操作。
大促结束之后我们又做了事件的管理,把大促备战和618当天发生的事件和故障记录了下来,这个是记录的维度。这个系统最主要的目的是寻求故障解决方案,把故障彻底地分析一遍,通过业务的层面、架构、运维的视角,再结合安全和合规的要求,寻求最合理的优化改造方案,并持续跟踪改造成果。
四、案例分析
案例一
给大家分享两个例子,第一个例子,有一个数据库,因为扩容的原因主库后面挂了15个从库,真正在大促0点那一刻这个数据库读写性能非常慢,后来经过分析,我们发现就是这15个从库在向主库获取日志的时候对主库压力太大了,所以当时的解决方案是关闭了几个不太重要的从库,把主从复制断开。
这个事情通过复盘我们还是找出很多能够改进的点。
第一,在数据库架构里要严格控制从库的数量,超过5个以后,我们就要用级联复制的方式或者dbrep做复制。
第二,在扩容之后研发要做二次的压测了。如果当时进行压测的话,是能够发现主库性能下降的故障问题的。
第三,自动化分析系统为什么当时没有识别这个故障?就是因为对这个复制用户产生的访问压力,我们自动化性能分析平台把它给忽略了,这一点要在以后自动化云平台上去添加自动识别的异常,如果它的并发进程过多也是有一个异常。
第四,自愈,这个问题解决方法就是要杀掉几个从库。当时我们DBA还是很纠结的,15个从库可能对应着不同的业务接口,关闭哪一个从库,当时我们还是讨论了很长时间。如何实现自愈呢?我们把所有的业务,所有接口按照一个业务等级去做一个排序,把等级低的直接关闭,这就不需要跟研发沟通了。
第五,资源扩容的时候要有一个数量的提醒。
第六,应用接口增加容错机制。当时我们关了几个从库,关闭之后应用接口就疯狂地报错,导致后面的一系列应用也出现了问题。虽然说没有影响到终端用户,但是我们认为接口要增加容错的机制,也就是说针对数据库挂掉的时候,应用能够有一个降级的逻辑。
案例二
第二个案例,在619大家都已经开了庆功宴,有的人都喝香槟去了,我们DBA在619零点十八分做了一个操作,就是打开半同步。刚才讲了,大促之前要关闭半同步,要提升主库性能。我们认为大促已经结束了该把半同步打开,结果打开一瞬间触发了一个bug,数据库重启了。
但我们事后分析这个故障,我们发现在两阶段提交的最后一个阶段,这个过程分为三个步骤,第一个Flush
Stage,第二个Sync Stage,第三个Commit Stage。在flush stage环节会把数据写到Binlog缓冲里面去,在Sync
Stage里面会把所有Binlog刷盘,第三个是根据顺序的调用存储引擎提交事务,这个就是Binlog写磁盘的操作逻辑。
整个过程中跟半同步有什么关系呢?后来我们分析了一下源码,也找了一些资料,发现在第一阶段,半同步在打开的时候,每一个事务会往active
transaction这hash表里记录提交事务的name、pos和entry标识,缓存这些信息的目的是在发送binlog时判断要不要等从库返回的ACK。这个entry的意义就是告诉从库这个event需要返回ACK,实际上就是供从库去判断要不要返回ACK应答的标识。如果从库在收到binlog的时候发现有entry值,就会返回ACK应答,如果没有它就不返回。
在第二个阶段设置binlog的相对位置,就是设置一个等待ACK返回的binlog值和pos点。如果从库返回的ACK里面包含的内容和pos点比等待的值要大,那说明这个事务就可以提交了,如果小的话就不能提交。刚好我们DBA就在这个阶段半同步打开了操作。
这个时候大家可以想象一下,在flush阶段有一条数据写入了,写入的时候active
transaction这张表里是没有entry标识的。在第二个阶段——Sync Stage阶段,从库因为没有标识,所以就不会返回ACK。但是主库因为识别了sync_master_enabled这个变量,所以它认为这个事务应该等ACK的返回,结果从库没有返回ACK,主库又一直都在等,所以出现了assertion
failure的错误。
其实这个错误也很简单,在改写的时候,这个bug只需要同时验证enable和entry这两个值,如果都有的话才会去等待ACK的反馈。我们查询官网的资料后发现5.6.35,5.7.17,8.0.1以后的版本都解决了这个问题。
经验总结
最后是经验的总结,好的地方不说了,说一下我们需要改进的地方。
① 容灾演练
我们经常做的演练都是模拟主从切换,但对于极端的场景我们是没有测到的。这些极端的场景如何去做演练?这些是我们今后要注意的地方。
② 性能优化
性能优化这部分要解决的问题也很多,我们要多从业务视角指导研发去做优化任务,在优化过程中还需要改进。
③ 数据治理
数据治理就是数据冷热的分离,这样能够对数据库进行保护和容灾。但冷热数据的界定还需要更加的灵活和准确。
④ 资源管控
资源管控可以帮我们做架构和资源合理性评估,可能以后互联网公司会更加注重硬件资源的使用率,服务器采购会越来越少,如何在有限资源里把架构设计得更加优化,这些方面需要考虑。
⑤ 业务优化
我们的DBA还是要多深入到业务层面,帮助研发减少业务逻辑在数据库层面的交互次数,简化事务逻辑。同时提出降级熔断的方案。帮助研发打造健壮的业务系统体系。
|