本篇文章只介绍 ZABBIX 数据库高可用的实现方式,ZABBIX前端的高可用将在后续文章中实现
ZABBIX 数据库高可用组网
ZABBIX-DB1和ZABBIX-DB2都已经安装好Mariadb,系统版本和数据版本均相同
代码语言:javascript复制# mysql --version
mysql Ver15.1 Distrib 10.3.13-MariaDB, for Linux (x86_64)using readline5.1
# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
ZABBIX 数据库高可用实现方式
keepalived 数据库双主复制
两台MySQL互为主从关系,即双主模式,通过Keepalived配置虚拟IP,实现当其中的一台数据库故障时,自动切换VIP到另外一台MySQL数据库,备机快速接管业务来保证数据库的高可用。
Mysql主从复制
Mysql主从复制过程描述
(1)master记录二进制日志:在每个事务更新数据完成之前,master在二进制日志记录这些改变。MySQL将事务写入二进制日志。在事务写入二进制日志完成后,master通知存储引擎提交事务。
(2)slave将master的binarylog拷贝到自己的中继日志:首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlogdump process。Binlogdump process从master的二进制日志中读取事务,如果已经同步了master,它会睡眠并等待master产生新的事件。I/O线程将这些事务写入中继日志。
(3)SQL slave thread处理该过程的最后一步:SQL线程从中继日志读取事务,并重放其中的事务而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
主主同步就是两台机器互为主的关系,在任何一台机器上写入都会同步至备端。
为了便于后续数据库服务器的扩展,且在整个复制环境中能够自动地切换,降低运维成本,引入了当前主流的基于MysqlGTID的复制特性。
GTID工作原理
(1)master更新数据时,会在事务前产生GTID,一同记录到Binlog日志中。
(2)slave的I/O线程将变更的binlog写入到本地的relaylog中。
(3)slave的sql线程从relaylog中获取GTID,然后对比slave端的binlog是否有记录。
(4)如果有记录说明该GTID的事务已经执行,slave会忽略。
(5)如果没有记录,slave就会从relaylog中执行该GTID的事务,并记录到binlog。
(6)在解析的过程中会判断是否有主键,如果有就用索引,如果没有就用全部扫描。
GTID优点
(1)一个事务对应一个唯一的ID,一个GTID在一个服务器上 只会执行一次。
(2)GTID是用来替代传统复制的方法,GTID复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置。
(3)减少手工干预和降低服务故障时间,当主机宕机之后会通过软件从众多的备机中提升一台备机为新的master。
GTID也存在一些限制
(1)不支持非事务引擎。
(2)不支持createtable … select 语句复制(主库直接报错)。
(3)不允许一个sql同时更新一个事务引擎表和非事务引擎表。
(4)在一个复制组中,必须要求统一开启GTID或者是统一关闭GTID。
(5)开启GTID需要重启(5.7版本除外)。
(6)开启GTID后,就不再使用原理的传统复制方式。
(7)不支持createtemporary table 和 drop temporary table语句。
(8)不支持sql_slave_skip_counter。
ZABBIX 数据库创建
创建ZABBIX数据库和用户授权
代码语言:javascript复制mysql> create database zabbix character set utf8c ollate utf8_bin;
mysql> grant all privileges on zabbix.*tozabbix@localhost identified by'zabbix';
mysql> grant all PRIVILEGES on *.*to'root'@'%'IDENTIFIED BY'zabbix@zabbix'WITHGRANTOPTION;
mysql> grant all PRIVILEGES on *.*to'zabbix'@'%'IDENTIFIEDBY'zabbix'WITHGRANTOPTION;
mysql> flush privileges;
mysql> show databases;
ZABBIX 高可用数据库复制配置
ZABBIX-DB1 my.cnf 配置文件
-----------------------------------------------------------------------
代码语言:javascript复制[mysqld]
#开启二进制日志
log-bin=mysql-bin
log-bin=/mariadb/binlogs/mysql-bin
#id标识唯一
server-id=82
#不同步的数据库,可设置多个
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=mysql
#指定需要同步的数据库(和slave是相互匹配的),可以设置多个
binlog-do-db=zabbix
replicate-do-db=zabbix
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60
###设置存储模式不设置默认
binlog_format=MIXED
#####日志清理时间
expire_logs_days=7
#####日志大小
max_binlog_size=100m
#####缓存大小
binlog_cache_size=4m
#####最大缓存大小
max_binlog_cache_size=512m
-----------------------------------------------------------------------
ZABBIX-DB2 my.cnf 配置文件
-----------------------------------------------------------------------
代码语言:javascript复制[mysqld]
#开启二进制日志
log-bin=mysql-bin
log-bin=/mariadb/binlogs/mysql-bin
#id标识唯一
server-id=89
#不同步的数据库,可设置多个
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=mysql
#指定需要同步的数据库(和slave是相互匹配的),可以设置多个
binlog-do-db=zabbix
replicate-do-db=zabbix
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60
###设置存储模式不设置默认
binlog_format=MIXED
#####日志清理时间
expire_logs_days=7
#####日志大小
max_binlog_size=100m
#####缓存大小
binlog_cache_size=4m
#####最大缓存大小
max_binlog_cache_size=512m
-----------------------------------------------------------------------
两个数据库除server-id 外其他配置相同
修改完配置,重启数据库
代码语言:javascript复制systemctl restart mariadb
ZABBIX-DB2数据库数据导入
由于主库ZABBIX Server 已经在使用,从库需要导入主库的zabbix表项和数据(保证主从数据库表结构和数据相同),使用mysqldump对主库数据进行备份,从库进行导入
主数据库操作
代码语言:javascript复制mysqldump -uzabbix -pzabbix@zabbix zabbix > /opt/zabbix.sql
[root@ZABBIX-DB1opt]# mysqldump -uroot -proot@centos zabbix > /opt/zabbix.sql
[root@ZABBIX-DB1opt]# ll
total 93988
-rw-r--r--. 1 root root 96240019 Mar 26 13:06 zabbix.sql
备数据库操作
代码语言:javascript复制[root@ZABBIX-DB2opt]# scp root@21.254.248.82:/opt/zabbix.sql /opt/
[root@ZABBIX-DB2opt]# ls
zabbix.sql
[root@ZABBIX-DB2opt]# mysql -uzabbix-pzabbixt@zabbix
MariaDB [(none)]> use zabbix;
MariaDB[zabbix]>source /opt/zabbix.sql
ZABBIX-DB2 上查看数据导入
查看zabbix数据有多少张表,验证从数据库数据导入是否成功
代码语言:javascript复制SELECT COUNT(*) TABLES, table_schema FROM information_schema.TABLES where table_schema ='zabbix';
ZABBIX-DB1数据库同步账户授权配置
代码语言:javascript复制#主从同步用户授权
grant replication slave on *.* to 'zabbixslave'@'21.254.248.89' identified by 'zabbixslave' ;
#查看是否修改成功
select host,user,password from mysql.user;
#刷新
flush privileges;
#查看主库信息
show master status;
注意:由于Position值会不断发生变化,
Slave在进行数据同步是需要锁表操作;
flushtables with read lock; (会话关闭后自动解锁)
unlocktables;当前会话解锁;
ZABBIX-DB2数据库同步配置
代码语言:javascript复制#关闭Slave
stop slave;
#设置连接主库信息
change master to master_host='21.254.248.82', master_user='zabbixslave',
master_password='zabbixslave', master_log_file='mysql-bin.000002',master_log_pos= 83829956;
#开启Slave
start slave;
注:上面的master_log_file是在配置Master的时候的File字段, master_log_pos是在配置Master的Position字段。 Master上使用show master status; 查看;一定要一一对应(不要忘记对matster进行锁表)
#查看信息
代码语言:javascript复制show slave status G;
stopslave;//停止
resetslave; //清空
startslave;//开启
ZABBIX-DB2数据库同步账户授权配置
代码语言:javascript复制#主从同步用户授权
grant replication slave on *.* to 'zabbixslave'@'21.254.248.82'identified by 'zabbixslave' ;
#查看是否修改成功
select host,user,password from mysql.user;
#刷新
flush privileges;
#查看主库信息
show master status;
代码语言:javascript复制注意:由于Position值会不断发生变化, Slave在进行数据同步是需要锁表操作;
flush tables with read lock; (会话关闭后自动解锁)
unlock tables;当前会话解锁;
ZABBIX-DB1数据库同步配置
代码语言:javascript复制#关闭Slave
stopslave;
#设置连接主库信息change master to master_host='21.254.248.89', master_user='zabbixslave',master_password='zabbixslave', master_log_file='mysql-bin.000002',master_log_pos= 101228163;
#开启Slave
start slave;
代码语言:javascript复制注:上面的master_log_file是在配置Master的时候的File字段, master_log_pos是在配置Master的Position字段。 Master上使用show master status; 查看;一定要一一对应(不要忘记对matster进行锁表)
#查看信息
show slave status G;
stop slave;//停止
reset slave; //清空
start slave;//开启
keepalived介绍
keepalived是集群管理中保证集群高可用的一个软件解决方案,其功能类似于heartbeat,用来防止单点故障
keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。
虚拟路由冗余协议,可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip,master会发组播(组播地址为224.0.0.18),当backup收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master,这样的话就可以保证路由器的高可用了。
keepalived主要有三个模块,分别是core 、check和vrrp。core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。check负责健康检查,包括常见的各种检查方式。vrrp模块是来实现VRRP协议的。同时为了避免出现脑裂,应关闭防火墙或者开启防火墙但允许接收VRRP协议。
选举算法 keepalived中优先级高的节点为MASTER。MASTER其中一个职责就是响应VIP的arp包,将VIP和mac地址映射关系告诉局域网内其他主机,同时,它还会以多播的形式(目的地址224.0.0.18)向局域网中发送VRRP通告,告知自己的优先级。网络中的所有BACKUP节点只负责处理MASTER发出的多播包,当发现MASTER的优先级没自己高,或者没收到MASTER的VRRP通告时,BACKUP将自己切换到MASTER状态,然后做MASTER该做的事:1.响应arp包,2.发送VRRP通告。
MASTER和BACKUP节点的优先级如何调整? 首先,每个节点有一个初始优先级,由配置文件中的priority配置项指定,MASTER节点的priority应比BAKCUP高。运行过程中keepalived根据vrrp_script的weight设定,增加或减小节点优先级。规则如下:
- 当weight > 0时,vrrp_script script脚本执行返回0(成功)时优先级为priority weight, 否则为priority。当BACKUP发现自己的优先级大于MASTER通告的优先级时,进行主从切换。
- 当weight< 0时,vrrp_script script脚本执行返回非0(失败)时优先级为priority weight, 否则为priority。当BACKUP发现自己的优先级大于MASTER通告的优先级时,进行主从切换。
- 当两个节点的优先级相同时,以节点发送VRRP通告的IP作为比较对象,IP较大者为MASTER。
数据库服务监控脚本
注意:监控脚本的权限 755
-----------------------------------------------------------------------
代码语言:javascript复制[root@ZABBIX-DB1keepalived]# more chkmysql.sh
#!/bin/bash
mysqld=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)
if [ "${mysqld}" -eq 0 ];then
systemctl stop keepalived
killall keepalived
fi
ping 21.254.248.82 -w1 -c1 &>/dev/null
if [ $? -ne 0 ]; then
systemctl stop keepalived
killall keepalived
fi
代码语言:javascript复制[root@ZABBIX-DB2keepalived]# more chkmysql.sh
#!/bin/bash
mysqld=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)
if [ "${mysqld}" -eq 0 ];then
systemctl stop keepalived
killall keepalived
fi
ping 21.254.248.89 -w1 -c1 &>/dev/null
if [ $? -ne 0 ]; then
systemctl stop keepalived
killall keepalived
fi
keepalived配置
ZABBIX-DB1 keepalived配置
代码语言:javascript复制[root@ZABBIX-DB1keepalived]# more keepalived.conf
!Configuration File for keepalived
global_defs{
router_id lvs-mysql01
}
vrrp_script chkmysql
{
script"/etc/keepalived/chkmysql.sh"
fall 2
rise 2
}
vrrp_instance mysql-ha {
state MASTER
interface ens33
virtual_router_id 100
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress{
21.254.248.121
}
track_script{
chkmysql
}
}
ZABBIX-DB2 keepalived配置
代码语言:javascript复制[root@ZABBIX-DB2keepalived]# more keepalived.conf
!Configuration File for keepalived
global_defs{
router_id lvs-mysql02
}
vrrp_scriptchk mysql
{
script "/etc/keepalived/chkmysql.sh"
fall 2
rise 2
}
vrrp_instance mysql-ha {
state BACKUP
interface ens33
virtual_router_id 100
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress{
21.254.248.121
}
track_script{
chkmysql
}
}
ZABBIX 数据库高可用切换验证
ZABBIX-DB1网卡VIP为21.254.248.121,执行systemctl stop mariadb后,执行chkmysql.sh 脚本stopkeepalived服务,在ZABBIX-DB2 验证VIP迁移到ZABBIX-DB2。
ZABBIX数据库回切
ZABBIX-DB1服务确认顺序
启动本地数据库
启动keepalived
代码语言:javascript复制[root@ZABBIX-DB1/]# systemctl start mariadb
[root@ZABBIX-DB1/]# systemctl start keepalived
查看ip address show ,ip vip address 完成回切
ZABBIX 数据库备份 定期清理
ZABBIX数据库定期备份脚本
代码语言:javascript复制[root@ZABBIX-DB2]# more bkzabbix.sh
#!/bin/bash
/usr/bin/mysqldump-uzabbix -pzabbix zabbix | gzip > /mysql-backup/zabbix_$(date %Y%m%d_%H%M%S).sql.gz
[root@ZABBIX-DB2mysql-backup]# ./bkzabbix.sh
[root@ZABBIX-DB2mysql-backup]# ls
bkzabbix.sh zabbix_20190327_155247.sql.gz
ZABBIX数据库定期清理脚本
代码语言:javascript复制[root@DC-2mysql-backup]# more rmysql.sh
#!/bin/bash
find /mysql-backup -name zabbix"*.sql.gz" -type f -mtime 20 -exec rm-rf {} ; > /dev/null 2>&1
添加计划任务
代码语言:javascript复制root@ZABBIX-DB2mysql-backup]# crontab -l
*/10* * * * root /usr/sbin/ntpdate 21.254.248.81;/sbin/hwclock -w
30 11 * * * /mysql-backup/bkzabbix.sh
30 11 * * * /mysql-backup/rmysql.sh
[root@ZABBIX-DB2mysql-backup]# systemctl restart crond
以上文章来源于有故事的宋师傅,作者songhongpeng