一个关于如何管理海量机器的“关联结构模型”。这个题目有点长,各位且往下看,听我慢慢道来。
最近PAAS和IAAS平台很火,如果使用得当的话可以大大的提高运维的各种战斗力。但是目前还不是所有的服务都可以适用以上的平台。PAAS平台的设计上跟google的borg思想比较接近,都摆脱了以往的运维模式中,服务对于单机服务器的依赖。
从长期来看,borg这种神器是国内运维圈奋斗的目标。但是,在目前没有这些高科技产品的情况下,还是需要去care每一台物理的服务器/虚拟机。
此文主要围绕在这种场景下,如何高效的管理大量(千+万+以上)服务器,介绍一个基于”tag层级”的服务关联系统。
这个模型本身并不复杂,由于还是想将“管理海量机器”这个话题尽量说透,需要费一些口舌。各位须知:魔鬼隐藏在细节中。
废话不多说。先举几个日常运维如何管理机器、服务的例子,再层层阐述:)
一、一般批量执行命令都是这样的:
1 |
for hosts in `cat host.list` ; do ssh $hosts "some cmd";done |
这个方法大家一看就懂,将机器列表写入一个文件,然后批量执行。在这个基础上,可以通过expect等方法、工具去封装实现更多的功能。说这个东西是运维自动化的最早雏形一点也不为过。我以前就经历过一段时间,通过excel来收集、管理每台服务器的信息。每台机器上面有什么服务,有什么端口等等。总之,作为运维,你要熟悉你的服务。
我们来看一下这种方法的模型:其实就是一个一维的表格,用excel来表示再贴切不过了。它无法给我们更多的信息。要知道,我们的服务即使不是网状,也应该是树状的模型。
不知道有多少同学,经历过自己一个一个的写脚本来做监控的。我经历过这个阶段,想知道有多蛋疼?可以从明天开始在自己的服务上试试。
这个阶段的核心问题是没有对服务进行更高层次的抽象,只是通过简单罗列的方式进行管理。
说句题外话,以前面试过一些自称有”运维开发经验“的工程师,做的很多东西本质上都是这个方法的升级版而已。话说到这里,我觉得如果只是做这种东西出来,还是不要好意思说自己做过”自动化运维系统”。→ →
二、一些开源软件在管理机器/服务的方式。比如nagios、cacti、zabbix这些比较常用的开源软件,管理机器的时候可以用分组来管理,也可以支持树状结构,来从一定程度上表示逻辑或者抽象的层级关系。
但是这些软件在使用过程中都有一些很不便的地方。举个实际的例子,在监控这方面,一台服务器上可能运行了多个程序实例,需要监控这些程序的端口、语义等信息。基本上这些开源软件,都是使用模板或者模板嵌套这种方式与主机或者主机组进行关联。
我们来看一下这种情况,其实是一个多对多的模型:主机(多个)—-主机组(多个)—监控模板(多个)—监控项(多个)。
这些开源软件在机器少的时候这些基本还可以凑合。但是当机器越来越多,业务越来越复杂的时候的时候,真是谁哭谁知道。π_π…
这个阶段机器管理模型可以说已经有一定层次的抽象,能在一定程度上反映服务、服务器的关联关系。但是给人的感觉却是比较的散乱和复杂,不够清晰明了,给人感觉很鸡肋。还有一个细节就是比如我把一台机器加入/移除一个节点或者模板,并不能自动关联/取消监控项、报警条件等。还是比较麻烦。
这个阶段的主要问题是什么呢?其实不太好总结,开源软件的设计目的就是为了满足绝大多数人的需要,在功能和设计上偏向于中庸之道,很多你想要的效果,它要么不支持,要么通过一种很灵活的方式去支持(用过zabbix,zabbix的灵活性确实很棒)。但是,在你不需要那么多的功能的时候,灵活反而成了一种束缚,变成了臃肿和笨拙。需要你去做二次开发来满足需求。如果你已经到了这个阶段,那么恭喜你,你的系统规模、复杂度已经超过了众多的同行(大厂的可以无视了,但是谁想过这些大厂的系统为啥是么设计的?)。
三、再看看百度大名鼎鼎的noah系统。话说noah系统在前几年面世的时候,应该是把国内公司的一些运维系统甩过了几条街。其实,庞大的noah系统核心是一颗”树”,可以方便的增删改树上的节点,机器依附在节点的末端。周边的部署、监控、权限管理等等众多的系统(当时有一大堆的周边系统,日常运维能用到的都做过)。
我们还拿监控来说,上面所属的开源软件的一些缺陷,这边都很好的解决了。之所以能解决好的一个重要原因就是:根据自己的需求去定制开发。这样才能达到开源软件达不到的效果。
通过将机器与节点强关联,然后再在节点上添加监控相关的属性。这样的效果是,前期将监控属性都创建好。新加一台机器,只要进入这个节点,那么他上面关联的那些监控就会自动添加生效,机器移除节点,相关的监控就会从这台机器去掉。类似于部署系统也是这样关联的。(没找到树的图片,用字符代替树状结构)
1 2 3 4 5 6 7 8 9 |
+/-BAIDU +/-NSOP +/-MP3 Search Mbox Zhangmen +/-IMAGE Search Daily |
这是一个“严格的,带有层级结构的,无限深度的树状结构”。一个节点类似于这样:BAIDU_NSOP_MP3_MBOX_JX,意义是这样的 : BAIDU (公司) –> NSOP (运维部门) –> MP3(业务) –> MBOX(系统)–> jx(酒仙桥机房)。
这个节点是固定死的。如果有新的业务、服务甚至机房的信息都需要提前建立节点,一级一级的建。最要命的是,一旦建立完成,将机器加入这个节点之后,由于本身设计的问题以及周边系统的强依赖,导致做一个更改基本不可能。比如我想在”MBOX(系统)_(jx酒仙桥机房)“中间添加一个北京甚至中国这样一个节点,来满足异地机房、国际化分布的展示、管理问题,基本上没招。
noah的这个设计在初期的时候,各个产品线的工程师管理个几千乃至上万的机器都还问题不大。但是随着业务复杂度的提升,毕竟众口难调。你很难做一个东西出来满足所有人的需求,除非你的设计够前瞻够灵活。当时的自动化思路并没有走向api这条路上,只是一味的想在web端把所有的需求都满足了,现在看来这些都是很大的弯路。
更可怕的是一旦依赖一个系统,大家对于它的依赖越多,一方面说明了它确实做得很成功,当另一方面势必带来一个噩梦般的问题:如果有一天这个东西从最基层的设计上已经无法满足以后的发展需求了,那么要迁移这么一个东西也是很费时费力的。
这种机器管理模型的特点就是:严格限制、周边强依赖、缺乏API。
我并无意贬低前厂,相反国内绝大多数搞运维的同行都挺羡慕noah这么一个平台。noah的成功是因为它很大程度上解决了海量机器运维的需求,但是由于其先天设计的一些不足(毕竟谁也不是神仙),到了一定程度的时候就不能满足发展的需要。这种情况下如果不能及时转向,那么其实会越走越远。
所以建议是在规划设计初期,将各个功能完全的独立开。通过一种足够灵活的机制来保证未来的扩展性。做运维系统不要太贪心。而且,做运维系统比较忌讳”做的人不用,用的人不做“。须知我们做系统的初衷是为了解放大部分还在一线苦苦打拼的兄弟们,如果这些同学们说做的不好,那肯定是有问题的。这个问题可能不仅仅是在系统/工具的设计、产品、研发上,更大的问题出在整个运维团队的方向、构成、理念上。
我觉得运维工作做到一定的程度(至于是什么程度,只可意会XD),要学会做减法,抛弃众多令人眼花缭乱的系统、技术、工具,思考和寻找适合自己团队发展的道路,抓住核心。
到了这里,作为一名经历过以上所有阶段的运维屌丝,我(以及团队,嘿嘿)决定改变这一切,于是就有了今天文章的核心。
—————————————— 以下内容翻墙可见,哈哈 ——————————————-
系统的设计概要如下:
通过层级和tag的方式为每一台物理/虚拟的服务器做标记,外围系统通过组合查询的方式拿到所需要的机器列表。
每个tag代表一种属性,属性可以是各种各样的。比如可以标记服务器故障下线,可以标记服务器运行了一个程序nginx,标记服务器的属主是某个team,可以标记服务器的idc位置,可以标记服务器是个虚拟机,等等。总之我们的目的是希望将服务器所有可能需要用到的属性都做一个标记,以便我们在需要的时候方便、快捷的取出来。
系统包括(但不仅限于)以下功能:
提供完善的增删改API接口,提供一套查询语法规则。
可以生成以服务器为单位,用来准确、直观的反映服务层级关系的动态树状模型。
支持不同维度去初始化动态树。
通过对tag授权,实现人员/组到机器粒度的授权。
以下分要点进行详解。
一、level、tag、schema
Level和tag都是两个抽象的概念,本质作用都是用来对某些属性进行描述,并将其应用到服务器上。从原则上来说不同的level是平级的,并没有附属关系。Schema指为了初始化动态树作为展示(web),所需要定义的不同level之间的层级关系。
Level可以理解为对于一类属性的合集。
举几个自己定义的例子:
Level | Level中文含义 | Level说明 | tag举例 | 是否必须 | 是否关联 |
cop | Company,公司 | 表示公司属性。一般可以有一个默认的属性(公司业务没有子公司) | xiaomi,duokan | 是 | 是 |
owt | Owner team,所有组 | 表示所有组(运维组)的属性 | miliao,miui | 是 | 是 |
loc | Location,地域 | bj、gz、us | 是 | 是 | |
idc | IDC,数据中心 | sd、dg、sjhl | 是 | 是 | |
pdl | Product line,产品线 | ml、b2c、dba | 是 | 是 | |
sbs | Subsystem,子系统 | fe、ln、im、mfs、hadoop | |||
srv | Service,服务 | ||||
mod | Module,模块 | ejd、xmq | 是 | 是 | |
grp | Group,分组 | 00、01、02 | |||
ptn | Partition,分区 | 20m-50m、50m-70m | |||
cln | Cluster-node,集群节点 | master、slave | |||
fls | Flow-status,流量情况 | full、exp | |||
status | 机器状态 | 机器可以有几种状态
在线、故障下线、待交付等 |
online、offline、delivered | 是 | 否 |
virt | 是否虚拟机 | n,y |
说明:
1、表中定义的“是否必须”列,其中如果为“是”。则表示机器在加入服务树的时候必须要有此level层级的tag,否则不予添加。
2、level可以根据需要任意添加,每个level下的tag可以枚举;在添加的tag的时候要考虑清楚适用的场景是什么,是一个独立的属性还是用来表示关联关系。
3、level要保持唯一性。同一个level下面的tag不能重复,不同level下可以有相同的tag名称。在每一台机器上可以在同一个level下有多个tag。
4、关联tag是指tag在关联到机器上的时候,以tag组的形式保存。关联tag的引入是为了解决多个tag组合查询的时候,多对多造成的多种组合(实际上我们要的只是一种组合)。
举个例子,某个机器有这么一个关联tag:cop.c_owt.t_idc.i_loc.l _pdl.p _sbs.s_mod.m。
独立tag有如下几个status.online、virt.n。
参照上面的表格,这里解释一下以上的各种tag所表示的含义。cop.c表示这台机器有一个“属于c这个公司”的属性,owt.t表示此机器有个“属于t这个team”的属性。loc、pdl、sbs、mod的几个也是同样的道理。status.online表示此机器是在线服务状态,virt.n表示此机器不是虚拟机(那就是物理机器)。
来几张我们自己系统的截图
最早系统做出来的时候,第一批机器是通过掉api给机器打tag加上去的。加上去之后,可以通过web端查看。目前有一个默认的schema,cop_owt_pdl_sbs_srv_mod_idc。它的意思是:这颗树的展示结构遵循以上的顺序。我可以任意的更改,树的结构,比如:cop_owt_pdl_idc。它会重新组织数的结构,按照这个结构来展示。
二、查询
查询的api,遵循一种特定的语法。
通过给出一个称为”tag-string“的东西来查询需要的机器,它的基本语法是与和或查询。
比如:cop.xiaomi_owt.miui_idc.sd与cop.xiaomi_idc.sd_owt.miui和cop.xiaomi_owt.miui_idc.sd是等价的,这也体现了”level平级的理念“。或查询通过逗号来支持:cop.xiaomi_owt.miui_idc.sd,idc.gg等价于分别查询cop.xiaomi_owt.miui_idc.sd和cop.xiaomi_owt.miui_idc.gg得到的结果。
另外权限也融入到api之中,原则上如果对于查询其中的tag有read权限,则可以将结果显示出来。
三、周边系统如何关联
——————–内容较多持续更新—————–
16 Comments
啥时候开源?
这个东西我们去年9月份已经上线了。当时没想过要开源,如果有需要的话会有开源的计划。:)谢谢支持
太有需要啦!
请问 你们开源了吗?github地址多少?
期待“周边系统如何关联”的分享
可以参考adc 分享那个ppt
这个基于tag的系统的确比noah的服务树模型更灵活易扩展,我的理解是基于这个系统可以管理复杂的服务:1.不知道这个系统在小米的使用效果如何.2.文章中没有提到的,周边系统,相信这个系统的api可以支撑大量的周边系统,如监控,部署等.不知道小米的周边系统有哪些使用了这个系统.用的效果又是如何?
监控系统用了,可以参考博客中 ADC那个PPT。部署、门神也用了,会在下次分享。
现在真是感觉没法管理越来越多的主机和监控项,期待开源啊,
tag的设计思路很赞
tag思路赞一个,期待开源
能否介绍一下“关联tag”在数据库层面是如何实现的呢?通过什么方式记录这些tag是某一组的?
能留言?
能留言,不过得后台审核
初期设计,会上已经把tag的思想说了。但依旧推行失败。深刻体会到七层模型的上面还有一层政治的模型==
metrics 2.0 的思路,跟 graphite-explorer 一样
我们也在朝这个方向发展,同样对 “做的人不用,用的人不做”深有
同感
能否请教下机器和tags之间在数据库里是怎样的一个存储结构?