京东到家MySQL容器化,为何首选Docker而非K8S?

DBAplus社群 2020-11-25 19:27


本文根据詹乡泉老师在〖deeplus直播第250期〗线上分享演讲内容整理而成。(文末有获取本期PPT&回放的方式,不要错过)


詹乡泉

京东到家运维部DBA


  • 2年研发,6年DBA从业经验,关注MySQL、Redis相关数据库技术。


一、起因和选型


1、起因



大概在一两年前,我们京东到家在进行容器化前面临着以下这些问题:


  • 资源配额:在资源调配上,特别是新业务上线需要比较多的资源或者想要大规格配置机器的时候,资源尤其紧张。当时我们面临着机房迁移的情况,临时或者促销活动需要申请调配资源就比较困难;

  • 管理复杂:有一些公司数据库使用时间比较长,导致公司内部使用版本非常老的数据库,或者存在着使用版本不统一的问题,这种情况下想要进行管理就非常的麻烦;

  • 审计需要:我们当时面临一些审计需求,需要记录我们在数据库上的操作日志,由于旧的使用方式的问题,导致无法满足一些审计需要;

  • 使用方式:由于当时的局限情况,对于整体的资源配置我们无法做到把握全部的权限。此外,整体的申请流程对于我们来说,也不是完全可控的。所以从集团的角度上看,数据库的核心资源并不完全在运维的掌握下。基于此,我们就考虑是不是可以借着整体机房迁移的路线进行整体化的改造。


容器化也可以理解成迁移上云的过程,当然这个云指的是私有云。大家在使用云端产品的时候,其实会发现和迁移上公有云的思路也是一样的,只不过私有云的资源我们是可以完全把控的。


2、选型



1)容器化的优缺点


容器化只能解决容器可以解决的问题:


优点:


  • 规格标准统一/标准化:比如说,MySQL怎样实现单机多实例呢?最常见的做法是,单机启用多个MySQL实例,需要考虑端口不一样的问题。但是对于云端的产品来说,很多的端口都是统一的,比方说默认的3306。当然会有一些公司不太需要特别去统一端口,它们的端口可以随便按照一定的规则往下加,就能解决单机多实例的端口规划的问题;

  • 管理灵活可控/资源隔离:对于MySQL来说,用比较原生的方式很难做到资源隔离。在高规格的机器上部署很多实例时,里面比较繁忙的实例很可能会完全拖垮在业务上白天相对使用率比较低的实例。从这方面考虑,容器化就能够很好地解决资源隔离的问题,但对底层架构来说是一个变化着的挑战;

  • 资源动态分配:在用原装的产品的时候这一点可能体会较少,但如果我们完全掌握了容器和资源,就可以解决这个问题。比如,业务线原本需要16核,但是在高负载的秒杀或者促销场景下,CPU完全100%,这时可以快速对资源进行动态分配,扩张到32核甚至48核。对于很多常见的云端产品来说,在没有进行容器化的时候进行这种操作比较难。按照我们之前的经验,需要提前做好资源规划,或者做临时扩容,但难题是需要做场景服务。


缺点:


  • 容器自身监控

  • 容器bug

  • 疑难问题定位


随着技术发展,做技术选型也要适配公司业务发展和扩张变化,我们需要不断思考可能会遇到的问题和随时进行业务迭代。


2)Docker


考虑到以上的问题,我们觉得容器化改造很有必要性,并且它能满足我们当时的一些需求。


因为我们的Docker针对MySQL运用,当时也需要考虑在Docker里需要注意哪些问题,所以我们在这几个方面做了相对于应用来说不太一样的适配,以宿主机为概述:


①配置选择


  • 高容量内存

  • 多核心

  • 高性能ssd:普遍来说选择pcie接口就能满足要求,除了一些高并发场景需要选择NVME接口。


②镜像管理


  • MySQL版本,不需要过多


最开始有一些比较老的MySQL版本,大版本加上小版本总共八个版本,这时候使用Docker可以根据需求定制化镜像,最终我们统一改成了5.6、5.7这两个版本。


