基于Amoeba读写分离
在实际生产环境中,如果对数据的读写都在一个数据库上操作,无论安全性高可用还是高并发等各方面都不能满足实际需求,因此一般来说是通过主从复制的方式来同步数据,再通过读写分离来提升数据的高并发负载能力这样的方案进行部署。
简单来说读写分离就是在主服务器上写,只在从服务器上读,基本的原理是让主数据库处理事务性查询,让从数据库处理select查询,数据库复制被用来把事务性查询导致的改变更新同步到集群中的从数据库
目前较为常见的读写分离方案有两种
1、基于程序代码内部实现
在代码中根据select,inster进行分离,这类方法在目前生产环境中应用最广泛,优点是性能好,不需要增加额外的设备作为硬件开支,缺点是需要开发人员来实现,运维无从下手;
2、基于中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接待客户端请求后通过判断后转发到后端数据库,代表性程序。
mysql-Proxy
mysql官方开发的早期开源项目,通过自带的lua脚本进行sql判断,虽然是mysql官方产品,但是mysql官方不建议将其应用到生成环境。
amoeba(变形虫)
由陈思儒开发,曾就职于阿里巴巴,该程序有java语言进行开发,阿里巴巴将其应用于生成环境,不支持事务和存储过程
Atlas
是由奇虎360公司网络平台部基础架构团队开发维护的一个基于mysql协议的数据中间层项目。它在mysql官方推出的mysql-proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能性特征。
Atlas官方链接:http://github.com/Qihoo360/Atlas/blob/master/README_ZH.md
Mysql
mycat活跃度比较高,前身就是cobar。cobar是阿里提供的一个中间件,已经停止更新。官网:http://www.mycat.io/
通过程序代码实现mysql读写分离自然是不错的选择,但是并不是所有的应用都适合在程序代码中实现读写分离,像大型复制的Java应用,如果在程序代码中实现读写分离对代码改动较大,像这种应用一般会考虑使用代理层来实现。
原理图二:
搭建基于amoeba读写分离架构
master:192.168.124.135
slave:192.168.124.134
slave:192.168.124.136
amoeba/Client:192.168.124.137
搭建主从从环境
master,slave1,slave2都执行
systemctl stop firewallld
systemctl disable firewalld
setenforce 0
或者
iptables -F
yum -y install mariadb mariadb-devel mariadb-server
搭建master数据库
yum -y install ntp
vim /etc/ntp.conf
server 127.127.1.0
fudge 127.127.1.0 startum 8
systemctl enable ntpd
systemctl start ntpd
vim /etc/my.cnf
[mysqld]
server-id=1
log-bin=mysql-binlog
log-slave-updates=true
#启动服务
systemctl start mariadb
ss -tnl
mysql -uroot -p
grant replication slave on . to ‘myslave’@‘192.168.124.%’ identified by ‘123.com’;
flush privileges;
show master status;
搭建slave1数据库
mysql -u myslave -p123.com -h192.168.124.135
\q;
ntpdate 192.168.124.135
vim /etc/my.cnf
[mysqld]
server-id=2
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
systemctl start mariadb
mysql -uroot -p
stop slave;
->CHANGE MASTER TO
MASTER_HOST=‘192.168.124.134’,
MASTER_USER=‘myslave’,
MASTER_PASSWORD=‘123.com’,
MASTER_LOG_FILE=‘mysql-binlog.000003’,
MASTER_LOG_POS=477;
start slave;
show slave status\G
搭建slave2数据库
mysql -u myslave -p123.com -h192.168.124.135
\q;
vim /etc/my.cnf
[mysqld]
server-id=3
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
systemctl start mariadb
mysql -uroot -p
stop slave;
->CHANGE MASTER TO
MASTER_HOST=‘192.168.124.135’,
MASTER_USER=‘myslave’,
MASTER_PASSWORD=‘123.com’,
MASTER_LOG_FILE=‘mysql-binlog.000003’,
MASTER_LOG_POS=478;
start slave;
show slave status\G
三台数据库给amoeba授权的用户
在master服务器中配置amoeba的访问授权
grant all on . to ‘amoeba’@‘192.168.124.%’ identified by ‘123.com’;
flush privileges;
在slave1中配置amoeba的访问授权
grant all on . to ‘amoeba’@‘192.168.124.%’ identified by ‘123.com’;
flush privileges;
在slave2中配置amoeba的访问授权
grant all on . to ‘amoeba’@‘192.168.124.%’ identified by ‘123.com’;
flush privileges;
至此主从从服务器架构已经搭建完毕,在数据库上创建一个master数据库,去两台从数据库上查看是否已经同步过来,如果同步过来表示成功
搭建amoeba服务器,并用此服务器当客户端
在主机amoeba上安装java环境,因为amoeba是基于jdk1.5版本开发的,所以官方推荐有1.5或者1.6版本的jdk,高版本的不建议使用。
安装jdk
chmod +x jdk-6u31-linux-x64-rpm.bin
./jdk-6u31-linux-x64-rpm.bin
vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/latest
export PATH=
J
A
V
A
H
O
M
E
/
b
i
n
:
/
JAVA_HOME/bin:/
JAVAHOME/bin:/PATH
. /etc/profile.d/java.sh
java -version
安装配置Amoeba
mkdir -pv /usr/local/amoebs
tar xf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
chmod -R 755 /usr/local/amoeba
cp /usr/local/amoeba/conf/dbServers.xml{,.bak}
vim /usr/localamoeba/conf/dbServers.xml
25行
#设置amoeba连接后端数据库服务器的账号,因此需要在所有后端数据库上创建该用户,并授权amoeba服务器可连接;
amoeba
#设置amoeba连接后端数据库服务器的密码;
123456
#设置一个后端可写的dbServer,这里定义为master,这个名字可以任意命名,后面在amoeba.xml文件里会用到
#设置后端可写dbserverd ip
192.168.124.135
#设置后端可读dbserver(如果是多个slave从节点,这里就配置多个<dbServer…,然后加入到后面第一的可读的组内)
#设置后端可读dbserver的ip
192.168.124.134
192.168.124.136
#设置定义一个虚拟的dbserver,实际上相当于一个dbserver组,这里将可读的数据库ip统一放到一个组中,将这个组的名字命名为slaves
#选择调度算法,1表示负载均衡,2表示权重,3表示HA,这里选择1
1
#myslave组成员
slave1,slave2
</amoeba:dbServer>
cp /usr/local/amoeba/conf/amoeba.xml{,.bak}
vim /usr/local/amoeba/conf/amoeba.xml
#提供客户端连接amoeba时需要使用这里设定的账号(这里的账号密码和amoeba连接后端数据库服务器的密码无关)
30行amoeba
123456
#设置amoeba默认的池,这里设置为masterdb(这个是在dbServer.xml文件里定义的)
master
#指定前面定义好的写池
master
#在dbServers,xml文件里定义的读池
slave
true
配置完成后启动Amoeba,默认端口:TCP/8066
/usr/local/amoeba/bin/amoeba start
ss -tnl
yum -y install mariadb mariadb-devel
mysql -uamoeba -p123456 -h192.168.124.137 -P8066
create database db_test;
use db_test;
create table student(id int(10),name varchar(10),address varchar(20));
测试:建立一个表,会不会同步到各从服务器上,然后关掉各从服务器上的slave功能,分别插入语句测试
验证主数据库的库,并在master中插入数据
master
查看主服务器数据库是否存在
show databases;
主服务器上插入数据
use db_test;
insert into student values(1,‘bob’,‘master_amoeba’);
验证slave1数据库的库,并停止掉slave在slave1中插入数据
slave1
show databases;
use db_test;
show tables;
在slave1上插入数据
stop slave;
insert into student values(‘2’,‘pavk’,‘slave_amoeba’);
验证slave2数据库的库,并停止掉slave在slave2中插入数据
slave2
show databases;
use db_test;
show tables;
stop slave;
insert into student values(‘3’,‘jrey’,‘slave2_amoeba’);
验证查询插入的数据
在amoeba上查看
第一次查询
select * from student;
第二次查询
select * from student;
第三次查询
select * from student;
测试写操作
在Client上插入一条数据
insert into student values (‘4’,‘nice’,‘client_write’);
第一次查询
selent *from student;
第二次查询
selent *from student;
第三次查询
selent *from student;
已经验证在client上查询不到,只有在master才能查询到,说明操作在master上
master
select * from studen;
由此验证了,已经实现mysql读写分离,目前所有的写操作都在master上,用来避免数据的不同步,所有的读操作都平分给了slave从服务,来分担数据库压力。