使用 python 管理 mysql 开发工具箱 - 2

这篇博文接着上篇文章《使用 python 管理 MysqL 开发工具箱 - 1》,继续写下自己学习 python 管理 MysqL 中的知识记录。

一、MysqL 的读写分离

学习完 MysqL 主从复制之后,可以考虑实现 MysqL 的读写分离,从而提高 MysqL 系统的整体性能。具体控制读写的路由功能可以交给应用程序或者MysqL-Proxy 程序来实现。读写分离其实就是让 Client 写入 master,而读数据从 slave 节点,这样减少了 master 既写又读的压力。这里没有具体介绍如何实现读写分离的功能,后续研究一下 MysqL Proxy 程序,这是 MysqL 官方提供的实现读写分离的程序。

 

二、slave 节点的负载均衡

1. 使用 DNS 来实现负载均衡

往往 slave 节点是多个,实现 slave 节点的负载均衡是非常重要的。其实可以采用 dns 的功能一个域名指向多个 slave 的 IP 地址,这样 Client 每次解析到的 slave 地址都是平均分布的,简单的实现了负载均衡的功能

2. 健康检查监控

我们自己需要实现一个监控程序,检查 slave 的健康情况,包括如下几个方面:

  • 是否能连接 slave 节点,判断 timeout 是否会超时即可
  • 检查 slave 状态,是否能正常工作。执行 show slave status\G; 查看 IO/sql Running 是否正常。
  • 主从同步时间间隔是否过长。如果 Second_behind_master > 2 认为太慢了

监控程序扫描所有 slave 节点,判断上述指标,把健康的 slave 节点加入到 DNS 解析记录里边,有问题的剔除出去。

三、DNS 基本安装和配置

1. 安装 rpm 包

[root@vip ~]# yum install bind -y

2. 修改配置文件named.conf

options {
    listen-on port 53 { any; };    # 修改为any
    listen-on-v6 port 53 { ::1; };
    ... ... ... ...
    allow-query     { any; };      # 修改为any

添加内容

zone "example.com" IN {
    type master;
    file example.com.zone;
};

3. 添加设置区域zone文件

[root@vip ~]# vim /var/named/example.com.zone     # 添加如下内容
$TTL 1D
@   IN SOA  ns.example.com. root.example.com. (
                    0   ; serial
                    1D  ; refresh
                    1H  ; retry
                    1W  ; expire
                    3H ); minimum
    NS  ns.example.com.
ns  A   192.168.0.8
www A   0.2

4. 启动named服务

[root@vip ~]# service named start

5. 测试dns解析

[root@vip ~]# host www.example.com. localhost
Using domain server:
Name: localhost
Address: :: 1 #
Aliases:     # 成功解析OK。
www.example.com has address 0.2

 

四、DNS 实现动态记录更新

DNS动态更新必要性:

  • 某个slave出现故障,DNS应该将该slave剔除,不要解析这个slave节点
  • 复制比较慢,拖后腿的slave节点也应该剔除出去。

考虑:类似keepalived的健康检查。

1. 生成key文件

[root@vip ~]# dnssec-keygen -a HMAC-MD5 -b 256 -n HOST -r /dev/urandom dnskey

生成 2 个文件

2. 修改配置文件named.conf,让dns支持更新:添加如下代码

key  {    # 该key为新增加内容
    algorithm HMAC-MD5;
    secret 25z/5wjwD4GsMgQluWagfkQ9TSqpoJzYbh/I/QEZo2M=";   # secret内容参考Kexample.com.+157+46922.key文件内容
};

zone ;
    allow-update { key ; };   # 增加一行
};

3. 创建update.txt文件

使用nsupdate前需要创建个文件,告诉nsupdate怎么样去更新update.txt,内容如下:

server 127.0.0.1
debug yes 
zone example.com.
update delete s.db.example.com. A
update add s.db.example.com. 86499 A 
update add s.db.example.com. 0.2
show 
send

4. 赋予/var/named目录写权限

5. 手动更新dns记录

[root@vip ~]# nsupdate -k Kdnskey.+42183.key update.txt

6. 验证

7. 问题总结

 

五、Python 实现 DNS 查询

需要使用到 dnspython 模块,需要执行 pip install dnspython 安装此模块。

参考:http://blog.chinaunix.net/uid-24690947-id-1747409.html

 

六、Python 实现 DNS 动态更新

代码参考:

