跨云服务器厂商--低成本--实现--伪·灾备
1.背景说明
(网上找了点资料,下面是自己的一些浅见,有不当之处,恳请大家指出。技术交流,只为进步。)
主要场景 假设ip如下
1台 阿里云服务器 10.0.0.2
1台 华为云服务器 10.0.0.3
要求:部署服务,实现灾备双活。(重点不是云服务器做灾备。重点是 客户想要在这个环境上 模拟灾备双活实现)
正常解决方式:
- 数据库双主同步+keepalived
- 前后端连接 数据库 连接的是 keepalived提供的ip。
这总方式在内网很容易实现,多准备1个ip地址即可。
但是在云环境上,要么买云厂商的服务,要么自己做一个 伪·灾备。
思路如下:
- 前端nginx权重轮询反向代理两个后端。
- 两个后端分别连接相应的数据库。
- 数据库之间做双向同步。
- 文件存储类文件通过NFS进行同步。
特殊时期特殊环境的特殊手段。如果有其他选择,建议大家不要选择这个方式。
2.遇到的问题
(1)数据库双向同步(云服务器安全组 ——配置信任ip,两个ip允许所有端口互相访问)
10.0.0.2操作如下
依赖 yum install -y perl perl-devel yum -y install autoconf libaio 解压安装 tar xf mysql-5.6.37-linux-glibc2.12-x86_64.tar.gz mv mysql-5.6.37-linux-glibc2.12-x86_64 /usr/local/mysql-5.6 cd /usr/local/mysql-5.6/ groupadd mysql useradd -r -g mysql mysql chown -R mysql.mysql /usr/local/mysql-5.6/ 初始化 /usr/local/mysql-5.6/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql-5.6/ --datadir=/usr/local/mysql-5.6/data 配置文件 vim /etc/my.cnf [mysqld] basedir=/usr/local/mysql-5.6 datadir=/usr/local/mysql-5.6/data port=3306 server-id=1 log-bin=/usr/local/mysql-5.6/mysql-bin sync_binlog = 1 binlog_checksum = none binlog_format = mixed auto-increment-increment = 2 auto-increment-offset = 1 slave-skip-errors = all innodb_flush_log_at_trx_commit=2 sync_binlog=1000 transaction_isolation=READ-COMMITTED expire_logs_days=7 user=mysql socket = /tmp/mysql.sock character-set-server=utf8 skip-name-resolve lower_case_table_names=1 max_connections=5000 max_connect_errors=1000 max_allowed_packet=500M wait_timeout=1814400 slow_query_log=on long_query_time=2 slow_query_log_file=/usr/local/mysql-5.6/slow.log symbolic-links=0 [mysqld_safe] log-err=/usr/local/mysql-5.6/data/error.log pid-file=/usr/local/mysql-5.6/data/mysql.pid sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 开机启动 cp /usr/local/mysql-5.6/support-files/mysql.server /etc/init.d/mysql chkconfig mysql on 环境变量 [ `egrep mysql /etc/profile|wc -l` -eq 0 ] && echo 'export PATH=$PATH:/usr/local/mysql-5.6/bin' >> /etc/profile ;source /etc/profile 启动 service mysql start 同步账户,锁表只读,查看log-bin. mysql grant replication slave,replication client,select on *.* to slave@'10.0.0.3' identified by 'Slave@123'; flush privileges; flush tables with read lock; flush logs; show master status;
两台机器按照上述步骤完成操作。注意以下配置区别。
第二个 10.0.0.3 配置
[mysqld] basedir=/usr/local/mysql-5.6 datadir=/usr/local/mysql-5.6/data port=3306 server-id=2 log-bin=/usr/local/mysql-5.6/mysql-bin sync_binlog = 1 binlog_checksum = none binlog_format = mixed auto-increment-increment = 2 auto-increment-offset = 2 slave-skip-errors = all innodb_flush_log_at_trx_commit=2 sync_binlog=1000 transaction_isolation=READ-COMMITTED expire_logs_days=7 user=mysql socket = /tmp/mysql.sock character-set-server=utf8 skip-name-resolve lower_case_table_names=1 max_connections=5000 max_connect_errors=1000 max_allowed_packet=500M wait_timeout=1814400 slow_query_log=on long_query_time=2 slow_query_log_file=/usr/local/mysql-5.6/slow.log symbolic-links=0 [mysqld_safe] log-err=/usr/local/mysql-5.6/data/error.log pid-file=/usr/local/mysql-5.6/data/mysql.pid sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
grant replication slave,replication client,select on *.* to slave@'10.0.0.2' identified by 'Slave@123'; flush privileges; flush tables with read lock; flush logs; show master status;
单向同步
10.0.0.3同步10.0.0.2的数据
先查看10.0.0.2的logbin
再10.0.0.3 进入mysql中操作
unlock tables; stop slave; change master to master_host='10.0.0.2',master_user='slave',master_password='Slave@123',master_log_file='mysql-bin.000004',master_log_pos=120; start slave; show slave status\G;
10.0.0.2同步10.0.0.3的数据
再10.0.0.3上刷新log-bin
然会回到 10.0.0.2上如下操作
unlock tables; stop slave; change master to master_host='10.0.0.3',master_user='slave',master_password='Slave@123',master_log_file='mysql-bin.000004',master_log_pos=120; start slave; show slave status\G;
最后去验证下。其中一台创建 表,第二台查看表.建库建表语句如下,可以去尝试测试。
create database if not exists ywjiasql default character set utf8; grant all privileges on ywjiasql.* to "ywjiasql"@"%" identified by "ywjiasql"; flush privileges;
CREATE TABLE IF NOT EXISTS `runoob_tbl`( `runoob_id` INT UNSIGNED AUTO_INCREMENT, `runoob_title` VARCHAR(100) NOT NULL, `runoob_author` VARCHAR(40) NOT NULL, `submission_date` DATE, PRIMARY KEY ( `runoob_id` ))ENGINE=InnoDB DEFAULT CHARSET=utf8; desc runoob_tbl;
(2)nginx权重轮询配置
具体大家可以去看一下。这里选择一种展示
upstream soft_up{ ip_hash; server 10.0.0.2:19998 weight=1; server 10.0.0.3:19998 weight=1; }
(3)文件同步NFS
server端部署如下:
yum -y install nfs-utils rpcbind
vim /etc/sysconfig/nfs
cat /etc/sysconfig/nfs |grep -v ^# |grep -v ^$
修改了一些端口,添加信任,端口该不该问题都不大
LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769
RPCNFSDARGS=""
RPCMOUNTDOPTS=""
MOUNTD_PORT=892
STATDARG=""
STATD_PORT=1001
STATD_OUTGOING_PORT=2001
SMNOTIFYARGS=""
RPCIDMAPDARGS=""
RPCGSSDARGS=""
GSS_USE_PROXY="yes"
BLKMAPDARGS=""
vim /etc/exports
/usr/local/eli_file 10.0.0.3/32(insecure,rw,sync,no_subtree_check,no_root_squash)
exportfs -rv
systemctl start rpcbind
systemctl start nfs
systemctl enable rpcbind
systemctl enable nfs
客户端挂载操作如下:
yum -y install nfs-utils rpcbind showmount -e 10.0.0.2 mount -t nfs -o nolock,nfsvers=3,vers=3,soft,intr,bg,rw,rsize=32768,wsize=32768 10.0.0.2:/usr/local/soft_file /usr/local/soft_file
(4)服务启动。数据库停止,服务停止。数据库恢复,服务恢复。
写一个死循环脚本持续运行。简简单单实现一下。稍后会更新一版通用化点的这个脚本。
#!/bin/bash function print_info_log(){ echo -e "\e[1;35m INFO:$(date "+%Y-%m-%d %H:%M:%S") \e[0m $1." } function jar_pid_cmd(){ jar_pid=`ps -ef|grep eli-main-1.0|grep -v grep|awk '{print $2}'` kill -9 $jar_pid } function jar_start_cmd(){ start_jar="nohup java -jar /usr/local/springboot_eli/eli-main-1.0-SNAPSHOT.jar -Xms1024m -Xms3072m -XX:PermSize=512m -XX:MaxPermSize=1024m -XX:MaxNewSize=1024m --spring.profiles.active=eli --spring.config.additional-location=/usr/local/springboot_eli/ >>/usr/local/springboot_eli/eli.out 2 >&1 & " echo "$start_jar" | bash &>/dev/null } #死循环 aaaaa=1 while [ $aaaaa -eq 1 ] do mysql_status=`netstat -tnlp|grep 3306|wc -l` jar_status=`ps -ef|grep eli-main-1.0|grep -v grep |wc -l` #检测数据库关闭,获取jar包运行状态,运行的进行关闭 if [ $mysql_status -eq 0 ];then [ $jar_status -ne 0 ] && jar_pid_cmd || print_info_log "已关闭" fi #检测数据库开启,获取jar包运行状态,未运行的进行启动 if [ $mysql_status -eq 1 ];then [ $jar_status -eq 0 ] && jar_start_cmd ||print_info_log "已启动" fi sleep 5 #结束死循环 #aaaaa=2 done
3.常规实现--数据库双主同步+keepalived
服务器ip:10.0.0.2 yum -y install gcc gcc-c++ autoconf automake make yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel yum -y install keepalived 配置安装文件 文件需要适配修改 vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id MASTER-1 } vrrp_script check_mysql_alive { script "/etc/keepalived/check_mysql_alive.sh" interval 2 weight -5 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 mcast_src_ip 10.0.0.2 priority 100 nopreempt advert_int 1 authentication { auth_type PASS auth_pass 123456 } track_script { check_mysql_alive } virtual_ipaddress { 10.0.0.3 } } 检测脚本 cd /etc/keepalived/ vim check_mysql_alive.sh 内容如下: #!/bin/bash counter=$(ss -tnlp|grep 3306 |wc -l) if [ $counter -eq 0 ];then systemctl stop keepalived fi chmod +x check_mysql_alive.sh 启动(保持mysql服务运行下,否则脚本检测到服务未运行会进行关闭keepalived) systemctl enable keepalived.service systemctl start keepalived.service systemctl status keepalived.service
10.0.0.3 操作
yum -y install gcc gcc-c++ autoconf automake make yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel yum -y install keepalived 配置安装文件 文件需要适配修改,参照图解说明 vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id MASTER-2 } vrrp_script check_mysql_alive { script "/etc/keepalived/check_mysql_alive.sh" interval 2 weight -5 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 mcast_src_ip 10.0.0.3 priority 90 nopreempt advert_int 1 authentication { auth_type PASS auth_pass 123456 } track_script { check_mysql_alive } virtual_ipaddress { 10.0.0.4 } } 检测脚本 cd /etc/keepalived/ vim check_mysql_alive.sh 内容如下: #!/bin/bash counter=$(ss -tnlp|grep 3306 |wc -l) if [ $counter -eq 0 ];then systemctl stop keepalived fi 执行权限 chmod +x check_mysql_alive.sh 启动(保持mysql服务运行下,否则脚本检测到服务未运行会进行关闭keepalived) systemctl enable keepalived.service systemctl start keepalived.service systemctl status keepalived.service
协助理解下