③部署流程


对于应用来说,数据库的部署对于K8s的需求来说并没有那么强烈,底层可能是一个库或者几个库,而应用的机器是几十或者几百个。最主要的区别是,应用是一个无创产物,研发人员来思考它的开启和关闭不会考虑太多问题,但对数据库来说就不是这样的:


  • MySQL是有状态服务,相对稳定和长期使用


网络模式需要根据自身条件取舍,由于我是DBA出身,而且团队对网络这一部分也不太熟悉,在当时的条件下经过了测试后发现没有什么问题就选用了套索模式。


3)为什么没选择k8s


  • 数据库服务是有状态的服务,要求更强的稳定性;

  • 常见的程序应用扩容非常简单,直接用镜像靠拢机器,加上分发、授权的现象就可以直接用,可是数据库服务弹性伸缩需求不强。数据库要做弹性扩容常见的方式就是改进配置容器去重启服务,但是对于需要伸缩云端产品的时候,也是类似的思路,想改高配置的话也需要流程去重启服务,但是对我们业务线来说不可接受。但是Docker在一定程度上解决了这个问题,因为刚刚也说到Docker可以进行CPU的扩容,但对我们大部分的研发线来说也不是日常的需求;

  • 基于现有流程改造更简单,只需要调整流程,加进Docker的部署就可以。


3、部署考虑




4、部署流程



基于到家业务场景下的部署和流程


这套自动化的流程需要自己把控,现在到家这一套流程保证在5分钟之内完成,可以给研发提供一个生产交付。


5、管理拓扑




我们刚买的机器和宿主机的规格还是比较匹配的,配置是128核、256g、xxx(18:56)这个样子。


我们当时的规划是平均所有业务线的数量,以8核16g作为一个技术(基础)标准,所以一个宿主机上部署了10个容器,每10个容器会预留一些资源以备扩容缩容的需求。如果布局过多的话,IO有可能扛不住,因为有一些业务可能比较特殊。


比方说从elk中把数据同步到数据库,然后再从数据库中处理,但是有一些业务比较特殊,有一定几率影响到宿主机上的其他业务,导致启动延迟、延迟调用的问题。所以部署也要看利用场景的标准规格。


图里展示的是一部分的管理拓扑,其实和现在的线上业务类似,后续随着业务场景的更变,更重点关注的是宿主机和容器,但对应用来说他们是没有什么区别的。而站在研发的角度上看,他们并不关心你们底层运用了什么技术,他们只关心这个运维产品是否能保证数据库稳定操作。


当然更重要的是,我们要保证自己hold得住新技术,再落实使用,这样才能更好地推动新技术或者架构的改变。


6、运维平台




我们之前的运维平台没有进行容器化的改造,几乎所有流程都是断断续续的。但进行容器化改造之后,所有的宿主机和资源都在我们自己手上,这样起码能够满足我们的审计要求。


为什么我们要做容器化改造呢?因为当时从简单管理上选择了host的模式,而使用这个模式有一个问题,就是创造的IP是宿主级的IP。简单点说就是,主从节点上看到的IP不是真实容器节点上的IP,而是宿主机的IP,这就导致了在拓扑上查询是有些不太准确的。所以基于此我们就做了一些定制化的改造。


可能每个公司的具体情况不同,但是运维平台的建设都是大同小异的,都分为:


  • 流程申请类:对于流程类的尽量都做到自动化,不要把时间耗在一些不必要的事情上;

  • 研发自助工具:很多运维人员都会面临一个痛苦的情况,就是被技术人员找上门控诉数据库有问题,但是大多数出现问题的情况都是应用自身的问题,可能是连接池、能源配置等方面运行不当。如果你的运维工具做得足够好,在出问题的时候就能够避免很多“背锅”情况,所以基于此我们做了7、8种自助运维工具,保证每个问题都能看到对应的情况;

  • 分析模块:比较常见的是日志分析、慢日志和巡检系统等,我们拿到日志、所有的数据库指标和报警信息之后,可以做趋势判断,像是故障自愈、对资源负载倾向性做预估等等。


二、问题和解决


1、前期问题和规划



  • 网络模式

  • 宿主机规格

  • 单实例承载能力

  • 运维平台改造


对于单实例承载能力,我们到家的在MySQL运维方面上单实例承载能力是30000 QPS。每家公司业务团队的方向不同,如果想要达到30000 QPS的话就需要考虑重构和分拆。


我们用的是非常大的ssd。虽然我们在容量上不是特别着急,但还是那句话,在引入新技术后压测能力最起码要达到95%。虽然我们都知道从应用中直接访问数据库,中间通过了一层容器,就算它是万兆网卡、没有延迟问题,但是等到哪天被研发人员告知数据库访问慢,就不得不去怀疑是容器的问题了。


这样的情况我们也遇到过,如果之前连接速度是0.1毫秒,但是现在变成了0.2毫秒,中间0.1毫秒的误差还会出现放大倍数和增减,就很让人怀疑确实是容器的问题。我们觉得引入了能解决问题的新技术,但是其他问题也要纳入考虑范围,像是上面也提到了的“容器化只能解决容器可以解决的问题”,所以网络问题也是我们需要留意的重点。


2、解决迁移过程中遇到的问题



1)整块大规格ssd解决io不满足问题


最开始在认为数据库容量在1T~2T的情况下,我们考虑的一个数据库大约放10个Docker,所以把一个大盘分成4个小盘,相当于分散部署。


在这种部署情况下,我们认为在io方面是不会有问题的。但这样就会涉及到一些其他的问题,比如说随着业务场景的变化,在凌晨的业务模式下的活动可能导致非常高的io,这样就拖慢了这个盘上另外的实例。


所以早期出现这个问题之后,我们觉得把一整块ssd全部合并在一起相对来说更好。


2)指定数据库版本解决数据库版本过多问题


我们是在多个数据库版本中制定了两个版本,在这个问题上不建议大家跨多个版本使用。比如说,从5.5升级到5.7对各个方面人员来说都是没有大问题的,但是从5.5升级到5.7的话对研发人员来说实现环境和代码上就有可能会出现问题。


3)核心库分散部署解决单一宿主机多个核心库问题


在单机上部署多个实例,不可避免地出现多个核心库部署在一台宿主机上的情况,如果这个宿主机挂了,虽然数据库有高频解决方案,但是不免会遇到核心业务宕掉的特殊情况。


因为每条业务线的情况都不同,所以最好在早期规划的时候就做好数据库定级,解决核心库聚集的问题。


4)冷热实例分散部署解决io压力大的实例聚集部署问题


实例分散不算是特别紧急的问题,因为比起热实例,冷实例相对更加重要,这也需要从业务层面上配合界定。

当然我们也有遇到过最极端的情况,有一些实例的业务特殊性导致写入实例非常频繁,运维团队有负责日志中转这一块业务的同学,它们中写入非常频繁,每天产生的binlog高达几百,这时候我们在和业务协定之后采取了最极端的做法——关闭binlog。


当然我们是大规格的ssd,但是对于80这种相对来说规格比较小的ssd来说可以尽量避免容量上升的问题,如果到后期真的涉及到容量问题,就需要考虑迁移。


三、过程和发展


1、前期规划



  • 选型

  • 测试

  • 实践

  • 小规模部署

  • 验证


2、迁移排期



  • 业务分级:先从周边、非核心业务做迁移;

  • 流量验证;

  • 解决遇到的问题;

  • 设计回滚方案:不需要每次验证,但需要保证回滚方案是可行的。


3、后续部署



  • 批量迁移;

  • 规划排期:有新的业务可以往容器化之后的排期上迁移,这就需要有合理的规划;

  • 资源冗余:拿到新的宿主机资源之后,需要进行资源合理分配以及资源最大化利用,避免以后出现需要用到资源但资源不足的情况。


4、迁移计划




  • 整体迁移过程:做好排期计划,先周边,后核心;

  • 不适合迁移的项目:多元复制实例(基于选型此类不适合);

  • 边改造边迁移:相关流程改在,满足审计、研发等相关需要,优化Docker image。


四、未来和思考


1、可行的改进点



  • 报警自动处理,回调机制:无论是用什么监控平台,在进行容器化改造之后都可以把这些能力加入进去;

  • 弹性扩容:如果做不到完全的弹性扩容,但是可以做弹性扩容工具,来对Docker的负载进行调整;

  • 统一接入接口:运维平台用统一接口以进行查;

  • 全链路问题排查:有一些业务场景的应用会出现数据库的问题,如果这时候能够从下往上帮助研发同学去溯源根因,也能从不同的角度看到运维平台的问题。但是如果你的平台自助工具做得足够好,他们也能够自主去排查问题了。


备注:需要注意容器的超卖问题。


2、思考



  • 容器的演进和局限:关注容器版本的升级和维护;

  • 推而广之的数据库容器化:我们数据库团队也不只是做MySQL,并且统一标准和资源隔离的特点对数据库产品来说很有用处,所以我们也在考虑Redis、ES、MongoDB等的容器化改造是否也可行;

  • 自下而上的问题追溯:可以由底层分析汇总数据反推业务潜在风险和问题;

  • 私有云平台可行性:进行容器化改造之后,运维平台就变成了私有云平台,所以也要考虑平台接口服务化,和应用联动排查全链路问题。


在整个过程中,如果我们有了足够多的数据,并且有很好的分析工具来支撑,就能够反向推动我们更好地建设业务平台。


早些年有一些公司和业务线特别深入地绑定在一起,但在建设私有云平台或者考虑自主运维的时候又不希望和业务离得太近,这个距离度虽然比较难把控。


对于运维的同学来说,深入了解业务以及保证建设云平台过程中运维、数据库产品的顺畅运行这两个方面虽然有所冲突,但是也需要仔细考虑。


>>>>

Q&A


Q1:有用nvme ssd吗?无法做硬raid,怎么解决硬盘损坏的问题啊?


A:Nvme的机器较少,只有2-3台,用于高并发合高qps的业务,磁盘损坏的话只能做高可用切换。


Q2:多个nvme组成一个大的lvm vg吗?一块盘坏了 这个宿主机上的所有容器都要做高可用切换,影响比较大吧,那怎么满足大空间需求啊?


A:Nvme的机器较少,上面实例都是比较稳定并且空间增长比较缓慢或者稳定的业务。


Q3:请问单台服务器上用了几块ssd,每块是多大容量?


A:2T*8,raid10。


Q4:容器化部署时也需要设置宿主机的操作系统各种参数,和传统实例部署类似,仅仅是一个容器拉起实例,一个mysqld启动实例,怎么体现出快速部署啊?


A:优化过的配置文件和数据库文件都写入到image中,部署的时候只需要选择少量配置,如ip和版本,主从架构等即可,宿主机只用于部署mysql实例使用,参数都经过调优了。


Q5:如果一整块大盘出了故障是不是影响会比较大,恢复起来比较复杂?


A:如果上面业务多会比较麻烦,另外就是实例占用空间大小也会影响恢复时长。


Q6:请问之后会考虑用k8s么?


A:会考虑。


Q7:数据库主从、集群高可用,用的什么方案?


A:主从是Master-slvae,高可用方案是改造过的mha。


Q8:数据库是有状态的,会放到glusterfs等共享存储上吗?这样一个容器停了,新容器还可以在其他虚机或宿主机上快速恢复?


A:研究过相关方案,但是在数据一致性上发现不太好实现或者说比较复杂,最后就没有考虑。


Q9:容器里面的mysql datadir是挂载在物理磁盘?


A:对的。


Q10:4个2T SSD盘是外置的云盘还是物理服务器的本地盘?


A本地盘。


Q11:请问CMDB用的是什么方案,自研的还是用的哪个开源方案?


A:自研,每一个公司的业务场景和模式及时有类似也不会完全相同,参考过一些方案后,还是进行了自研。


获取本期PPT
请添加右侧二维码微信

↓点这里可回看本期直播