# 动态更新dns记录
def dnsUpdate(zone,name,rdlist):
    key = dns.tsigkeyring.from_text({zone:keyring})
    up = dns.update.Update(zone,keyring=key)
    rdata_list = [dns.rdata.from_text(dns.rdataclass.IN,dns.rdatatype.A,i) for i in rdlist]
    ttl = 60
    rdata_set  = dns.rdataset.from_rdata_list(ttl,rdata_list)
    up.replace(name,rdata_set)
    q = dns.query.tcp(up,'127.0.0.1')
 调用
dnsUpdate(',1)">s.db七、MysqL 从服务器状态检查

按照检查的要求,对 slave 进行健康检查,代码如下:


keys = (
    Slave_IO_State,Master_HostMaster_UserMaster_PortConnect_RetryMaster_Log_FileRead_Master_Log_PosRelay_Log_FileRelay_Log_PosRelay_Master_Log_FileSlave_IO_RunningSlave_sql_RunningReplicate_Do_DBReplicate_Ignore_DBReplicate_Do_TableReplicate_Ignore_TableReplicate_Wild_Do_TableReplicate_Wild_Ignore_TableLast_ErrnoLast_ErrorSkip_CounterExec_Master_Log_PosRelay_Log_SpaceUntil_ConditionUntil_Log_FileUntil_Log_PosMaster_SSL_AllowedMaster_SSL_CA_FileMaster_SSL_CA_PathMaster_SSL_CertMaster_SSL_CipherMaster_SSL_KeySeconds_Behind_MasterMaster_SSL_Verify_Server_CertLast_IO_ErrnoLast_IO_ErrorLast_sql_ErrnoLast_sql_Error 模拟一下slave节点列表,设置注意实验时设置某些实例为不健康状态
conf = {
    master':127.0.0.1:3306slave:[
            127.0.0.1:3307192.168.0.8:3307127.0.0.1:3308192.168.0.8:3308127.0.0.1:3309192.168.0.8:3309 检查slave节点的状态是否正常
 checkSlaveStatus(host,port):
    try:
        conn = MysqLdb.connect(host=host,port=port,user=root)
    except Exception,e:
        print e
        return False
    cur = conn.cursor()
    cur.execute(show slave status)
    data = cur.fetchall()    获取到了冒号后边的value,key没有获取到,和sql shell显示不同.

     将keys和data组合为字典的结构
    data = dict(zip(keys,data[0]))
    
     IO/sql Running 是否正常
    if data['] == No' or data[:
         False
    elif data['] > 2:   主从复制时间持续超过2秒,太慢了
         False

     到这里肯定是没问题的了
     True

 将ip:port解析为主机+端口
 parseIP(s):
    host,port = s.split(: host,int(port)

if __name__ == __main__:
    host = '127.0.0.1' # 写IP好像连不上,需要授权相应的主机
    port = 3307
    alive = []
    for ip in conf[]:
        host,port = parseIP(ip)
        print checkSlaveStatus(host,port)

八、MysqL 从服务器状态更新

对 slave 健康状态检查后,将健康的节点列表记录,更新到 DNS 记录中。代码如下:



print q
    

if 解释下这里为什么要设置slave的alive集群阈值
     如果不设置阈值,那么存在健康的slave过少,会导致slave的雪崩现象
     反而会影响服务的正常运行,保证只有在一定数量情况下才更新dns记录.
    if float(len(alive))/len(conf[']) > 0.6:
        dnsUpdate( 注意: 1. dns服务一定要保证/var/named目录组用户有写的权限 2. iptables 和 selinux 一定要设置好,最好设置为关闭状态.

九、MysqL 监控测试

通过上边的代码已经实现了 slave 的健康检查,DNS 的动态更新。现在可以做一下测试:

> 执行:

[root@vip MysqLmanager] python MysqL_dns_monitor.py

> 结果:

> 扩展:
其实可以准备几台独立的虚拟机来做测试,每台虚拟机作为要给 slave 节点,模拟一些健康问题,看是否能够正确检测并更新到。

十、MysqL 从服务器信息来自CMDB

待更新。。。。

相关文章

功能概要:(目前已实现功能)公共展示部分:1.网站首页展示...
大体上把Python中的数据类型分为如下几类: Number(数字) ...
开发之前第一步,就是构造整个的项目结构。这就好比作一幅画...
源码编译方式安装Apache首先下载Apache源码压缩包,地址为ht...
前面说完了此项目的创建及数据模型设计的过程。如果未看过,...
python中常用的写爬虫的库有urllib2、requests,对于大多数比...