概述

本项目解决了MySQL读操作频繁给数据库服务器造成的巨大压力,和写操作数据库服务器的高可用性以及数据存储的问题。

两台写的数据库服务器之间使用heartbeat心跳线,和drdb技术构建网络raid1存储,搭建nfs直接绑定VIP,对客户端来说透明,方便,切换时耗时较短

keepalived和heartbeat对比

网上找了不少资料,简单整理下

  • keepalived使用配置很简单
  • heartbeat的功能更强大
  • 协议不同:keepalived使用VRRP协议通信,heartbeat使用心跳,可以通过以太网络,串口通信。
  • 都是要自定义脚本来和业务进行关联

总结下:Keepalived使用的vrrp协议方式,虚拟路由冗余协议 (Virtual Router Redundancy Protocol,简称VRRP);

Heartbeat是基于主机或网络的服务的高可用方式;

keepalived的目的是模拟路由器的双机;

heartbeat的目的是用户service的双机;

lvs的高可用建议用keepavlived;

业务的高可用建议heartbeat

一、环境

全部都是CentOS7.5操作系统,并且已经关闭防火墙和selinux,需要使用配置放行策略

主机名 IP地址 担任角色
dbmaster 192.168.111.7 写操作服务器master,已经搭建完成了drbd,heartbeat
dbbackup 192.168.111.8 写操作服务器backup,已经搭建完成了drbd,heartbeat
lvs1 192.168.111.3 lvs代理master,搭建lvs和keepalived
lvs2 192.168.111.4 lvs代理backup,搭建lvs和keepalived
readMySQL1 192.168.111.5 读操作服务器
readMySQL2 192.168.111.6 读操作服务器和readMySQL之间互相负载均衡
web 192.168.111.9 web服务器搭建Tomcat进行测试读写分离;为了节省资源amoeba也是在这台机器配置
heartbeatVIP 192.168.111.100
keepalivedVIP 192.168.111.200
  • 搭建思路

二、部署

部署lvs代理和keepalived

lvs1:

