主從複製以及主從複製的做用:
在實際的生產環境中,對數據庫的讀和寫都在同一個數據庫服務器中,是不能知足實際需求的,經過主從複製的方式來同步數據,再經過讀寫分離來提高數據庫的併發負載能力java
.mysql
mysql主從複製
mysq支持的複製類型linux
基於語句的複製。在服務器上執行sql語句,在從服務器上執行一樣的語句,mysql默認採用基於語句的複製,執行效率高。sql
基於行的複製。把改變的內容複製過去,而不是把命令在從服務器上執行一遍。數據庫
Slave將master的binary log複製到其中繼日誌。首先slave開始一個工做線程(I/O),I/O線程在master上打開一個普通的鏈接,而後開始binlog dump process。binlog dump process從master的二進制日誌中讀取事件,若是已經跟上master,它會睡眠並等待master產生新的事件,I/O線程將這些事件寫入中繼日誌。vim
MySQL讀寫分離原理
讀寫分離就是在主服務器上修改,數據會同步到從服務器,從服務器只能提供讀取數據,不能寫入,實現備份的同時也實現了數據庫性能的優化,以及提高了服務器安全。後端
前較爲常見的Mysql讀寫分離分爲如下兩種:
.centos
基於程序代碼內部實現緩存
在代碼中根據select 、insert進行路由分類,這類方法也是目前生產環境下應用最普遍的。優勢是性能較好,由於程序在代碼中實現,不須要增長額外的硬件開支,缺點是須要開發人員來實現,運維人員無從下手。
.安全
基於中間代理層實現
代理通常介於應用服務器和數據庫服務器之間,代理數據庫服務器接收到應用服務器的請求後根據判斷後轉發到,後端數據庫,有如下表明性的程序。
.
環境介紹;
安裝mysql過程不作解釋
(mysql。主)
[root@centos1 ]# mount /dev/cdrom /media/ [root@centos1 ]# yum -y install ntp
.
[root@centos1 ]# vim /etc/ntp.conf #restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap server 127.127.1.0 /添加 fudge 127.127.1.0 stratum 8 /添加 .
重啓ntpd服務 [root@centos1 ]# service ntpd restart
.
防火牆開例外 [root@centos1 ]# iptables -I INPUT -p udp --dport 123 -j ACCEPT [root@centos1 ]# iptables -I INPUT -p udp --dport 3306 -j ACCEPT
在(節點A)進行時間同步 [root@centos1 ]# yum -y install ntpdate [root@centos1 ]# /usr/sbin/ntpdate 192.168.1.30
在(節點B)進行時間同步 [root@centos1 ]# yum -y install ntpdate [root@centos1 ]# /usr/sbin/ntpdate 192.168.1.30
.
(mysql。主)
修改/etc/my.cnf配置文件 [root@centos1 ]# vim /etc/my.cnf
server-id = 11 //mysql數據的惟一標示(不能重複) log-slave-updates=true //容許連級複製 (增長) log-bin=master-bin //二進制文件名(修改)
.
重啓mysql服務 [root@centos1 ]# service mysqld restart
.
登錄mysql給從服務器受權 [root@centos1 ]# mysql -u root -p . mysql> GRANT REPLICATION SLAVE ON *.* TO 'lijialiang'@'192.168.1.%' IDENTIFIED BY '123456'; . mysql> FLUSH PRIVILEGES;
.
mysql> show master status; +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-bin.000001 | 558 | | | +-------------------+----------+--------------+------------------+ 1 row in set (0.03 sec)
.
(節點B,C)
在/etc/my.cnf中修改如下內容 [root@centos3 ~]# vim /etc/my.cnf server-id = 22 //不能與其餘實例重複 log-bin=mysql-bin //二進制日誌文件名 修改 relay-log=relay-log-bin //複製過來的二進制文件名,增長 relay-log-index=slave-relay-bin.index //中繼日誌存放的文件名稱,增長
.
重啓mysql服務 [root@centos1 ]# service mysql restart
.
登陸mysql 配置同步
[root@centos1 ]# mysql -u root -p mysql> change master to master_host='192.168.1.30',master_user='lijialiang',master_password='123456',master_log_file='master-bin.000001',master_log_pos=558; IP地址、用戶、密碼都master的數據庫信息
.
啓動同步 mysql> start slave;
.
查看slave狀態確保如下兩個值爲YES . mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.30 Master_User: lijialiang Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 558 Relay_Log_File: relay-log-bin.609531 Relay_Log_Pos: 254 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
.
(mysql。主)
.
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.11 sec)
.
mysql> create datebase IT; . mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | IT | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.11 sec)
.
(節點B,C)
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | IT | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.27 sec)
.
讀寫分離
(amoeba)
讀寫分離安裝java環境(amoeba軟件基於java平臺運行)
運行jdk
[root@centos1 ]# umount /dev/cdrom /media/ [root@centos1 ]# mount /dev/cdrom /media/ [root@centos1 ]# cp jdk-6u14-linux-x64.bin /usr/local/ [root@centos1 ]# cd /usr/local/ [root@centos1 ]# chmod +x jdk-6u14-linux-x64.bin [root@centos1 ]# ./jdk-6u14-linux-x64.bin 安裝過程當中提示(yes/no),咱們要選擇yes安裝
.
修改/etc/profile配置文件,增長如下配置 [root@centos1 ]# mv jdk1.6.0_14/ /usr/local/jdk1.6 [root@centos1 ]# vim /etc/profile
.
export JAVA_HOME=/usr/local/jdk1.6 //設置jdk的根目錄 export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib //將jdk的程序文件賦予CLASSPATH變量 export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$PATH:$HOME/bin //將jdk的程序文件賦予PATH變量 export AMOEBA_HOME=/usr/local/amoeba/ //定義AMOEBA的根目錄 export PATH=$PATH:$AMOEBA_HOME/bin //將amoeba的程序文件複製給PATH變量
.
執行腳本
[root@centos1 ]# source /etc/profile [root@centos1 ]# java -version
.
安裝並配置Amoeba軟件
安裝
[root@centos1 ]# mkdir /usr/local/amoeba [root@centos1 ]# cd /media/ [root@centos1 ]# ls [root@centos1 ]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ [root@centos1 ]# chmod -R 755 /usr/local/amoeba/
.
出現如下內容說明安裝成功了
[root@centos1 ]# /usr/local/amoeba/bin/amoeba amoeba start|stop .
配置amoeba讀寫分離,兩個從節點讀負載均衡 在主從服務器上開放權限給amoeba(三臺服務器上都作相同設置,這裏以一臺爲例) mysql> grant all on *.* to liang@'192.168.1.%' identified by '123456';
.
修改amoeba.xml文件
注意:全部配置文件註釋都是以 <!-- 內容 -->,再刪除註釋時請將內容也一併刪除,最好是刪除正行,可是有些時候只須要刪除頭和尾便可,裏面的配置項是能夠直接使用的。這個配置文件須要定義兩個配置,第一是應用程序使用什麼用戶鏈接amoeba訪問到後端的mysql數據庫,第二個是定義默認寫池以及讀池。
[root@centos1 ]# cd /usr/local/amoeba/ [root@centos1 ]# vim conf/amoeba.xml <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator"> <property name="user">amoeba</property> //這裏的賬戶名和密碼在後面連接amoeba使用 <property name="password">123456</property> <property name="filter"> ....................................................................... <property name="LRUMapSize">1500</property> <property name="defaultPool">master</property> //修改成master //注意:這裏原有註釋,須要刪除 <property name="writePool">master</property> //修改成master <property name="readPool">slaves</property> //修改成slaves <property name="needParse">true</property> . 編輯dbServers.xml [root@centos1 ]# vim conf/dbServers.xml <!-- mysql schema --> <property name="user">liang</property> //以前設置開放權限的用戶名和密碼 //注意刪掉此位置的註釋 <property name="password">123456</property> //注意刪掉此位置的註釋 </factoryConfig>
.............................................................................
<dbServer name="master" parent="abstractServer"> //修改成master <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.1.30</property> //修改IP </factoryConfig> </dbServer> <dbServer name="slave1" parent="abstractServer"> //修改成slave1 <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.1.40</property> //修改IP </factoryConfig> </dbServer> <dbServer name="slave2" parent="abstractServer"> //複製一份,修改成slave2 <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.1.50</property> //修改IP </factoryConfig> </dbServer> <dbServer name="slaves" virtual="true"> //修改成slaves <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> <property name="loadbalance">1</property> <!-- Separated by commas,such as: server1,server2,server1 --> <property name="poolNames">slave1,slave2</property> //修改成slave1,slave2 </poolConfig> </dbServer> </amoeba:dbServers>
.
.
啓動amoeba軟件
[root@centos1 ]# bin/amoeba start& [root@centos1 ]# netstat -anpt | grep java
.
測試讀寫分離
打開一臺客戶端192.168.1.10,也須要安裝mysql,做爲測試機,可使用yum -y install mysql安裝。
.
創建防火牆規則 [root@centos1 /]# iptables -I INPUT -p tcp --dport 8066 -j ACCEPT . amoeba,主服務器和兩個從節點,都須要開放3306端口入站 [root@centos1 /]# iptables -I INPUT -p tcp --dport 3306 -j ACCEPT [root@centos1 /]# service iptables save
.
也可修改amoeba的amoeba.xml配置文件的第一個8066改成3306以後創建一條防火牆規則爲容許3306端口入站而且從新啓動amoeba服務
<property name="port">3306</property> //在11行
這樣一來測試機訪問的時候後方就不用跟 P 8066 了
.
重啓服務 [root@centos1 ]# bin/amoeba restart&
測試階段
(客戶端)
[root@centos1 ]# mysql -u amoeba -p 123456 -h 192.168.1.20 P 8066 密碼123456,爲:以前登錄amoeba設置的密碼
在主服務器master上建立一個數據庫WLZS,同步到各從服務器上,而後關掉從服務器的slave功能,再插入數據。
(主服務器)
mysql> create database WLGCSZS; Query OK, 1 row affected (0.84 sec)
mysql> use WLGCSZS; Database changed
mysql> create table student(id int,name char(10)); Query OK, 0 rows affected (1.39 sec)
.
(從服務器查看同步)
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | WLGCSZS | | IT | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.27 sec)
.
(主服務器寫入數據)
mysql> insert into student values(1,'li'); Query OK, 1 row affected (0.48 sec)
.
(從服務器也同步了)
mysql> use WLGCSZS; Database changed mysql> select * from student; +------+------+ | id | name | +------+------+ | 1 | li | +------+------+ 1 row in set (0.45 sec)
.
在兩臺從服務器執行stop slave
分別在兩臺從服務器寫入不一樣數據
(節點A)
mysql> stop slave; Query OK, 0 rows affected (0.05 sec) mysql> use WLGCSZS; Database changed mysql> insert into student values(5,'jia'); Query OK, 1 row affected (0.07 sec)
.
(節點B)
mysql> stop slave; Query OK, 0 rows affected (0.05 sec) mysql> use WLGCSZS; Database changed mysql> insert into student values(6,'liang'); Query OK, 1 row affected (0.07 sec)
(客戶端查詢)
mysql> use WLGCSZS; Database changed mysql> select * from student; //第一次查詢顯示第一臺從服務器的用戶 +------+------+ | id | name | +------+------+ | 1 | li | | 4 | jia | +------+------+ 2 rows in set (0.00 sec)
mysql> select * from student; //第一次查詢顯示第二臺從服務器的用戶,說明負載均衡成功 +------+----------+ | id | name | +------+----------+ | 1 | li | | 5 | liang | +------+----------+ 2 rows in set (0.00 sec)
(客戶端寫入一條語句)
mysql> insert into student values(6,'asdf'); Query OK, 1 row affected (0.05 sec)
.
查詢不到剛寫入的語句,只有在主服務器能夠查到由於寫操做只有master有另外兩臺負責讀取數據
mysql> select * from student; +------+------+ | id | name | +------+------+ | 1 | jia | | 4 | abcd | +------+------+ 2 rows in set (0.00 sec)
(客戶端查詢)
mysql> use WLGCSZS; mysql> select * from student; +------+-------+ | id | name | +------+-------+ | 1 | li | | 5 | jia | | 6 | liang | +------+-------+ 4 rows in set (0.00 sec)