MySQL主從複製與讀寫分離前端
1、簡介java
MySQL主從複製和讀寫分離二者有着緊密的聯繫,只有部署好主從複製了,才能在此基礎上進行數據庫的讀寫分離。mysql
1.MySQL支持的複製類型linux
a.基於語句的複製。sql
b.基於行的複製。shell
c.混合類型的複製。默認基於語句複製,當基於語句的複製沒法精確複製時,就會採用基於行的複製。數據庫
2.讀寫分離vim
只在主服務器上寫,從服務器上讀。基本原理就是讓主數據庫處理事務性查詢,而從服務器處理select查詢。set global read_only=0;服務器
目前常見的MySQL讀寫分離有兩種:網絡
a.基於程序代碼內部實現
在代碼中根據select、insert進行路由分類。有點是性能好,不須要增長額外的設備做爲硬件開支;缺點是須要開發人員實現,運維人員無從下手。
b.基於中間代理實現
1)MySQL-Proxy。
2)Amoeba,由陳思儒開發,做者曾就任阿里巴巴,阿里巴巴將其應用於生產環境中。這個軟件致力於mysql的分佈式數據庫前端代理層,它主要爲應用層訪問mysql的時候充當sql路由功能,並具有有負載均衡、高可用性、sql過濾、讀寫分離、可路由相關的到目標數據庫,可併發請求多臺數據庫,不過它不支持事務和存儲過程。
2、案例環境
系統: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
3、環境準備
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地址
4、安裝MySQL數據庫
1.在master,slave1,slave2上安裝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用戶設置密碼
5、規劃配置主從服務器,驗證主從複製。
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;
//master,slave1,slave2,上分別查看,的到的結果是同樣的,都有新建的cjenlet數據庫存在
6、搭建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用戶就能夠了,由於slave1和slave2都會同步的。
//只賦予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文件中修改端口
7、測試讀寫分離
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; //查看錶結構
//這時slave1和slave2都會同步這份數據,在它們上顯示的結果是同樣的
b.製造差別,以便後面區分讀寫分離的效果
先關掉slave1和slave2的slave功能
slave1:
mysql>stop slave;
slave2:
mysql>stop slave;
master,slave1和slave2上分別在表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的數據,方正屢次查詢結果是不同的,分別是slave1和slave2上的數據,這就是amoeba實現mysql負載均衡的體現。
//不過本人實現的過程當中卻沒有這一現象出現,一直都是slave2的數據,不知道問題出在哪裏
解決:
查看對比slave1和slave2的相關配置文件
發現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主機上查到的結果是有的。