[root@localhost ~]# yum -y install ipvsadm keepalived
[root@localhost ~]# > /etc/keepalived/keepalived.conf
#清空自带的配置 [root@localhost ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lvs_clu_2
#设置lvs的id,在一个网络内应该是唯一的
}
virrp_sync_group Prox {
group {
mail
}
}
vrrp_instance mail {
#vrrp实例定义部分
state MASTER
#设置lvs的状态,MASTER和BACKUP两种,必须大写
interface ens32
#设置对外服务的接口
lvs_sync_daemon_interface ens32
#负载均衡器之间的监控接口,类似于 HA HeartBeat的心跳线。但它的机制优于 Heartbeat,因为它没有“裂脑”这个问题,它是以优先级这个机制来规避这个麻烦的。在DR 模式中,lvs_sync_daemon_inteface 与服务接口 interface 使用同一个网络接口。
virtual_router_id 50
#设置虚拟路由标示,这个标示是一个数字,同一个vrrp实例使用唯一标示
priority 80
#定义优先级,数字越大优先级越高,在一个vrrp——instance下,master的优先级必须大于backup
advert_int 1
#设定master与backup负载均衡器之间同步检查的时间间隔,单位是秒
authentication {
#设置验证类型和密码
auth_type PASS
#主要有PASS和AH两种
auth_pass 1111
#验证密码,同一个vrrp_instance下MASTER和BACKUP密码必须相同
}
virtual_ipaddress {
192.168.111.200
#设置虚拟Vip地址,可以设置多个,每行一个
}
}
virtual_server 192.168.111.200 3306 {
#设置虚拟VIP服务器,需要指定虚拟ip和服务端口
delay_loop 6
#健康检查时间间隔
lb_algo wrr
#负载均衡调度算法
lb_kind DR
#负载均衡转发规则
persistence_timeout 0
#设置会话保持时间,对动态网页非常有用
protocol TCP
#指定转发协议类型,有TCP和UDP两种
nat_mask 255.255.255.0
real_server 192.168.111.5 3306 {
#配置服务器节点1,需要指定real server的真实IP地址和端口
weight 1 
#设置权重,数字越大权重越高
TCP_CHECK {
#realserver的状态监测设置部分单位秒
connect_timeout 3
#超时时间
nb_get_retry 3
#重试次数
delay_before_retry 3
#重试间隔
connect_port 3306
#监测端口
}
}
real_server 192.168.111.6 3306 {
weight 1  
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
}

lvs2:

[root@localhost ~]# yum -y install ipvsadm keepalived
[root@localhost ~]# > /etc/keepalived/keepalived.conf
[root@localhost ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id lvs_clu_1
}
virrp_sync_group Prox {
group {
mail
}
}
vrrp_instance mail {
state BACKUP
interface ens32
lvs_sync_daemon_interface ens32
virtual_router_id 50
priority 70
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.111.200
}
}
virtual_server 192.168.111.200 3306 {
delay_loop 6
lb_algo wrr
lb_kind DR
persistence_timeout 0
protocol TCP
nat_mask 255.255.255.0
real_server 192.168.111.5 3306 {
weight 1 
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
real_server 192.168.111.6 3306 {
weight 1  
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
}

注意备机的权重和routeid

配置负载调度器

配置虚拟IP地址(VIP)采用虚拟接口的方式(ens32:0),为网卡ens32绑定VIP址,以便响应群集访问。

[root@localhost ~]# ifconfig ens32:0 192.168.111.200 netmask 255.255.255.0
[root@localhost ~]# ifconfig ens32:0
ens32:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.111.200 netmask 255.255.255.0 broadcast 192.168.111.255
#两个lvs都需要配置 配置节点服务器
使用 DR 模式时,节点服务器也需要配置 VIP 地址,并调整内核的 ARP响应参数以阻止更新 VIP 的 MAC 地址,避免发生冲突。除此之外,Web 服务的配置与 NAT 方式类似。
在每个节点服务器,同样需要有 VIP 地址 192.168.111.200,但此地址仅用作发送 Web响应数据包的源地址,并不需要监听客户机的访问请求(改由调度器监听并分发)。因此使用虚拟接口 lo:0 来承载 VIP 地址,并为本机添加一条路由记录,将访问 VIP 的数据限制在本地以避免通信紊乱。
[root@localhost ~]# ifconfig lo:0 192.168.111.200 netmask 255.255.255.255
[root@localhost ~]# ifconfig lo:0
lo:0: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 192.168.111.200 netmask 255.255.255.255
loop txqueuelen 1000 (Local Loopback) [root@localhost ~]# route add -host 192.168.111.200 dev lo:0
#临时添加了该路由,也可写入配置文件需要重启网卡,两个节点都做 节点服务器调整/proc相应参数 [root@localhost ~]# vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
#arp_ignore=1,系统只回答目的 IP 为是本地 IP 的包。也就是对广播包不做响应。
#rp_announce=2,系统忽略 IP 包的源地址(source address),而根据目标主机(target host),选择本地地址。
[root@localhost ~]# sysctl -p

MySQL+heartbeat+drbd的部署

参考笔者另一篇文档来部署drbd及heartbeat

基于drbd和heartbeat部署成功的基础和MySQL进行结合

mkdir /mysqlda
#新的MySQL数据存放目录 [root@dbmaster ~]# vim /usr/local/heartbeat/etc/ha.d/haresources
dbmaster IPaddr::192.168.111.100/24/ens32 drbddisk::r0 Filesystem::/dev/drbd0::/mysqlda::ext4 killmy
#将资源配置修改为如上 [root@dbmaster ~]# vim /usr/local/heartbeat/etc/ha.d/resource.d/killmy
pkill -9 mariadb; systemctl restart mariadb; exit 0
#编写相应的脚本,heartbeatVIP切换时会执行改脚本 chmod +x /usr/local/heartbeat/etc/ha.d/resource.d/killmy [root@dbmaster ~]# yum -y install mariadb*
[root@dbmaster ~]# ip a | grep ens32:0
inet 192.168.111.100/24 brd 192.168.111.255 scope global secondary ens32:0
[root@dbmaster ~]# df | grep drbd
/dev/drbd0 1014612 2568 943288 1% /mysqlda
#可以看到我的VIP和drbd的控制权现在都在dbmaster主机上 systemctl restart heartbeat
#各自重新加载heartbeat,卡住的话直接kill掉再重启 [root@dbmaster ~]# cp -Rp /var/lib/mysql/ /mysqlda/
#旧的数据目录复制到新的数据目录 [root@dbmaster ~]# vim /etc/my.cnf
[mysqld]
datadir=/mysqlda/mysql
#这里更改数据目录
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
user=mysql
server-id=1
log-bin
#二进制日志开启
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid #
# include all files from the config directory
#
!includedir /etc/my.cnf.d
备机配置一样,记得server-id修改为不同的

dbbackup上重启mariadb

  • 可能遇到如下报错,但是小弟这里目前没有发现。
[root@dbmaster ~]# systemctl restart mariadb
/usr/libexec/mysqld: Table 'mysql.plugin' doesn't exist
161121 14:45:35 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
161121 14:45:36 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist
161121 14:45:36 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended 因为我之前第一次启动的时候datadir是/var/lib/mysql,更改配置文件后,重新启动时找不到对应 库文件,虽然我已经把/var/lib/mysql/* 复制到了/database/mysql下面 解决方法就是重新执行mysql_install_db来解决问题。 [root@dbmaster ~]# mysql_install_db --user=mysql
  • 简单测试
[root@dbmaster mysql]# ls
aria_log.00000001 ibdata1 ib_logfile1 mariadb-bin.index mysql.sock test
aria_log_control ib_logfile0 mariadb-bin.000001 mysql performance_schema
#跟后面做个对比 [root@dbmaster mysql]# mysql MariaDB [(none)]> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
MariaDB [mysql]> update user set password=password('123456') where user='root' and host='localhost';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0 MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.01 sec) MariaDB [mysql]> exit
Bye #这里顺便更改下用户的默认密码 MariaDB [(none)]> create database test1;
Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> use test1; MariaDB [test1]> create table t1 (id int,name varchar(20));
Query OK, 0 rows affected (0.01 sec) [root@dbmaster ~]# ls /mysqlda/mysql/
aria_log.00000001 ibdata1 ib_logfile1 mariadb-bin.index mysql.sock test/
aria_log_control ib_logfile0 mariadb-bin.000001 mysql/ performance_schema/ test1/
[root@dbmaster ~]# ls /mysqlda/mysql/test1/
db.opt t1.frm
[root@dbmaster ~]# ls /mysqlda/mysql/test1/
db.opt t1.frm
  • 切换VIP看数据
[root@dbmaster mysql]# systemctl stop heartbeat.service
#master上停掉心跳 [root@dbbackup ~]# netstat -anpt | grep mysqld
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 6873/mysqld
#备上查看MySQL,我原来没开,切过来VIP ,heartbeat通过脚本执行的 [root@dbbackup ~]# ls /mysqlda/mysql/
aria_log.00000001 ib_logfile0 mariadb-bin.000002 mariadb-bin.index performance_schema/
aria_log_control ib_logfile1 mariadb-bin.000003 mysql/ test/
ibdata1 mariadb-bin.000001 mariadb-bin.000004 mysql.sock test1/
[root@dbbackup ~]# ls /mysqlda/mysql/test1/
db.opt t1.frm
#备上查看,暂时准确无误

MySQL主从复制

Mysql的复制是异步复制,即从一个Mysql实例或者端口(成为master)复制到另一个Mysql实例或者端口(成为slave)。复制操作有3个进程实现的,其中两个进程(Sql进程和IO进程)在Slave上,另一个进程在master(binlog dump)上。

  • 实现复制前提需要打开log-bin二进制日志功能这是因为整个复制实际上是slave从Master端获取该更新操作的日志,将其传输到本地并写到本地文件中,然后在读取本地内容执行日志中所记录的更新操作。
master操作:
MariaDB [(none)]> grant replication slave on *.* to 'rep'@'192.168.111.%' identified by'123456';
Query OK, 0 rows affected (0.00 sec)
#授权用户权限 show grants for rep@'192.168.111.%'
#查看权限 MariaDB [(none)]> flush privileges; 先采用打包的方式,进行一次完全备份
MariaDB [(none)]> flush tables with read lock;
#锁表
MariaDB [(none)]> reset master
-> ;
Query OK, 0 rows affected (0.02 sec)
MariaDB [test1]> create table t2 (id int,name varchar(20));
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
#锁表完成了 然后另外打开一个终端操作 [root@dbbackup ~]# cd /mysqlda/mysql/ [root@dbbackup mysql]# tar zcvf mysqlsql`date +%F`.tar.gz ib* mysql* test/ test1/
#将需要的文件打包压缩,也可以选择通过mysqldump导出数据库。 [root@dbbackup mysql]# scp -r mysqlsql2019-05-16.tar.gz root@readMySQL1:/opt/
root@readmysql1's password:
mysqlsql2019-05-16.tar.gz 100% 572KB 42.5MB/s 00:00
[root@dbbackup mysql]# scp -r mysqlsql2019-05-16.tar.gz root@readMySQL2:/opt/
root@readmysql2's password:
mysqlsql2019-05-16.tar.gz 100% 572KB 3.9MB/s 00:00
#复制到读操作服务器上 MariaDB [(none)]> show master status;
+--------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000001 | 245 | | |
+--------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
#查看状态,读服务器根据二进制日志备份会需要。
  • 读服务器的操作
yum -y install mariadb*

tar zxf /opt/mysqlsql2019-05-16.tar.gz -C /var/lib/mysql/
#解压到指定的数据目录,我这里是默认目录,-C指定路径 [root@localhost ~]# ls /var/lib/mysql/
ibdata1 ib_logfile0 ib_logfile1 mysql test test1 [root@localhost ~]# vim /etc/my.cnf
[mysqld]
server-id = 4
#每个id都不同 [root@localhost ~]# systemctl start mariadb [root@localhost ~]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 83
Server version: 5.5.60-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]>
MariaDB [(none)]> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
MariaDB [mysql]> update user set password=password('123456') where user='root' and host='localhost';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.00 sec) MariaDB [mysql]> exit
Bye
#更改下默认密码 [root@localhost ~]# mysql -u root -p123456 -e "change master to master_host='192.168.111.100',master_user='rep',master_password='123456',master_log_file='mariadb-bin.000001',master_log_pos=245;"
[root@localhost ~]# mysql -u root -p123456 -e "start slave;" [root@localhost ~]# mysql -u root -p123456 -e"show slave status\G;"
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.111.100
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mariadb-bin.000001
Read_Master_Log_Pos: 1585
Relay_Log_File: mariadb-relay-bin.000002
Relay_Log_Pos: 531
Relay_Master_Log_File: mariadb-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1585
Relay_Log_Space: 827
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 2 重点关注这两项:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
为yes基本上主从复制算是成功了
  • MySQL主从复制及VIP切换测试
VIP所在机器操作如下:
MariaDB [test1]> create table tabletest (id int,name varchar(20)); 读操作服务器查看:
MariaDB [(none)]> use test1;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
MariaDB [test1]> show tables;
+-----------------+
| Tables_in_test1 |
+-----------------+
| t1 |
| tabletest |
+-----------------+
2 rows in set (0.00 sec)

VIP切换测试

[root@dbbackup ~]# ip a| grep ens32:0
inet 192.168.111.100/24 brd 192.168.111.255 scope global secondary ens32:0
[root@dbbackup ~]# systemctl stop heartbeat.service [root@dbmaster ~]# ip a| grep ens32:
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.111.100/24 brd 192.168.111.255 scope global secondary ens32:1
#另一台机器查看VIP是否转移过来 [root@dbmaster ~]# mysql -u root -p123456 MariaDB [(none)]> use test1; [test1]> create table tabletest2 (id int,name varchar(20));
Query OK, 0 rows affected (0.01 sec) #创建表进行,主从复制测试 读操作服务器查看:
[root@localhost ~]# mysql -uroot -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 168
Server version: 5.5.60-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use test1;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
MariaDB [test1]> show tables;
+-----------------+
| Tables_in_test1 |
+-----------------+
| t1 |
| tabletest |
| tabletest2 |
+-----------------+
3 rows in set (0.00 sec)

主从复制告一段落

web服务器及amoeba配置

  • 这里安装Tomcat做以示范
[root@web ~]# ls
anaconda-ks.cfg apache-tomcat-8.5.16.tar.gz initial-setup-ks.cfg jdk-8u191-linux-x64.tar.gz 安装tar包jdk
[root@web ~]# rm -rf /usr/bin/java
[root@web ~]# tar zxf jdk-8u191-linux-x64.tar.gz
[root@web ~]# mv jdk1.8.0_191/ /usr/local/java8
[root@web ~]# echo "export JAVA_HOME=/usr/local/java8" >> /etc/profile
[root@web ~]# echo "PATH=$PATH:/usr/local/java8/bin" >> /etc/profile
[root@web ~]# source /etc/profile
[root@web ~]# java -version
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode) [root@web ~]# /usr/local/tomcat8/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat8
Using CATALINA_HOME: /usr/local/tomcat8
Using CATALINA_TMPDIR: /usr/local/tomcat8/temp
Using JRE_HOME: /usr/local/java8
Using CLASSPATH: /usr/local/tomcat8/bin/bootstrap.jar:/usr/local/tomcat8/bin/tomcat-juli.jar
Tomcat started.

客户端访问 http://192.168.111.9:8080 进行测试

  • 安装配置amoeba

    常见读写分离方案概述:
  1. 基于程序代码内部实现

    在代码中根据 select,insert进行路由分类,这类方法也是目前生产环境应用最广泛的,优点是性能好,因为在程序代码中实现,不需要曾加额外的设备作为硬件开支,缺点是需要开发人员来实现,运维人员无从下手。
  2. 基于中间代理层实现

    代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,代表性程序:

    (1)mysql-proxy 为 mysql 开发早期开源项目,通过其自带的 lua 脚本进行 SQL 判断,虽然是 mysql 的官方产品,但是 mysql 官方不建议将其应用到生产环境。

    (2)Amoeba (变形虫)由陈思儒开发,曾就职与阿里巴巴,该程序由 java 语言进行开发,阿里巴巴将其应用于生成环境,它不支持事物和存储过程。

配置

[root@web ~]# mkdir /usr/local/amoeba
[root@web ~]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@web ~]# chmod -R 755 /usr/local/amoeba/ 在负责写操作的并且VIP所在服务器上操作如下,目的是进行授权
在两台负责读操作服务器上操作如下,授权:
MariaDB [test1]> grant all on *.* to 'amoetest'@'192.168.111.%' identified by '123456';
Query OK, 0 rows affected (0.00 sec) MariaDB [test1]> flush privileges; 回到amoeba所在服务器上:
[root@web ~]# vim /usr/local/amoeba/conf/amoeba.xml
11 <property name="port">8066</property>
#amoeba监听端口
30 <property name="user">amoeba</property>
#给开发人员用的账号,下文是密码
32 <property name="password">123456</property>
116 <property name="defaultPool">master</property>
#配置默认的数据库节点,除了select,update,insert,delete语句都会在defaultpool上执行
119 <property name="writePool">master</property>
#配置写操作数据库
120 <property name="readPool">slaves</property>
#配置读操作数据库 [root@web ~]# vim /usr/local/amoeba/conf/dbServers.xml
20 <property name="port">3306</property>
#mysql端口
23 <property name="schema">test</property>
#amoeba控制的mysql库名,可以多添加几个
26 <property name="user">amoetest</property>
#mysql给授权的用户名
28 <property name="password">123456</property>
#mysql给授权的密码
43 <dbServer name="master" parent="abstractServer">
46 <property name="ipAddress">192.168.111.100</property>
#定义服务器名字和amoeba.xml相对应,下面指定的IP地址指定的是写操作高可用几群的VIP,如下一样
48 </dbServer>
50 <dbServer name="slave" parent="abstractServer">
53 <property name="ipAddress">192.168.111.200</property>
54 </factoryConfig>
55 </dbServer> 另外建议注释以下文件行,本案例中并没有服务器池,对amoeba来说一个集群即为一台服务器
56 <!--
57 <dbServer name="multiPool" virtual="true">
58 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
59 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
60 <property name="loadbalance">1</property>
61
62 <!-- Separated by commas,such as: server1,server2,server1 -->
63 <property name="poolNames">server1,server2</property>
64 </poolConfig>
65 </dbServer>
66 --> [root@web ~]# nohup /usr/local/amoeba/bin/amoeba start &
#本来到这里就正常启动了,接下来的报错可能有些不会发生 [root@web ~]# cat nohup.out
The stack size specified is too small, Specify at least 228k
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit. 解决
[root@web ~]# vim /usr/local/amoeba/bin/amoeba
58 DEFAULT_OPTS="-server -Xms256m -Xmx256m -Xss256k" [root@web ~]# nohup /usr/local/amoeba/bin/amoeba start &
#不出意外成功
[root@web ~]# netstat -anpt | grep 8066
tcp6 0 0 :::8066 :::* LISTEN 65920/java
#端口出来的慢比较
[root@web ~]# mysql -h192.168.111.9 -uamoeba -p -P8066
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
#指向amoeba的地址,用户端口,密码要输入正确.这停留等待时间可能需要点,但如果配置无措,可以连接的 MySQL [(none)]> use test; No connection. Trying to reconnect...
Connection id: 185788589
Current database: *** NONE *** Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed MySQL [test]> create table t2 (id int,name varchar(20));
Query OK, 0 rows affected (0.02 sec) MySQL [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t2 |
+----------------+
#感觉卡,目前不是特别顺

amoeba配置文件详解

另一个

  • 配置Tomcat连接mysql(amoeba)
下载 mysql-connector-java
官网下载地址:http://dev.mysql.com/downloads/connector/j/
我用的是mysql-connector-java-3.1.14 [root@web lib]# cp mysql-connector-java-3.1.14-bin.jar /usr/local/tomcat8/lib/
#下载好的放到tomcat目录下的lib目录下
[root@web lib]# /usr/local/tomcat8/bin/shutdown.sh
[root@web lib]# /usr/local/tomcat8/bin/startup.sh [root@web lib]# vim /usr/local/tomcat8/webapps/test/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.Connection"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body> <%
try{
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://192.168.111.9:8066/test";
String username="amoeba";
String password="123456";
Connection conn=DriverManager.getConnection(url,username,password);
if(conn!=null){
out.println("mysql数据库连接成功!!!");
}else{
out.println("数据库连接失败!!!");
}
}catch(ClassNotFoundException e){
e.printStackTrace();
}
%>
%%</body>
%%</html>
#以上文件使用的时候更改相应的ip地址,及端口,我这里直接输入的是在amoeba上的端口,以及ip,和账户及密码 #测试:浏览器输入http://192.168.111.9:8080/test/index.jsp
#配置正确的话显示输出信息,连接成功

总测试

  • 部署开源站点在Tomcat上跑

jpress 官网:http://jpress.io

下载地址:https://github.com/JpressProjects/jpress

MariaDB [(none)]> create database jpress default character set utf8;
MariaDB [(none)]> grant all on jpress.* to jpress@'192.168.111.%' identified by '123456';
MariaDB [(none)]> flush privileges;
#写操作服务器VIP所在机器上操作 #查看读操作服务器是否同步
[root@localhost ~]# ip a | grep ens32
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.111.5/24 brd 192.168.111.255 scope global noprefixroute ens32
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jpress |
| mysql |
| test |
| test1 |
+--------------------+
5 rows in set (0.00 sec) [root@localhost ~]# ip a | grep ens32
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.111.6/24 brd 192.168.111.255 scope global noprefixroute ens32
[root@localhost ~]# mysql -u root -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 2829
Server version: 5.5.60-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jpress |
| mysql |
| test |
| test1 |
+--------------------+
5 rows in set (0.00 sec) #也可以在读操作服务器上查看授权信息,也已经同步到本机
  • 代码上线
[root@localhost ~]# wget https://github.com/JpressProjects/jpress/archive/0.4.0.tar.gz
[root@localhost ~]# tar xf 0.4.0.tar.gz
[root@localhost ~]# cd jpress-0.4.0/wars/
[root@localhost wars]# mv jpress-web-newest.war /usr/local/tomcat8/webapps/
[root@localhost wars]# /usr/local/tomcat8/bin/shutdown.sh
[root@localhost wars]# /usr/local/tomcat8/bin/startup.sh
[root@web ~]# ls /usr/local/tomcat8/webapps/
docs examples host-manager jpress-web-newest jpress-web-newest.war
#自动部署war包 [root@web ~]# vim /usr/local/amoeba/conf/dbServers.xml
23 <property name="schema">jpress</property>
24
25 <!-- mysql user -->
26 <property name="user">jpress</property>
27
28 <property name="password">123456</property> #改为在数据库新授权的用户

浏览器访问http://192.168.111.9:8080/jpress-web-newest/install

[root@web ~]# /usr/local/tomcat8/bin/shutdown.sh

[root@web ~]# /usr/local/tomcat8/bin/startup.sh

查看数据库数据同步否

[root@dbmaster ~]# ip a | grep ens32
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.111.7/24 brd 192.168.111.255 scope global noprefixroute ens32
inet 192.168.111.100/24 brd 192.168.111.255 scope global secondary ens32:2 [root@dbmaster ~]# mysql -uroot -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 169
Server version: 5.5.60-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use jpress
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
MariaDB [jpress]> show tables;
+-------------------+
| Tables_in_jpress |
+-------------------+
| jpress_attachment |
| jpress_comment |
| jpress_content |
| jpress_mapping |
| jpress_metadata |
| jpress_option |
| jpress_taxonomy |
| jpress_user |
+-------------------+
8 rows in set (0.00 sec)
#正常情况下,MySQL写服务器,读操作的两台数据应该是完全一样的
  • heartbeat切换测试
[root@dbmaster ~]# cat /opt/monitor_mysql.sh
#!/bin/bash
while true
do
sleep 2
counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)
if [ "${counter}" -eq 0 ]; then
systemctl stop heartbeat.service
fi
done
#只是简单测试脚本,不可应用于生产环境下
[root@dbbackup ~]# chmod +x /opt/monitor_mysql.sh
[root@dbmaster ~]# nohup /opt/monitor_mysql.sh &
[1] 26582
[root@dbmaster ~]# nohup: 忽略输入并把输出追加到"nohup.out"
#VIP机器运行此脚本 接下来在VIP所在机器将mariadb关闭 等待几秒,另一台查看,转移成功 [root@web ~]# mysql -h192.168.111.100 -ujpress -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.60-MariaDB MariaDB Server Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]>
别的服务器测试也没啥问题

keepalived配置文件详解

! Configuration File for keepalived

global_defs {
notification_email {
acassen@firewall.loc #设置报警邮件地址,可以设置多个,每行一个。
failover@firewall.loc #需开启本机的sendmail服务
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc #设置邮件的发送地址
smtp_server 127.0.0.1 #设置smtp server地址
smtp_connect_timeout 30 #设置连接smtp server的超时时间
router_id LVS_DEVEL #表示运行keepalived服务器的一个标识。发邮件时显示在邮件主题的信息
} vrrp_instance VI_1 {
state MASTER #指定keepalived的角色,MASTER表示此主机是主服务器,BACKUP表示此主机是备用服务器
interface enp0s3 #指定HA监测网络的接口
virtual_router_id 51 #虚拟路由标识,这个标识是一个数字,同一个vrrp实例使用唯一的标识。即同一vrrp_instance下,MASTER和BACKUP必须是一致的
priority 100 #定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级
advert_int 1 #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
authentication { #设置验证类型和密码
auth_type PASS #设置验证类型,主要有PASS和AH两种
auth_pass 1111 #设置验证密码,在同一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码才能正常通信
}
virtual_ipaddress { #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个
192.168.137.100
}
} virtual_server 192.168.137.100 80 { #设置虚拟服务器,需要指定虚拟IP地址和服务端口,IP与端口之间用空格隔开
delay_loop 6 #设置运行情况检查时间,单位是秒
lb_algo rr #设置负载调度算法,这里设置为rr,即轮询算法
lb_kind DR #设置LVS实现负载均衡的机制,有NAT、TUN、DR三个模式可选
nat_mask 255.255.255.0
persistence_timeout 0 #会话保持时间,单位是秒。这个选项对动态网页是非常有用的,为集群系统中的session共享提供了一个很好的解决方案。
#有了这个会话保持功能,用户的请求会被一直分发到某个服务节点,直到超过这个会话的保持时间。
#需要注意的是,这个会话保持时间是最大无响应超时时间,也就是说,用户在操作动态页面时,如果50秒内没有执行任何操作
#那么接下来的操作会被分发到另外的节点,但是如果用户一直在操作动态页面,则不受50秒的时间限制
protocol TCP #指定转发协议类型,有TCP和UDP两种 real_server 192.168.137.5 80 { #配置服务节点1,需要指定real server的真实IP地址和端口,IP与端口之间用空格隔开
weight 1 #配置服务节点的权值,权值大小用数字表示,数字越大,权值越高,设置权值大小可以为不同性能的服务器
#分配不同的负载,可以为性能高的服务器设置较高的权值,而为性能较低的服务器设置相对较低的权值,这样才能合理地利用和分配系统资源
  • 还有读操作数据库切换,关闭一台,使用客户端访问测试,这里不再掩饰

    暂时完结

总结

  1. lvs使用dr模式,而且由于我这是测试环境,也没有加多余的网卡,刚开始时没有配置/proc参数,一直出问题,我还以为是amoeba连接慢呢,人家都没连上去,都连接到写操作服务器上了.
  2. 细节决定成败,历时三天两夜,加油吧
  3. 总测试没有很好的测出来效果,但也是没什么问题的,数据库毕竟和网站服务器不一样
  4. 脚本写的非常敷衍

MySQL读写分离高可用集群及读操作负载均衡(Centos7)的更多相关文章

  1. Redis Cluster高可用集群在线迁移操作记录【转】

    之前介绍了redis cluster的结构及高可用集群部署过程,今天这里简单说下redis集群的迁移.由于之前的redis cluster集群环境部署的服务器性能有限,需要迁移到高配置的服务器上.考虑 ...

  2. Redis Cluster高可用集群在线迁移操作记录

    之前介绍了redis cluster的结构及高可用集群部署过程,今天这里简单说下redis集群的迁移.由于之前的redis cluster集群环境部署的服务器性能有限,需要迁移到高配置的服务器上.考虑 ...

  3. Mysql分布式部署高可用集群方案

    HAproxy+Mycat +MySQL主从集群高可用方案 1.         HAproxy高可用方案: haproxy+keepalived,利用keepalived的VIP浮动能力,(多台ha ...

  4. mysql读写分离[高可用]

    顾名思义, 在mysql负载均衡中有多种方式, 本人愚钝,只了解驱动中间件和mysql_proxy两种方式, 对于驱动,利用的是ReplicationDriver,具体请看远哥的这篇文章: MySQL ...

  5. linux系统下对网站实施负载均衡+高可用集群需要考虑的几点

    随着linux系统的成熟和广泛普及,linux运维技术越来越受到企业的关注和追捧.在一些中小企业,尤其是牵涉到电子商务和电子广告类的网站,通常会要求作负载均衡和高可用的Linux集群方案. 那么如何实 ...

  6. Linux下"负载均衡+高可用"集群的考虑点 以及 高可用方案说明(Keepalive/Heartbeat)

    当下Linux运维技术越来越受到企业的关注和追捧, 在某些企业, 尤其是牵涉到电子商务和电子广告类的网站,通常会要求作负载均衡和高可用的Linux集群方案.那么如何实施Llinux集群架构,才能既有效 ...

  7. activemq+Zookeper高可用集群方案配置

    在高并发.对稳定性要求极高的系统中,高可用的是必不可少的,当然ActiveMQ也有自己的集群方案.从ActiveMQ 5.9开始,ActiveMQ的集群实现方式取消了传统的Master-Slave方式 ...

  8. Dubbo入门到精通学习笔记(二十):MyCat在MySQL主从复制的基础上实现读写分离、MyCat 集群部署(HAProxy + MyCat)、MyCat 高可用负载均衡集群Keepalived

    文章目录 MyCat在MySQL主从复制的基础上实现读写分离 一.环境 二.依赖课程 三.MyCat 介绍 ( MyCat 官网:http://mycat.org.cn/ ) 四.MyCat 的安装 ...

  9. 基于Keepalived高可用集群的MariaDB读写分离机制实现

    一 MariaDB读写分离机制 在实现读写分离机制之前先理解一下三种主从复制方式:1.异步复制:MariaDB默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库 ...

随机推荐

  1. (五)AJAX技术

    一.定义 AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 传统的 ...

  2. MySQL必知必会:组合查询(Union)

        MySQL必知必会:组合查询(Union) php mysqlsql  阅读约 8 分钟 本篇文章主要介绍使用Union操作符将多个SELECT查询组合成一个结果集.本文参考<Mysql ...

  3. ElasticSearch文档删除字段

    https://www.cnblogs.com/ljhdo/archive/2017/03/24/4885796.html

  4. iOS-NSBundle、NSArray、NSDictionay

    NSBundle.NSArray.NSDictionay 读取plist文件 NSDictionary  *dict= [NSDictionary dictionaryWithContentsOfFi ...

  5. lvs整理

    LVS是Linux Virtual Server的简写,即Linux虚拟服务器,是一个虚拟的服务器集群系统.通过LVS提供的负载均衡技术和Linux操作系统实现一个高性能.高可用的服务器群集,它具有良 ...

  6. python3.7.3安装beautifulsoup4出现版本不兼容的问题

    今天想安装一个beautifulsoup4,结果一直出错,好多教程总是有各种坑……找了很多个教程,为了记录方法也为了分享给大家,简单些一个.但是是真真不想再费劲写一遍了……直接贴链接,亲测有效,但是底 ...

  7. python __name__ == ‘__main__’详细解释(27)

    学习过C语言或者Java语言的盆友应该都知道程序运行必然有主程序入口main函数,而python却不同,即便没有主程序入口,程序一样可以自上而下对代码块依次运行,然后python不少开源项目或者模块中 ...

  8. 日常工作问题解决:rhel7下配置多路径设备

    目录 1.情景描述 2.安装多路径软件 2.1 安装多路径 2.2检查安装情况 2.3 重启系统 2.4 将多路径软件添加至内核模块 2.5 检查内核添加情况 2.6 启动multipath服务 2. ...

  9. v-if v-else-if v-else 条件渲染案例

    <body><!--修饰符--><div id="app"> <span v-if="isuser"> < ...

  10. 系统获取 IP 工具类

    系统获取 IP 工具类 import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterf ...