MySQL主从复制与读写分离


MySQL主从复制与读写分离

一、简介

MySQL主从复制和读写分离两者有着紧密的联系,只有部署好主从复制了,才能在此基础上进行数据库的读写分离。


1.MySQL支持的复制类型

a.基于语句的复制。

b.基于行的复制。

c.混合类型的复制。默认基于语句复制,当基于语句的复制无法精确复制时,就会采用基于行的复制。


2.读写分离

只在主服务器上写,从服务器上读。基本原理就是让主数据库处理事务性查询,而从服务器处理select查询。set global read_only=0;

目前常见的MySQL读写分离有两种:

a.基于程序代码内部实现

在代码中根据selectinsert进行路由分类。有点是性能好,不需要增加额外的设备作为硬件开支;缺点是需要开发人员实现,运维人员无从下手。

b.基于中间代理实现

1MySQL-Proxy

2Amoeba,由陈思儒开发,作者曾就职阿里巴巴,阿里巴巴将其应用于生产环境中。这个软件致力于mysql的分布式数据库前端代理层,它主要为应用层访问mysql的时候充当sql路由功能,并具备有负载均衡、高可用性、sql过滤、读写分离、可路由相关的到目标数据库,可并发请求多台数据库,不过它不支持事务和存储过程。

二、案例环境


 

 

 

 

 

 

 

 

 

 

 

 

统:CentOS 6.5-64

主机:

master 192.168.0.100 cmake mysql

slave1 192.168.0.101 cmake mysql

slave2 192.168.0.102 cmake mysql

Amoeba 192.168.0.110 amoeba jdk

client 192.168.0.111

三、环境准备

1.配置主机名和ip地址

root@localhost #hostname master

root@master #vim /etc/hosts

192.168.0.100 master

192.168.0.101 slave1

192.168.0.102 slave2

192.168.0.110 amoeba

192.168.0.111 client

root@master #vim /etc/sysconfig/network

HOSTNAME=master

root@master #ifconfig -a //查询所有网卡

root@master #vim /etc/sysconfig/network-scripts/ifcfg-eth2


DEVICE=eth2


HWADDR=00:0C:29:49:0F:81


TYPE=Ethernet


UUID=d97bca82-0440-41f9-9cd0-02fe0909cee6


ONBOOT=yes


NM_CONTROLLED=yes


BOOTPROTO=static


IPADDR=192.168.0.10


NETMASK=255.255.255.0


root@master #service network restart


2.安装NTP

NTP时间同步服务器,在主节点上搭建,主节点可以是单独一台服务器,也可以是master,或者Amoeba服务器

root@master #mount /dev/cdrom /media/

root@master #rm -fr /etc/yum.repos/*

root@master #cat >/etc/yum.repos/local.repo<<end

>[local]

>name=cjenlet

>baseurl=file:///media/

>enabled=1

>gpgcheck=0

>end

root@master #yum -y install ntp

root@master #vim /etc/ntp.conf

server 127.127.1.0

fudge 127.127.1.0 stratum 8

root@master #service ntpd restart

root@master #service iptables stop

root@master #chkconfig iptables off

root@master #setenforce 0

root@master #vim /etc/selinux/config

SELINUX=disabled

从节点上安装ntpdate,每台需要同步时间的服务器都要安装

root@localhost ~#service iptables stop

root@master #chkconfig iptables off

root@localhost ~#setenforce 0

root@localhost ~#vim /etc/selinux/config

SELINUX=disabled

root@localhost ~#yum -y install ntpdate

root@localhost ~#/usr/sbin/ntpdate 192.168.0.100 //指向NTP服务器的ip地址


 

 

四、安装MySQL数据库

1.masterslave1slave2上安装mysql

[root@master ~]# yum -y install ncurses-devel

[root@master ~]# tar xvf cmake_2_.tgz

[root@master ~]# cd cmake-2.8.6/


[root@master cmake-2.8.6]# ./configure

[root@master cmake-2.8.6]#gmake

[root@master cmake-2.8.6]#gmake install


[root@master ~]# tar xvf mysql_5_.tgz

[root@master ~]# cd mysql-5.5.22/


[root@master mysql-5.5.22]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DSYSCONFDIR=/etc

[root@master mysql-5.5.22]#make &&make install


2.优化调整,master,slave1,slave2都要优化

[root@master mysql-5.5.22]# cp support-files/my-medium.cnf /etc/my.cnf

[root@master mysql-5.5.22]# cp support-files/mysql.server /etc/rc.d/init.d/mysqld

[root@master mysql-5.5.22]# chmod +x /etc/rc.d/init.d/mysqld

[root@master mysql-5.5.22]# chkconfig --add mysqld

[root@master mysql-5.5.22]# cat >>/etc/profile<<end

PATH=$PATH:/usr/local/mysql/bin

end

 

 

 

 

 

[root@master mysql-5.5.22]# . /etc/profile

3.初始化数据库

[root@master mysql-5.5.22]# groupadd mysql

[root@master mysql-5.5.22]# useradd -M -s /sbin/nologin mysql -g mysql

//-M不创建家目录;-s指定shell环境;-g指定组

[root@master mysql-5.5.22]# chown -R mysql.mysql /usr/local/mysql/

[root@master mysql-5.5.22]# /usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --user=mysql

//本人不小心漏打了- -user=mysql,后来重新把整条命令完整执行一遍,这样是不对的,到时候启动数据库的时候会启动失败,建议把/usr/local/mysql/data/目录下的所有东西删掉,然后再完整执行这条命令


4.启动mysql服务

[root@slave1 mysql]# service mysqld start

[root@master mysql-5.5.22]# chkconfig mysqld on


[root@master mysql-5.5.22]# mysqladmin -u root password 'abc123.' //root用户设置密码


 

 

 

五、规划配置主从服务器,验证主从复制。

1.配置mysql master主服务器

[root@master mysql-5.5.22]# vim /etc/my.cnf

log-bin=master-bin //修改

log-slave-updates=true //增加

server-id=11 //修改

 

 

 

 

 

 

[root@master mysql-5.5.22]# service mysqld restart

//重启服务


[root@master mysql-5.5.22]# mysql -uroot -pabc123. //登录数据库

mysql> grant replication slave on *.* to myslave@'192.168.0.%' identified by 'abc123.';

// 意思是,在mysql数据库user表中创建myslave用户,允许其能够以密码abc123.’

//网段为192.168.0.%访问数据库时有复制的权限

//夺权:

revoke replication slave on *.* from myslave@'192.168.0.%'

//mysql> grant replication slave on *.* to myslave@192.168.0.102 identified by 'abc123.';

//只给单个ip赋予权限,给ip地址改成主机名,建议先把user表的myslave对应的host改成///slave1

mysql>update user set host='slave1' where user='myslave';

mysql> flush privileges; //跟新用户列表

mysql> show master status;

 

 

 

 

 

 

 

2.配置mysql slave从服务器

a. [root@slave1 mysql]# vim /etc/my.cnf

server-id = 22

//修改,server-id不能与服务器相同

relay-log=relay-log-bin

//增加

relay-log-index=slave-relay-bin.index

//增加


 

 

 

 

 

 

 

 

b. [root@slave1 mysql]# service mysqld restart //重启服务

c. 登录从服务器mysql数据库,配置同步

[root@slave1 mysql]# mysql -uroot -pabc123.

mysql> change master to master_host='192.168.0.100',master_user='myslave',master_password='abc123.',master_log_file='master-bin.000001',master_log_pos=488;

//注意单引号要打全,每次设置都要先回到master主机show master status;

//slave2从服务器上只需把上面这条命令中的slave1改为slave2,执行

d. mysql> start slave; //启动同步

mysql> show slave status\G;

//查看slave状态,确保以下两个值为yes



 

 

 

 

 

 

 

 

3.验证主从复制效果

mysql> create database cjenlet;

//主服务器上创建cjenlet数据库

mysql> show databases;

//masterslave1slave2,上分别查看,的到的结果是一样的,都有新建的cjenlet数据库存在



 

 

 

 

 

六、搭建mysql读写分离

1.环境准备,在amoeba主机上安装java环境

[root@amoeba ~]# cp jdk_6u14.bin /usr/local/

[root@amoeba ~]#cd /usr/local

[root@amoeba local]# chmod +x /usr/local/jdk_6u14.bin

[root@amoeba local]# ./jdk_6u14.bin //enter继续

[root@amoeba local]# vim /etc/profile

export JAVA_HOME=/usr/local/java

export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib

export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$PATH:$HOME/bin

export AMOEBA_HOME=/usr/local/amoeba/

export PATH=$PATH:$AMOEBA_HOME/bin

 

 

 

 

[root@amoeba local]# vim /etc/profile

[root@amoeba local]# java -version



 

 

2.安装amoeba

[root@amoeba ~]# mkdir /usr/local/amoeba

[root@amoeba ~]# tar xvf amoeba_m.tgz -C /usr/local/amoeba/

[root@amoeba ~]# chmod -R 755 /usr/local/amoeba/

[root@amoeba ~]# /usr/local/amoeba/bin/amoeba

//显示如下图则成功



3.配置amoeba读写分离,两个slave负载均衡

master

mysql> grant all on *.* to test@'amoeba' identified by 'abc123.';

//只在master上给创建test用户就可以了,因为slave1slave2都会同步的。

//只赋予amoeba具有代理的权限,以test用户管理数据库,通过代理,其没有创建用户和给//用户赋权的权限


4.编辑amoeba.xml配置文件

[root@amoeba ~]# vim /usr/local/amoeba/conf/amoeba.xml

//修改下图中红框的地方,这是设置amoeba管理密码


 

 

 

 

 

 

 

//修改下图红框的地方,这是规划读写分离


 

 

 

 

 

 

 

5.配置dbServer.xml配置文件

[root@amoeba ~]# vim /usr/local/amoeba/conf/dbServers.xml

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

6.启动amoeba

[root@amoeba ~]#/usr/local/amoeba/bin/amoeba start&

//后台运行,没有&’是前台运行的意思

[root@amoeba ~]#netstat -anpl|grep java

//可以查看到amoeba的监听端口,默认为8066,可以在amoeba.xml文件中修改端口


七、测试读写分离
1.客户机通过端口访问代理登陆mysql

cjenlet@cjenlet-u:~$ mysql -uamoeba -pabc123. -h 192.168.0.110 -P 8066

//确保客户端有mysql客户端工具,能够与整个网络互通,其他的不需要

 

 

 

 

 

 

 

 

 

注意:指定端口的P是大写的,否则永远过不去。

2.创建数据

a.本地登陆master主机mysql数据库,创建表cjenDB

mysql> use cjenlet;

mysql> create table cjenDB (id int(10),name varchar(10),address varchar(20));

mysql> describe cjenDB; //查看表结构


 

 

 

 

 

 

 

 

 

 

 

 

//这时slave1slave2都会同步这份数据,在它们上显示的结果是一样的

b.制造差异,以便后面区分读写分离的效果

先关掉slave1slave2slave功能

slave1:

mysql>stop slave;

slave2:

mysql>stop slave;

 

master,slave1slave2上分别在表cjenDB上插入不同的数据

master

mysql> insert into cjenDB values('1','cjenlet','this_is_master');

slave1

mysql> insert into cjenDB values('2','cjenlet','this_is_slave1');

slave2

mysql> insert into cjenDB values('3','cjenlet','this_is_slave2');


3.客户端访问数据库

a.负载均衡:

mysql>use cjenlet;

mysql>select * from cjenDB;

//如果没有出错的话,第一次查到的结果是slave1上表cjenDB的数据

//第二次查到的结果是slave2上表cjenDB的数据,方正多次查询结果是不一样的,分别是slave1slave2上的数据,这就是amoeba实现mysql负载均衡的体现。

//不过本人实现的过程中却没有这一现象出现,一直都是slave2的数据,不知道问题出在哪里

解决:

查看对比slave1slave2的相关配置文件

发现slave1/etc/hosts文件有一条打错,导致没有amoeba主机的ip记录

本机的ip地址配置文件/etc/sysconfig/network-scripts/ifcfg-eth2中的DEVICE=eth2也打成DEVICE=eth2: ,多打了一个冒号

把这些弄号后,发现还是client还是select不到slave1的数据

后来推断应该是之前的ip地址和hosts文件的出错导致主从同步时,master主机创建test用户时,slave1没有同步过来,所以只要在slave1上重新创建一次test用户即可

b.读写分离:

在客户端执行

mysql>insert into cjenDB values('4','cjenletC','this_is_client');

mysql>select * from cjenDB;

//这时客户端查到的结果是没有这一行内容的,而master主机上查到的结果是有的。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM