keepalived工作原理_Mysql+Keepalived高可用最佳配置实践
01背景简介MySQL是一个小型关系型数据库,性能方面存在先天性不足,尽管如此,其也因为开源、免费、可自主迭代研发、总体拥有成本低等诸多优点被广大企业使用。目前业界有许多方法可以降低MySQL性能上限不足问题,软件层面可通过数据库中间件解决(如MyCAT、DRDS等),架构层面可以通过业务解耦、冷热温数据分离存储等方式,降低高并发业务对MySQL数据库的冲击。尽管如此,但在MySQL实例...
MySQL是一个小型关系型数据库,性能方面存在先天性不足,尽管如此,其也因为开源、免费、可自主迭代研发、总体拥有成本低等诸多优点被广大企业使用。目前业界有许多方法可以降低MySQL性能上限不足问题,软件层面可通过数据库中间件解决(如MyCAT、DRDS等),架构层面可以通过业务解耦、冷热温数据分离存储等方式,降低高并发业务对MySQL数据库的冲击。尽管如此,但在MySQL实例规模较多时,通过合理规划MySQL配置,一是可以确保降低高并发业务冲击数据库导致的数据库宕机风险,二是可以最大化的利用服务器资源,以节约企业资源投入成本,三是通过统一标准化的配置可以较大程度降低自动化运维研发投入成本。
本文重点针对MySQL+Keepalived高可用架构进行讲解,包含MySQL配置、Keepalived高可用配置,并附带有相应的VIP切换监控脚本。
02 实现原理Mysql中Master->Slave的主主同步。主主是数据双向同步,主从是数据单向同步。一般情况下,主库宕机后,需要手动将连接切换到从库上。但如果使用keepalived组件架构可实现自动切换,保证数据库的高可用性。
在MySQL双主结构当中,使用keepalived,通过VIP实现Mysql双主对外连接的统一接口。即客户端通过Vip连接数据库;保障其中某一台主机出现故障,无法提供服务时,VIP可自动漂移到另一台主机上,整个过程对于客户端接来说几乎无感觉,从而实现高可用。
为保障MySQL数据的一致性,必须避免VIP频繁漂移。当keepalived检测发现MySQL服务工作异常时,VIP漂移,为禁止VIP出现二次漂移,必须人工介入操作,从而保障数据的一致性及安全性。所以,在MySQL+keepalived使用过程中,master和slave两节点均设置为backup,当人工介入,对故障主机处理完毕之后,重新启动keepalived,不会出现VIP漂移的情况,只有仅当keepalived检测到MySQL无法提供服务,才会执行VIP漂移。
03 安装实施Mysql安装部署:
软件信息
软件名称 | 版本号 |
MySQL | MySQL官方社区5.7 |
主机参数调整:
禁用selinux
#vi/etc/sysconfig/selinux
查看是否SELINUX=disabled
关闭numa
#vi/etc/default/grub
在GRUB_CMDLINE_LINUX这一行最后添加numa=off,使其变为GRUB_CMDLINE_LINUX=”crashkernel=auto…… rhgb quiet numa=off”,变更完成后保存退出。
#grub2-mkconfig -o /boot/grub2/grub.cfg
文件数进程数限制
#vi /etc/security/limits.conf
添加mysql用户限制如下:
mysqlsoft nproc 65535
mysql hard nproc 65535
mysql soft nofile65536
mysql hard nofile 65536
#vi/etc/sysctl.conf将该配置文件内容清空,改成以下内容
vm.swappiness=0
net.ipv6.conf.all.disable_ipv6=1
net.core.somaxconn=65535
net.core.netdev_max_backlog=65535
net.ipv4.tcp_max_syn_backlog=65535
net.ipv4.tcp_fin_timeout=10
net.ipv4.tcp_tw_reuse=1
#netipv4.tcp_tw_recycle=1
net.core.wmem_default=87380
net.core.wmem_max=16777216
net.core.rmem_default=87380
net.core.rmem_max=16777216
net.ipv4.tcp_keepalive_time=120
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=3
net.ipv4.ip_local_port_range= 40000 60000
kernel.sem = 250 32000 100 128
创建mysql用户:
#groupadd mysql
#useradd -g mysql -m mysql
依赖包安装:
软件安装前需检查以下依赖包,将缺少的依赖包安装。
#rpm-q gcc gcc-c++ zlib-devel pcre-devel readline readline-develbzip2-devel rpm-build \kernel-devel libaio-develelfutils-libelf-devel compat-libstdc++-33 compat-libcap1 cmake bisonautomake ncurses-devel xinetd openssl-devel |grep "notinstalled"
软件安装:
#cd/opt
#tar –xzvf mysql-version-os.tar.gz
#cdmysql-version-os
#cmake .-DCMAKE_INSTALL_PREFIX=/opt/mysql-version\
-DWITH_BOOST=boost/boost_1_59_0 \
-DDEFAULT_CHARSET=utf8mb4\
-DDEFAULT_COLLATION=utf8mb4_bin
# make&&makeinstall
建立软链接:
#ln-s /opt/mysql-version-os /usr/local/mysql
#ln -s/usr/local/mysql/bin/* /usr/local/bin
初始化数据库,MySQL数据目录:
实例要创建在/data/mysql下,实例中目录的具体划分如下:
主目录 | 二级目录 | 三级目录 |
/data/mysql/db_insname | bin(启动脚本目录) | login.sh |
shutdown.sh | ||
startup.sh | ||
blog | mysql-bin.* | |
mysql-bin.index | ||
conf(配置文件目录) | init_file.sql | |
insname.cnf | ||
data(数据目录) | ||
elog(慢日志、错误日志) | mysql.err | |
slow.log | ||
mysql.pid | ||
mysql.sock | ||
mysql.sock.lock | ||
nohup.out | ||
rlog(表空间目录) | ib_logfile0 | |
ib_logfile1 | ||
ib_logfile2 | ||
tmp(临时目录) | ||
ulog(undo表空间目录) | undo001 | |
undo002 |
配置参数说明:
参数名 | 数值 | 配置说明 |
max_connections | 5000 | 数据库中已连接的所有用户总数不超过5000 |
max_user_connections | 1200 | 单个用户最大连接数不超过1200 |
connect_timeout | 10 | 建立数据库连接时不允许超过十秒 |
wait_timeout | 600 | 状态为sleep的线程超过600秒会被关闭 |
max_execution_time | 10000 | 执行时间超过10000毫秒的sql语句会被终止 |
innodb_lock_wait_timeout | 10 | 事务中的DML语句10秒未获得锁,会回滚整个事务 |
sql_safe_updates | 1 | 使用update或delete必须用where条件且使用索引 |
loose_rpl_semi_sync_master_enabled | on | 开启半同步 |
loose_rpl_semi_sync_master_timeout | 1000 | 客户端等待1秒得不到确认变为异步 |
loose_rpl_semi_sync_master_wait_for_slave_count | 1 | 主库收到1个从库写成功则返回客户端 |
loose_rpl_semi_sync_master_wait_no_slave | on | 启动备库后进入半同步模式 |
log_queries_not_using_indexes | 1 | 查询不使用索引会计入慢日志 |
secure_file_priv | /data/mysql/db_insname/tmp | 在库中提取数据的数据存放路径 |
实例创建:
setserver.ini配置文件
10.10.1.133 /usr/local/mysql /data/mysql db test1 3306 11 root 123456 512M |
setServer_57.sh配置文件
#!/bin/bash
#目录、端口、实例名等信息的配置文件
INI_CFG=./setServer.ini
#IP
IP=""
#软件目录
SOFTDIR=""
#根目录
BASE_DIR=""
#实例名
INS_NAME=""
#实例名前缀
INS_NAME_PRE=""
#实例端口
INS_PORT=""
#server id
SERVER_ID=""
#实例根目录
INS_BASE_DIR=""
#管理员用户
ADMIN_USER=""
#管理员密码
ADMIN_PASSWD=""
#实例参数文件
INS_CNF=""
#初始化SQL文件
INIT_FILE=""
#INNODB_BUFFER_POOL_SIZE设定
BUFFER_POOL=""
function Isok()
{
[ $? == "0" ] && echo "Complete OK !" || echo " Failed !!!";exit 128
}
#创建实例函数
function create_instance()
{
#1、创建实例相应目录
mkdir -p ${INS_BASE_DIR}/{bin,conf,data,rlog,ulog,blog,elog,tmp}
chmod -R 755 ${INS_BASE_DIR}
echo "****** 1、创建目录:"
echo " 启动脚本目录:${INS_BASE_DIR}/bin"
echo " 配置文件目录:${INS_BASE_DIR}/conf"
echo " 数据目录:${INS_BASE_DIR}/data"
echo " relog目录:${INS_BASE_DIR}/rlog"
echo " ulog目录:${INS_BASE_DIR}/ulog"
echo " blog目录:${INS_BASE_DIR}/blog"
echo " elog目录:${INS_BASE_DIR}/elog"
echo " 临时目录:${INS_BASE_DIR}/tmp"
#2、生成参数文件
cat <${INIT_FILE}
set global sql_safe_updates=1;
EOF
cat <${INS_CNF}
[mysqld]
#************** basic ***************
datadir =${INS_BASE_DIR}/data
basedir =${SOFTDIR}
tmpdir =${INS_BASE_DIR}/tmp
secure_file_priv =${INS_BASE_DIR}/tmp
port =${INS_PORT}
socket =${INS_BASE_DIR}/mysql.sock
pid_file =${INS_BASE_DIR}/mysql.pid
#************** connection ***************
max_connections =5000
max_connect_errors =100000
max_user_connections =1200
#************** sql timeout & limits ***************
max_execution_time =10000
group_concat_max_len =1048576
lock_wait_timeout =60
#autocommit =0
lower_case_table_names =1
thread_cache_size =64
disabled_storage_engines ="MyISAM,FEDERATED"
character_set_server =utf8
transaction-isolation ="READ-COMMITTED"
skip_name_resolve =ON
explicit_defaults_for_timestamp =ON
log_timestamps =SYSTEM
local_infile =OFF
event_scheduler =OFF
query_cache_type =OFF
query_cache_size =0
lc_messages =en_US
lc_messages_dir =${SOFTDIR}/share
init_connect ="set names utf8"
#sql_mode =NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO
init_file =${INIT_FILE}
#init_slave
#******************* err & slow & general ***************
log_error =${INS_BASE_DIR}/elog/mysql.err
#log_output ="TABLE,FILE"
slow_query_log =ON
slow_query_log_file =${INS_BASE_DIR}/elog/slow.log
long_query_time =1
log_queries_not_using_indexes =0
log_throttle_queries_not_using_indexes = 10
general_log =OFF
general_log_file =${INS_BASE_DIR}/elog/general.log
#************** binlog & relaylog ***************
expire_logs_days =7
sync_binlog =1
log-bin =${INS_BASE_DIR}/blog/mysql-bin
log-bin-index =${INS_BASE_DIR}/blog/mysql-bin.index
max_binlog_size =500M
binlog_format =ROW
binlog_rows_query_log_events =ON
binlog_cache_size =2M
binlog_stmt_cache_size =2M
max_binlog_cache_size =512M
max_binlog_stmt_cache_size =512M
relay_log =${INS_BASE_DIR}/blog/relay
relay_log_index =${INS_BASE_DIR}/blog/relay.index
max_relay_log_size =500M
relay_log_purge =ON
relay_log_recovery =ON
#*************** rpl_semi_sync ***************
loose_rpl_semi_sync_master_enabled =ON
loose_rpl_semi_sync_master_timeout =1000
loose_rpl_semi_sync_master_trace_level =32
loose_rpl_semi_sync_master_wait_for_slave_count =1
loose_rpl_semi_sync_master_wait_no_slave =ON
loose_rpl_semi_sync_master_wait_point =AFTER_SYNC
loose_rpl_semi_sync_slave_enabled =ON
loose_rpl_semi_sync_slave_trace_level =32
#*************** group commit ***************
binlog_group_commit_sync_delay =1
binlog_group_commit_sync_no_delay_count =1000
#*************** gtid ***************
gtid_mode =ON
enforce_gtid_consistency =ON
master_verify_checksum =ON
sync_master_info =1
#*************slave ***************
skip-slave-start =1
#read_only =ON
#super_read_only =ON
log_slave_updates =ON
server_id =${SERVER_ID}
report_host =$IP
report_port =${INS_PORT}
slave_load_tmpdir =${INS_BASE_DIR}/tmp
slave_sql_verify_checksum =ON
slave_preserve_commit_order =1
#*************** muti thread slave ***************
slave_parallel_type =LOGICAL_CLOCK
slave_parallel_workers =4
master_info_repository =TABLE
relay_log_info_repository =TABLE
#*************** buffer & timeout ***************
read_buffer_size =1M
read_rnd_buffer_size =2M
sort_buffer_size =1M
join_buffer_size =1M
tmp_table_size =16777216
max_allowed_packet =64M
max_heap_table_size =64M
connect_timeout =10
wait_timeout =600
interactive_timeout =600
net_read_timeout =30
net_write_timeout =30
#*********** myisam ***************
skip_external_locking =ON
key_buffer_size =2M
bulk_insert_buffer_size =16M
concurrent_insert =ALWAYS
open_files_limit =65000
table_open_cache =16000
table_definition_cache =16000
#*********** innodb ***************
default_storage_engine =InnoDB
default_tmp_storage_engine =InnoDB
internal_tmp_disk_storage_engine =InnoDB
innodb_data_home_dir =${INS_BASE_DIR}/data
innodb_log_group_home_dir =${INS_BASE_DIR}/rlog
innodb_log_file_size =1024M
innodb_log_files_in_group =3
innodb_undo_directory =${INS_BASE_DIR}/ulog
innodb_undo_log_truncate =on
innodb_max_undo_log_size =1024M
innodb_undo_tablespaces =3
innodb_flush_log_at_trx_commit =2
innodb_fast_shutdown =1
innodb_flush_method =O_DIRECT
innodb_io_capacity =1000
innodb_io_capacity_max =4000
innodb_buffer_pool_size =${BUFFER_POOL}
innodb_log_buffer_size =8M
innodb_autoinc_lock_mode =1
innodb_buffer_pool_load_at_startup =ON
innodb_buffer_pool_dump_at_shutdown =ON
innodb_buffer_pool_dump_pct =15
innodb_max_dirty_pages_pct =85
innodb_lock_wait_timeout =10
#innodb_locks_unsafe_for_binlog =1
innodb_old_blocks_time =1000
innodb_open_files =63000
innodb_page_cleaners =4
innodb_strict_mode =ON
innodb_thread_concurrency =0
innodb_sort_buffer_size =64M
innodb_print_all_deadlocks =1
innodb_rollback_on_timeout =ON
EOF
echo "****** 2、生成参数文件:"
echo " 实例${INS_NAME}的参数文件: ${INS_CNF}"
# 3、实例化数据库
echo "****** 3、初始化数据库:"
#[ `echo $USER` == "root" ] && chown mysql:root $INS_BASE_DIR
${SOFTDIR}/bin/mysqld --defaults-file=${INS_CNF} \
--initialize-insecure --user=mysql \
--basedir=${SOFTDIR} \
--datadir=${INS_BASE_DIR}/data
#4、生成启动、关闭、登陆脚本
echo "****** 4、生成启动、关闭、登陆脚本:"
cat <${INS_BASE_DIR}/bin/startup.sh
#!/bin/bash
source /etc/profile
source ~/.bash_profile
export UMASK=0644
export UMASK_DIR=0750
## vars
SOFTDIR=${SOFTDIR}
DBHOME=${INS_BASE_DIR}
DBNAME=${INS_NAME}
CNF=\${DBHOME}/conf/\${DBNAME}.cnf
DATADIR=\${DBHOME}/data
## startup
nohup \${SOFTDIR}/bin/mysqld_safe --defaults-file=\${CNF} --ledir=\${SOFTDIR}/bin >\${DBHOME}/nohup.out 2>&1 &
EOF
cat <${INS_BASE_DIR}/bin/shutdown.sh
#!/bin/bash
source /etc/profile
source ~/.bash_profile
## vars
SOFTDIR=${SOFTDIR}
DBHOME=${INS_BASE_DIR}
DBNAME=${INS_NAME}
CNF=\${DBHOME}/conf/\${DBNAME}.cnf
SOCK=\${DBHOME}/mysql.sock
## shutdown
\${SOFTDIR}/bin/mysqladmin --defaults-file=\${CNF} -uroot -p -S\${SOCK} shutdown
EOF
cat <${INS_BASE_DIR}/bin/login.sh
SOFTDIR=${SOFTDIR}
DBHOME=${INS_BASE_DIR}
DBNAME=${INS_NAME}
SOCK=\${DBHOME}/mysql.sock
\${SOFTDIR}/bin/mysql -uroot -p -S\${SOCK} -A
EOF
chmod 700 ${INS_BASE_DIR}/bin/startup.sh ${INS_BASE_DIR}/bin/shutdown.sh ${INS_BASE_DIR}/bin/login.sh
#5、修改管理员密码
echo "****** 5、修改管理员密码:"
hostname=`hostname`
sh ${INS_BASE_DIR}/bin/startup.sh
sleep 30
${SOFTDIR}/bin/mysql -uroot -S${INS_BASE_DIR}/mysql.sock<
#install semi sync
install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
install plugin rpl_semi_sync_master soname 'semisync_master.so';
#root
alter user 'root'@'localhost' identified by "${ADMIN_PASSWD}";
delete from mysql.user where user='root' and host=lower("${hostname}");
#备份用户
GRANT SELECT,SHOW VIEW,TRIGGER,LOCK TABLES,RELOAD,PROCESS,SUPER ON *.* TO 'bkpuser'@'%' IDENTIFIED BY "n#CJ^f&i";
#复制用户
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replic'@'%' IDENTIFIED BY "4%REplic";
#业务数据监控用户
create user monitorjk identified by 'esEYq7QWkB6F2M$';
#数据库监控用户
grant PROCESS, REPLICATION CLIENT, SELECT on *.* to zabbixjk identified by 'CvNYz!6WIb9u';
#4A用户
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, ALTER, SHOW DATABASES, CREATE USER ,RELOAD ON *.* TO aiuap@'%' IDENTIFIED BY "p#1nVF.|c1" WITH GRANT option;
#运维管理用户
GRANT ALL ON *.* TO myrobot@'127.0.0.1' identified by 'Si*hx79*HIqHQdLY' with grant option;
#inception用户
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, PROCESS, INDEX, ALTER, SUPER, REPLICATION SLAVE, REPLICATION CLIENT, TRIGGER ON *.* TO inception identified by 'fF&w@tw5qZK1WRvi';
flush privileges;
shutdown;
EOF
[ $? == "0" ] && echo " 密码修改成功!"
#修改配置文件,使半同步参数生效
sleep 5
sed -i 's/loose_//g' ${INS_CNF}
sh ${INS_BASE_DIR}/bin/startup.sh
echo "****** 6、网络监听:"
netstat -pltn 2>/dev/null |grep -E "Proto|$INS_PORT|mysql"
echo "****** 7、MySQL错误日志:"
grep -Ei "error|warning" $INS_BASE_DIR/elog/mysql.err
}
if [ -f ${INI_CFG} ]; then
grep -v "^#" ${INI_CFG} | while read line
do
IP=`echo ${line} | cut -d" " -f1`
SOFTDIR=`echo ${line} | cut -d" " -f2 | sed 's/\/$//'`
BASE_DIR=`echo ${line} | cut -d" " -f3 | sed 's/\/$//'`
INS_NAME_PRE=`echo ${line} | cut -d" " -f4`
INS_NAME=`echo ${line} | cut -d" " -f5`
INS_PORT=`echo ${line} | cut -d" " -f6`
SERVER_ID=`echo ${line} | cut -d" " -f7`
ADMIN_USER=`echo ${line} | cut -d" " -f8`
ADMIN_PASSWD=`echo ${line} | cut -d" " -f9`
BUFFER_POOL=`echo ${line} | cut -d" " -f10`
INS_BASE_DIR=${BASE_DIR}/${INS_NAME_PRE}_${INS_NAME}
INS_CNF=${INS_BASE_DIR}/conf/${INS_NAME}.cnf
INIT_FILE=${INS_BASE_DIR}/conf/init_file.sql
echo "****** 实例${INS_NAME}信息: ******"
echo " IP: ${IP}"
echo " 软件目录: ${SOFTDIR}"
echo " 根目录: ${BASE_DIR}"
echo " 实例根目录: ${INS_BASE_DIR}"
echo " 实例名前缀: ${INS_NAME_PRE}"
echo " 实例名: ${INS_NAME}"
echo " 实例端口: ${INS_PORT}"
echo " server_id: ${SERVER_ID}"
echo " 管理员用户: ${ADMIN_USER}"
echo " 管理员密码: ${ADMIN_PASSWD}"
echo " INNODB_BUFFER_POOL_SIZE设定: ${BUFFER_POOL}"
if [ `echo ${line} | awk '{print NF}'` != "10" ]; then
echo "ERROR:创建实例相应参数不够!"
echo "##############################################################################################"
echo -e "\n"
#判断端口与ibdata01文件是否存在,都不存在则创建实例。存在一个则创建失败
elif [ X"`netstat -ltn | grep ${INS_PORT}`" = X"" ] && [ ! -f ${INS_BASE_DIR}/data/ibdata01 ]; then
#调用创建实例函数
create_instance;
else
echo "ERROR:端口${INS_PORT}或${INS_BASE_DIR}/data/ibdata01文件存在,创建实例失败!"
echo "##############################################################################################"
echo -e "\n"
fi
done
else
echo "ERROR:${INI_CFG}配置文件不存在!"
exit 1
fi
数据库的初始化使用上面两个脚本完成。
1.填写setserver.ini配置文件。
2.执行setserver.sh,初使化数据库。
setserver.ini,填写方法如下:
序列 | 名称 | 示例 |
第1列 | ip | 0.0.0.1 |
第2列 | 软件目录 | /usr/local/mysql |
第3列 | 数据根目录 | /data/mysql |
第4列 | 实例名前缀 | Db |
第5列 | 实例名 | Insname |
第6列 | 端口 | 20001 |
第7列 | serverid(如果有两个节点,serverid不能一样,一个写01一个写02) | port+01/port+02 |
第8列 | root账号 | Root |
第9列 | root密码 | Root |
setserver.sh
用mysql用户执行脚本完成数据库实例初始化。
登录数据库
数据库登录脚本在/data/mysql/db_InsName/bin下,login.sh。
04 主主复制复制方式:半同步、主主复制
操作步骤:
登陆节点1:
步骤 | 操作 | 解释 |
1 | mysql>RESET MASTER; | 重置 |
2 | mysql>CHANGE MASTER TO | 配置主主 |
3 | mysql>START SLAVE; | 启动服务 |
登陆节点2:
步骤 | 操作 | 解释 |
1 | mysql>RESET MASTER; | 重置 |
2 | mysql>CHANGE MASTER TO | 配置主主 |
3 | mysql>START SLAVE; | 启动服务 |
集群中的每一个MySQL实例都单独部署在一个物理机,考虑到容错和网络环境尽量实现跨机柜部署。
禁止集群的一对主从部署在同一台物理机。
MySQL不应和高磁盘I/O,高计算任务的应用部署在同一台物理机上
软件名称 | 版本号 |
Keepalived | Keepalived-1.3.2 |
安装目录规范:
软件安装目录:/usr/local/keepalived
日志输出目录:/usr/local/keepalived/log/keepalived.log
配置文件目录:/etc/keepalived/keepalived.conf
检测脚本目录:/etc/keepalived/scripts/
参数文件目录:/etc/sysconfig/keepalived
执行文件目录:/usr/sbin/keepalived
启动文件目录:/etc/rc.d/init.d/keepalived
源码存放目录:/tmp/keepalived-1.3.2/
keepalived安装:
检测依赖包:
在root用户权限下执行:
rpm-qa make gcc libpopt-dev libnl-dev libcurl4-openssl-dev | grep "notinstall"
查看是否存在未安装的依赖包。(注意:当操作系统语言为中文时需注意,notinstall筛选不出结果,可自行查看是否存在对应依赖包。)
如果存在未安装的依赖包,则对缺失的依赖包进行安装。
解压缩编译:
tar zxf keepalived-1.3.2.tar.gz,进入目录并编译
在编译过程中,只需要执行安装目录,其他使用默认配置即可。
./configure –prefix=/usr/local/keepalived
make && make install
所需文件创建:
在keepalived1.3.2中,部分系统所需使用的脚本文件在源码安装包中,即脚本存在位置为:/tmp/keepalived-1.3.2/keepalived/etc。
复制可执行文件:
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
复制系统服务文件:
cp/tmp/keepalived-1.3.2/keepalived/etc/init.d/keepalived /etc/rc.d/init.d/
复制参数文件:
cp/usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
创建配置文件/脚本文件目录:
mkdir -p /etc/keepalived/scripts
修改文件目录权限:
将以下目录用户及所属组该为mysql
/etc/keepalived
/usr/local/keepalived
chown -R mysql:mysql /etc/keepalived
chown -R mysql:mysql /usr/local/keepalived
修改日志输出:
1、修改keepalived启动参数文件
vi /etc/sysconfig/keepalvied
将文件中KEEPALIVED_OPTIONS=”-D”修改为:
KEEPALIVED_OPTIONS=”-D -d -S 0”
2、修改rsyslog.conf文件
vi /etc/rsyslog.conf
在文件最后增加一行:
local0.* /usr/local/keepalived/log/keepalived.log
3、重启rsyslog服务
systemctl restart rsyslog
配置keepalived:
keepalived配置文件及说明
参数说明:
参数名 | 配置说明 |
vrrp_script块 | keepalived调用检测脚本块 |
script | 检测脚本文件指定 |
ineerval | 检测脚本调用周期 |
vrrp_instance块 | keepalivd配置块 |
state | keepalived角色状态,只有MASTER和BACKUP两种,必须使用大写 |
interface | keepalived实例绑定网卡 |
virtual_router_id | 实例ID,用于主备之间互通,主备必须相同,值范围:0-255 |
priority | 权重值 |
advert_int | keepalived之间心跳检测时间间隔 |
nopreempt | 设置不抢占 |
track_script | 选择检测脚本块 |
authentication | 认证设置 |
auth_type | 认证方式 |
auth_pass | 认证密码,最大不可超过8位 |
virtual_ipaddress | 设置服务IP |
vrrp_garp_master_refresh | Master发一次ARP包到网关的间隔时间,可以防止产生脑裂 |
配置文件展示:
global_defs {
vrrp_garp_master_refresh10 #Master间隔10s发一次ARP包到网关
}
vrrp_scriptcheck_run {
script"/etc/keepalived/scripts/keepalived_check_mysql.sh"#
需手工修改文件中的mysql端口号
interval30
weight0
}
vrrp_instanceVI_1 {
stateBACKUP
interfaceteam0 # 网卡,根据实际情况填写
virtual_router_id155 # 推荐使用虚IP第四段数字
priority101
advert_int1
authentication{
auth_typePASS
auth_pass1111
}
virtual_ipaddress{
0.0.0.1 # 虚IP
}
track_script{
check_run
}
notify_master/etc/keepalived/scripts/notify_master.sh
}
Keepalived手动切换操作方案:
mysql数据库VIP切换操作步骤 | ||||
序号 | 主任务 | 子任务 | 操作节点 | 操作命令 |
1 | VIP切换前准备 | 检查数据库同步状态 | 主从节点 | show slave status\G |
2 | 检查数据库日志 | 主从节点 | tail -1000f /data/db_{实例名}/elog/mysql.err | |
3 | 检查keepalived状态 | 主从节点 | ps -ef |grep -i keepalived | |
4 | VIP切换阶段 | 设置read_only为on | 主节点 | set global read_only=on; |
5 | kill应用连接 | 主节点 | kill processid; | |
6 | 切换VIP | 主节点 | sudo systemctl stop keepalived | |
7 | 检查VIP是否切换成功 | 主从节点 | ip a | |
8 | 检查应用连接 | 主从节点 | show processlist; | |
9 | 检查同步状态 | 主从节点 | show slave status\G | |
10 | 设置read_only为off | 新主节点 | set global read_only=off; |
说明:为保障MySQL数据库数据的一致性,防止keepalived虚拟IP节点漂移次数过于频繁,在state中设置为双BACKUP,即主从均为BACKUP,此时,如果主机出现故障或宕机,从机检测到之后,接管VIP,并继续提供服务。主机恢复,仍不会争用VIP,直至下次从机出现故障宕机,VIP才会进行第二次漂移,恢复到原主机,继续提供服务。该设置避免频繁切换数据库节点,导致数据的不一致。
08 小结当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,而且切换的时间非常短,mysql双主复制,即互为Master-Slave(只有一个Master提供写操作),可以实现数据库服务器的热备,但是一个Master宕机后不能实现动态切换。使用Keepalived,可以通过虚拟IP,实现双主对外的统一接口以及自动检查、失败切换机制,基本不需要人工干预操作,从而实现MySQL数据库的高可用性。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)