大规模机器集群-基础环境一致性

扶醉桌前 提交于 2019-12-22 08:41:10

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

本篇讲 “故障自动维修流程”里 “环境初始化”这个环节。

 

初始化的问题—环境不一致

可能大家会觉得,环境初始化有什么好说的,不就是跑一堆设置系统参数的脚本么? 事实上,设置环境很容易,但是要保证环境设置正确会遇到很多问题。

 

环境不一致影响业务的case

先来看我们对业务sre 的访谈,因“环境设置不正确”导致业务受损的case有很多,如下所示, 

  • 因超线程未开启,导致服务在流量高峰时性能不足,产生请求拒绝

  • 因QoS未设置,导致跨机房查询数据时,响应延迟飙高,大面积拖慢了了用户访问速度

  • 因未设置ssd磁盘内核参数,导致磁盘处于低性能状态,影响业务读取速度

  • 因网卡多队列未正确设置,导致单个cpu被打满,产生拒绝请求

  • 因基础agent版本不一致,影响变更、数据配送任务,产生了脏数据

  • 因core pattern 未正确设置,业务程序出core打满磁盘,拉长了止损时间

  • 因环境缺失/版本不符导致业务程序依赖异常,产生请求拒绝, 如mysql/hadoop client 缺失, python/perl 版本过老

  • 因内核网络、内存参数未正确设置,导致业务出现性能颠簸问题,产生间歇性请求拒绝,排查成本高

上述case,都是因部分机器环境未正确设置导致的,也就是机器环境存在“不一致”的情况。

 

环境不一致的原因

为什么会不一致?我们分析了各个业务初始化脚本集合,得到的结论是:“硬件/系统多样、业务需求差异化、初始化流程不统一不规范” 这3个因素综合作用导致了“环境不一致”。

 

1、硬件/系统多样

机器硬件不一样,设置某个功能的命令是不一样的。

比如开启超线程,戴尔机器和惠普机器不一样,这导致同一个功能,业务sre会写出多个脚本, 例如 cpu_ht_dell.sh, cpu_ht_hp.sh;

同样道理,系统发行版不一样,开机启动、参数文件位置、内核参数的设置方式有可能不一样,对于同一个需求,就会存在多个脚本,长期下来,几乎无法维护。

 

2、业务需求差异化

不同的业务类型,通常会根据自身需要,调优设置各种参数。

 

如接入层机器,需设置tcp内核参数,包括缓冲区大小、拥塞窗口大小;

 

存储层机器,需设置内核换页、磁盘调度策略、shm参数;

 

计算密集型业务机器,需开启超线程,QoS优先级设置为高;

 

这些差异化的存在,使得各个业务sre小组都维护着一套自己的初始化脚本集合,很难共用、复用。

 

3、初始化流程不统一、不规范

业务sre执行初始化时,没有统一规范,初始化的执行方式多样(pssh/ansible/部署系统),而且没有强制性检查。

由于环境初始化失败,不会影响服务的初期运行,只有在流量大的时候才会出现问题,如果执行初始化的sre经验不足或者不够细心,这些“环境初始化失败”的机器,也会投入使用,造成隐患。

 

 

怎么解决不一致

在自己动手解决问题之前,我们粗略地调研了业界的环境管理方案:puppet,存在以下问题,

  • puppet管理的资源中,有file, service, yum 等, 但不包括硬件,如BIOS、超线程、网卡多队列; 另外,关于service 这个资源,涉及到版本问题,需要和部署系统联动,puppet似乎没有提供相应的功能

  • puppet has its own configuration language,  puppet 通过自成体系的配置语言来声明资源,控制任务的执行,这对我们来说是一个很大的学习成本,我们需要的是:低成本地使用已经存在的上百个脚本,而不是用别的语言重写它们。

  • puppet 是 C/S架构,意味着需要部署它自己的agent,在几万台机器的集群上部署一个新agent,风险性很高,需要经历漫长的审核、测试、运行验证过程

 

解决思路

所以,我们决定还是结合自身问题来解决,分以下几步走,

 

1、引入apply-check机制,规范初始化的执行和检查,保证交付质量

apply-check强制要求每一个初始化的执行和检查成对出现;

apply 即对文件或内存写入,check即对文件或内存读出并做对比判断,例如,

Item

Apply

Check

超线程

ipmitool raw 0x3e  0x20 0x00 0x00 0x00

cat /proc/cpuinfo  | grep -o ht | uniq

 这样,可以明确知道初始化是否成功。

 

2、根据机器品牌,部署硬件/BIOS/系统发行版相关命令工具

 

如图所示,超线程的初始化apply、check脚本分别软链到了相应厂商的实现脚本,这样就可以在执行时,无需关注机器厂商、系统的差异,直接调用,消除适配问题。

 

3、明确业务类型和初始化集合的关系

我们引入 Pool 的概念,每个Pool对应一个环境初始化集合,如下表所示,

Pool

超线程

网卡多队列

QoS

Tcp参数集

Disk io参数集

Web

on

on

on

off

计算

on

on

on

off

存储

off

on

off

on

通用

off

on

off

off

 

这样,给定一台机器,只要知道归属于哪个集群,就能通过调用相应的check来判断这机器的环境是否正确,是否一致。

 

 

解决环境不一致问题

 

做了上述优化之后,我们在机器重装系统流程中增加了apply-check的逻辑,可以保证环境一定是正确的,因为只有在所有初始化的check通过之后,系统才会交付。

 

对于存量机器,我们把环境不一致当作一种故障来处理,复用了硬件故障维修的流程框架。

环境不一致修复的工作流程,

  1. 环境检测: 每5分钟发起一次环境检测,即调用初始化的check脚本,获取当前时刻整个集群的环境不一致的机器列表,推送到工作流子系统

  2. 安全策略: 遍历机器列表,依次执行安全策略,过滤不符合要求的机器,得到一个可安全执行初始化脚本的机器列表

  3. 执行初始化: 根据机器所属pool,执行相应初始化apply脚本

  4. 检查初始化:根据机器所属pool,执行相应初始化check脚本,如果初始化正确,流程结束

  5. 如果初始化不正确,那么认为此机器存在硬件或系统级别的故障,生成repair_host流程,本流程结束。

(故障修复流程框架的详情请参阅 大规模机器集群-故障自动处理(一) )

 

通过这两点,逐步消除存量机器的环境不一致,同时保证新交付的机器一定是正确的。

 

 

在解决基础环境一致性问题之后,结合硬件故障自动维修,我们得到了一个能力,

输入: 任何一台机器,不管是否有故障,环境是否正确

输出: 无硬件故障,符合业务环境需求的可用机器

 

这为后续做机房建设,灾备重建打下了基础,下一篇会讲这部分内容。


 

排列文字,重组感受。

我是曲行人,日常写码,闲时写点儿文字,

如果你觉得有点意思,或者有点用,可以关注我,

我将在大脑里的思维原子做布朗运动时,输出文字。

公众号: qxren7

二维码: 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!