Zabbix分布式架构创建Node节点代码剖析

本文节选自正在撰写的《Zabbix监控系统——构建企业级分布式监控系统》一书稿件,预计下半年出版   最近在写一本关于Zabbix的书,正巧今晚写到了如何创建分布式Zabbix中的Node。一切是从Zabbix官方网站中对于创建Node的命令的警告,“只能运行一次命令,否则数据库会出现问题”。我对这个比较好奇,不清楚这个命令到底执行了什么,从而需要有如此严重的警告。这篇文章主要介绍我如何从一个入口,最后将Zabbix创建Node节点的原理弄清楚的过程,希望大家能从中了解到如何从代码级别分析解决Zabbix的问题。 这条命令是这样的:

直接编辑这个zabbix_server这个文件是没用的,因为这个已经是C语言编译过后的O文件了,我们要从源码开始看。首先我要知道这个“-n”参数是干什么,从zabbix_server.c找到了蛛丝马迹:

当我们使用“-n”参数的时候,会使得task的值变为“ZBX_TASK_CHANGE_NODEID”,继续往下看一点代码,就发现这个task的作用了。

这段代码告诉我们,当我们在执行ZBX_TASK_CHANGE_NODEID这项任务的时候,执行的是change_nodeid这个方法,我们用grep在源代码中搜索这个方法,找到了nodechange.c。

在nodechange.c中,我先根据printf方法,找到了建立Node节点的三个步骤: Dropping foreign keys,删除外键 Converting tables,转换数据库表 Creating foreign keys,创建外键   删除外键 从代码里看到,这是核心逻辑。

逻辑很简单,内容应该都在这个db_schema_fkeys_drop中,老办法,使用grep来找,发现了libs/zbxdbhigh/dbschema.c中定义了这个数组。在dbschema.c中,根据不同数据库,这个数组的内容是不同的,这里我选了MySQL的数组,截取了一部分代码,让大家知道里面的内容是什么:

这下明白了,这里面就是删除外键的SQL。 转换数据库表 这里的逻辑是三者最复杂的,首先还是看代码,先把转换数据库表操作的代码截取出来。

我们反过来看这段代码,最后的DBexecute显然是在执行一些SQL,看SQL的内容是在将一些值增加,即将tables[i].fields[j].name这个值增加prefix这么多(ZBX_FS_UI64是个占位符,我们就理解为%s就行了),tables这个数组也是在dbscheme.c中定义的,它的内容就是Zabbix数据库中的结构。这里tables[i].fields[j].name我们就可以理解为遍历数据库的每一张表。我们可以看到,这条SQL的最关键的是这个prefix。prefix的赋值过程是这样的:

ZBX_DM_MAX_HISTORY_IDS我们使用grep方法可以知道它是在include/db.h中定义的,nodeid就是我们传入的参数。

我们例子中传入的参数是3,那么我们就知道这里的prefix就为300000000000000。 再看下面还有一个对prefix的操作:

这个操作是只当某个数据库表的flags字段为ZBX_SYNC的时侯,会进行类似的操作,只不过ZBX_DM_MAX_CONFIG_IDS的值是100000000000000。 我们来看看flags字段的值是什么,首先我们发现talbes数组,它的类型是ZBX_TABLE。再追溯一下,我们从dbschema.h中找到ZBX_TABLE的结构定义。再进一步,可以知道我们上面这一行是一个ZBX_FIELD,根据它的定义,我们就知道flag字段原来是倒数第二个字段,我们随便在dbschema.c中找一行表结构的描述:

发现它的flag值是ZBX_NOTNULL | ZBX_SYNC。这里插一句,这种形式是非常典型的C语言中表示属性的用法,比如这里的ZBX_NOTNULL | ZBX_SYNC就表示这一行有两个属性,分别是ZBX_NOTNULL和ZBX_SYNC。再结合代码逻辑,下面这个逻辑与的含义就是这个数据库表是具有ZBX_SYNC属性的

后面的逻辑就简单了,我翻译下,就是说如果数据库表有ZBX_SYNC属性,那么prefix则还要再增加ZBX_DM_MAX_CONFIG_IDS*nodeid这么多。具有ZBX_SYNC这个属性,就表示这个数据库在分布式架构中,是需要在不同节点间传输的。 好了,prefix的来龙去脉搞清楚了。那为什么要将表中某个字段加上prefix呢?这里要简单说下Zabbix数据库表结构,对于任何一个资源(item,host等),在表中都有一个自己的id,比如itemid,hostid等,这个id是该表的主键。在分布式架构中,所有子节点的数据要同步到父节点中,难免会出现子节点中itemid(或其他id)相同的情况,所以需要将不同子节点的id区分开,所以要对于id加上一个前缀。比如10001这个itemid,再加上prefix后,可能就会变成300000000010001 创建外键 这个类似于删除外键,不做赘述了,各位可自己挖掘理解。

Date
Categories
Tags
Comments

Published:2014/02/28 View Post

Zabbix

Leave a comment

7 Ways to be a Better Programmer in 2014

O’REILLY Programming中的一篇文章,受益匪浅,原文抄过来的,没有翻译,值得一读   Coders make resolutions, no? If your to-do-better list is still empty, consider these ideas from other programmers to put to use in the New Year. Even the smartest folks have room to grow. The following excerpts are contained in the book 97 Things Every Programmer Should Know edited by Kevlin Henney. Check Your Code First…

Date
Categories
Tags
Comments

Published:2014/01/30 View Post

Uncategorized

Leave a comment

Python获取实例的方法列表,并运行方法

具体需求是这样的,有一个类,是用作检查运行环境的,比如python版本,java_home等,具体如下:

我在FlumeEnv中定了了很多检查的方法,都以_check开头,需求是在check方法中,要把每一个以_check方法开头的方法跑一边,希望能做到无论写了多少方法,check能自动找到所有方法并且运行。 google了下找到了解决方法,其中用到了dir和getattr。 代码示例:

在ipython中,getattr获得的已经是bound到a的方法了,所以可以直接使用:

 

Date
Categories
Tags
Comments

Published:2013/09/13 View Post

Python

Leave a comment

SublimeCodeIntel配置(以python为例)

sublime text2写写小脚本不错,自动提示看网上都说用 SublimeCodeIntel好,但之前一直配置不对,今天趁吃好饭有空把它配置好了。其实很简单,但网上有些说法不详细。   ctrl+shift+p,安装SublimeCodeIntel 安装好后,在弹出的窗口里,在最下面找到python,把注释去掉,检查下环境是不是ok,其他语言可参考:https://github.com/SublimeCodeIntel/SublimeCodeIntel 重启sublime,打开个python文件,按ctrl+shift+space,这时候第一次运行会去下载一些东西,可以按ctrl+~来看进度 之后就ok了。

Date
Categories
Tags
Comments

Published:2013/09/10 View Post

Uncategorized

Leave a comment

python如何使脚本以daemon方式运行

继承Daemon这个class,并且复写run方法就行了。然后就是start,stop,restart,和linux的init一样。 地址:https://github.com/baniuyao/python-daemon

 

Date
Categories
Tags
Comments

Published:2013/09/09 View Post

Linux Python

Leave a comment

storm提示only be run from with in a release解决方法

报错如下,无论是nimbus,ui,supervisor,都会出现如下报错: ****************************************** The storm client can only be run from within a release. You appear to be trying to run the client from a checkout of Storm’s source code. You can download a Storm release at https://github.com/nathanmarz/storm/downloads ****************************************** grep了下代码,发现是bin/storm会去找目录下的RELEASE文件:

原来是我手贱把目录下的RELEASE文件删除了,不知道为什么需要有这个机制,反正从别的机器cp过来一个就解决了

Date
Categories
Tags
Comments

Published:2013/09/08 View Post

Uncategorized

Leave a comment

Mac浏览器无法运行Java问题

http://support.apple.com/kb/HT5559 具体做法:

然后重启浏览器就行了,注意chrome还是有问题,用firefox就ok

Date
Categories
Tags
Comments

Published:2013/08/30 View Post

Mac

Leave a comment

storm ui显示supervisor个数与实际不符的解决

蛮奇怪的问题,具体现象就是启动了多个supervisor,单在ui上只显示一个(也有可能是多个supervisor中的某几个看上去被“合并”了),当我kill掉其中一个时,另一个就出现了。   重启集群也没有用,想到可能是zookeeper中有冲突,删除了/storm中的所有,一启动,发现还是这样。检查了配置,也没有不对的地方。接着检查日志,发现两个supervisor用的都是同一个id,随后检查zk,/storm/supervisors/下面也是一样的id。似乎发现问题了。   google了一把,发现了nathanmarz之前解答过这个问题,https://groups.google.com/forum/#!topic/storm-user/pheWVv_3JZ4   他的说法是: Delete the local dirs on the supervisors. They’ll generate new ids for themselves.   在删除了local dir,重启后恢复了。后来回想起来,是因为这个集群是拿线上的环境scp的,可能残留了local dir的东西,然后storm是根据local dir中的某一个或一些文件计算出一个supervisor id的。删除local dir后,会重新生成id。

Date
Categories
Tags
Comments

Published:2013/08/07 View Post

Storm

Leave a comment

how to修改bash提示符

之前看过dan的linux,bash提示符在$加了个换行,当时没在意。早上在看nodejs时候,目录好长,一个小窗口几乎放不下命令,想起可以改bash,于是网上google了下,其实很简单,修改PS1环境变量就好了。比如我这样:   mac默认使用的是\W,我这里用的\w,目的是显示完整的目录名,然后加上了时间。具体的参数,有下面的列表:   \! 显示该命令的历史记录编号。 \# 显示当前命令的命令编号。 \$ 显示$符作为提示符,如果用户是root的话,则显示#号。 \\ 显示反斜杠。 \d 显示当前日期。 \h 显示主机名。 \n 打印新行。 \nnn 显示nnn的八进制值。 \s 显示当前运行的shell的名字。 \t 显示当前时间。 \u 显示当前用户的用户名。 \W 显示当前工作目录的名字。 \w 显示当前工作目录的路径。  

Date
Categories
Tags
Comments

Published:2013/08/04 View Post

Linux

Leave a comment

码农们,迈开跑步的第一步

很久没更新blog了,前段时间忙东忙西的,想写的东西很多,但一打开blog就写不下去了,因为一写又是一大片。之前写了kafka技术实现的一个slide,结果游泳脚划破了一直拖着没讲,后来我直接传slideshare上去了。现在上来,写这篇完全跟技术没关系的东西,是希望广大码农能有个好身体。   码农们比较容易出毛病的就是颈椎,肩膀和腰了,还有就是变成胖子。形形色色的体育我都蛮喜欢,常年参与的是篮球和跑步,现在越来越喜欢跑步,因为篮球有对抗,万一脚崴了很麻烦,跑步就一个人,而且没时间,场地,人数的限制。 我去年经常头疼,就是从颈椎往上一直到后脑勺那边疼,不知道是什么原因,买了记忆枕稍微缓和点,但还是一个星期有1次左右。后来开始在健身房跑步,发现我头疼的话,只要跑跑步就好了。后来咨询了下医生,说可能是一直看电脑,颈椎僵硬压迫什么神经blablabla的,然后跑步会使得那里运动起来,有缓和作用。现在一年下来,基本是1,2个月碰到一次头疼,基本没啥关系了。 跑步的硬件成本有多高? ========================== 以我为例,迪卡侬短袖短裤各*2,一共不超过250块,nike的跑步鞋,京东330块,然后满300减60,当然最近打算amazon上海淘以上ascis的,600块。goout的腰带,里面放2块钱零钱中途买水,放iphone,用咕咚记录跑步的距离啊,热量之类的,有点成就感。 开始跑 ======================== 跑步一开始肯定不适应可能一会就气喘吁吁跑不动,这个是正常的。要注意几点: 跑前要做好热身,拉伸。其实就是弯弯腰啊,活动下膝盖,脚踝。 不要一上来猛跑,慢跑,不是冲刺。一上来跑很快,后面没体力就跑不动了。 马路上要注意车,特别是路口,腰带最好买有反光材质的,goout的盗版的就几十块,防水的很不错。 对于跑步伤膝盖一说,我现在差不多是跑一次5公里到6公里,1、2天跑一次,300块的鞋子,柏油路,健身房都有,没觉得膝盖有任何不适,而且我90kg这样的体重,一般人应该不会伤膝盖吧?这个我不确定,因人而异吧。 跑步能得到什么呢? ====================== 肥肉变少 运动完后洗好澡看看文档,效率很高 健康的身体 远离码农职业病 呼吸新鲜空气(我一般晚上跑,小区绿化也很不错) 可以一边跑一边想想东西 好了,废话不多,先出去跑一次再说,肯定会喜欢上的。

Date
Categories
Tags
Comments

Published:2013/07/24 View Post

Uncategorized

Leave a comment