mysql的主從複製以及讀寫分離

mysql的主從複製以及讀寫分離

前言:我們前面搭建過LAMPLNMP,做過了web服務器羣集和熱備,web服務器壞了我們是不怕了,但是我們要知道,網站的數據有很多是存儲在數據庫裏面的,例如註冊的會員,發的文章,購物的訂單等信息。當然我們可以給數據庫做備份,但是如果每天00:00做一次備份,那麼如果在23:59數據丟失了,那麼就會丟失一天的數據,有沒有一種方法能實現實時備份,就是說有數據產生就立即備份,答案當然是有,也就是今天我們要學習的mysql主從複製。有點類似於前面我們學習過的rsync,但是不同的是rsync是對磁盤文件做備份,而mysql主從複製是對數據庫中的數據,語句做備份。另外讀寫分離主要是爲了優化數據庫。下面把實驗給大家做一遍。

 

一、mysql主從複製的工作原理

1、mysq支持的複製類型

1)基於語句的複製。在服務器上執行sql語句,在從服務器上執行同樣的語句,mysql默認採用基於語句的複製,執行效率高。

2)基於行的複製。把改變的內容複製過去,而不是把命令在從服務器上執行一遍。

3)混合類型的複製。默認採用基於語句的複製,一旦發現基於語句無法精確複製時,就會採用基於行的複製。

原理工作試圖:

通俗易懂的說法就是:

(1)在主MySQL服務器數據修改之後數據文件記錄在Binary log日誌當中

(2)從服務器的i/o線程連接到主MySQL服務器的Binary log的日誌當中獲取當中發生變化的數據內容

(3)將獲取到的內容寫入到自己的Relay log日誌當中

(4)通過從服務器的自身sql線程讀取Relay log日誌當中的內容進行同步

(5)mysql服務器之間的數據同步主要是通過日誌的方式進行同步的,並非是通過命令或是複製內容

wKioL1kAqUmzvxcYAABhiZJVKVo678.png-wh_50 

以下內容是官方的專業術語:

1)在每個事務更新數據完成之前,master在二進制日誌記錄這些改變。寫入二進制日誌完成後,master通知存儲引擎提交事務。

2)Slavemasterbinary log複製到其中繼日誌。首先slave開始一個工作線程(I/O),I/O線程在master上打開一個普通的連接,然後開始binlog  dump  processbinlog  dump  processmaster的二進制日誌中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件,I/O線程將這些事件寫入中繼日誌。

3)Sql  slave  threadsql從線程)處理該過程的最後一步,sql線程從中繼日誌讀取事件,並重放其中的事件而更新slave數據,使其與master中的數據一致,只要該線程與I/O線程保持一致,中繼日誌通常會位於os緩存中,所以中繼日誌的開銷很小。

 

3、mysql讀寫分離原理

讀寫分離就是在主服務器上修改,數據會同步到從服務器,從服務器只能提供讀取數據,不能寫入,實現備份的同時也實現了數據庫性能的優化,以及提升了服務器安全。

接下來進行主從複製的案例如下圖:

wKioL1kAqWqjCp9RAAB7QvjJurY014.png-wh_50 

搭建mysql主從複製

1.建立時間同步環境,在主節點上搭建時間同步服務器

1)安裝NTP

[root@centos2 ~]# yum -y install ntp

wKioL1kAqYOyCJUyAAADCdzPysY947.png-wh_50 

2)配置NTP

[root@centos2 ~]# vim /etc/ntp.conf

server 127.127.1.0                        //上游時間服務器爲本機

fudge 127.127.1.0 stratum 8//允許與上級時間服務器的時間偏移

wKioL1kAqZbh6bMEAAAJtcTFNPc438.png-wh_50 

3)重啓服務

[root@centos2 ~]# service ntpd restart

wKioL1kAqajRVymxAAAIFFRyTkE899.png-wh_50 

2.在從節點上進行時間同步mysql從服務器兩臺都如此)

[root@centos3 ~]# yum  -y  install  ntpdate

[root@centos3 ~]# /usr/sbin/ntpdate  192.168.1.2

wKiom1kAqbzD9logAAACx7FzzpQ114.png-wh_50 wKioL1kAqc2QZ5j6AAAPSq_aajo064.png-wh_50

3.關閉每臺服務器防火牆  service  iptables stop

4.安裝mysql過程略 本節內容不在講解mysql的安裝可以查看本人的mysql技術文檔和LNMPLAMP文檔;裏面有詳細的內容

5.啓動mysql

wKiom1kAqePRIQA8AAAK1GcPa24634.png-wh_50 

6.配置mysql主服務器

1)在/etc/my.cnf中修改或增加下面內容

server-id       = 11  //修改

log-bin=master-bin    //修改,啓用二進制日誌,日誌文件名稱前綴

log-slave-updates=true  //增加,允許從服務器複製

wKioL1kAqfTyODVyAAASqrSlWdA988.png-wh_50 wKioL1kAqgWzcs2VAAAJ0W3svWk528.png-wh_50

2)重啓mysql服務

[root@centos2 ~]# service mysqld restart

wKiom1kAqhbgrc2_AAAH4Xy5bUM757.png-wh_50 

3)登錄mysql程序,給從服務器以授權

[root@centos2 ~]# mysql -u root -p

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

mysql> flush  privileges;

mysql> show  master  status;

+-------------------+----------+--------------+------------------+

| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+-------------------+----------+--------------+------------------+

| master-bin.000007 |      337|              |                  |

+-------------------+----------+--------------+------------------+

1 row in set (0.00 sec)

wKioL1kAqijixVfQAAARnGxUOoU711.png-wh_50 wKiom1kAqjiSdOKlAAAaSpBdmoA621.png-wh_50

7.配置兩臺從服務器

1)在第一臺從服務器/etc/my.cnf中修改或增加下面內容

server-id       = 22  //修改

relay-log=relay-log-bin //增加

relay-log-index=slave-relay-bin.index  //增加

wKioL1kAqkuxVBefAAAKGHvDAFU585.png-wh_50 

2)重啓mysql服務

[root@centos3 ~]# service mysqld restart

wKioL1kAqlzRMH7rAAAFyW5NtnU197.png-wh_50 

3)第二臺從服務器只是server-id不同其他都和第一臺一樣

server-id       = 33

wKiom1kAqnORvZREAAAEgxQ0oqw752.png-wh_50 

完成後重啓mysql服務

wKiom1kAqoTzHiHHAAAFyW5NtnU048.png-wh_50 

4)登錄mysql,配置同步

mysql>change  to master master_host='192.168.1.2',master_user='myslave',master_password='123456',master_log_file='master-bin.000002',master_log_pos=412; 可以變動

wKioL1kAqprAWoC4AAAJuDWJhzA629.png-wh_50 

5)啓動同步

mysql> start slave;

wKioL1kAqqugGM2PAAAECDrpM5Q044.png-wh_50 

6)查看slave狀態,確保以下兩個至爲YES

mysql> show slave status \G;

  Slave_IO_Running: Yes

  Slave_SQL_Running: Yes

wKiom1kAqr7jd39jAAAQcH1AM7g955.png-wh_50 

7)驗證主從複製效果

①在主、從服務器上登錄mysql

[root@centos2 ~]# mysql -u root -p

②在主服務器上新建數據庫db_test

mysql> create database db_tese;

wKioL1kAqs-hjF57AAAEfi6nYpk293.png-wh_50 

③在兩臺從服務器上查看數據庫

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| db_test           |

| mysql              |

| performance_schema |

| test               |

+--------------------+

5 rows in set (0.02 sec)

wKiom1kAquPjATp9AAAPogxOro0859.png-wh_50

實驗二、構建mysql讀寫分離,此內容爲讀寫分離:

1.在主機amoeba上安裝java環境

[root@centos1 ~]# cp /mnt/jdk-6u14-linux-x64.bin /usr/local/

wKioL1kAqvqDQtqCAAAJJCyKayk525.png-wh_50 

[root@centos1 ~]# chmod +x /usr/local/jdk-6u14-linux-x64.bin

wKioL1kAqwjC1uIxAAAEo8P9Xh0072.png-wh_50 

[root@centos1 local]# cd /usr/local/

wKioL1kAqxnhK566AAAI9MKHKDQ775.png-wh_50 

[root@centos1 local]# ./jdk-6u14-linux-x64.bin  //根據提示按回車和yes即可

wKioL1kAqzDiD0EAAAADWkM56Jw470.png-wh_50 

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

wKiom1kAqz_h6ZFzAAAcCt2qj_o421.png-wh_50 

wKioL1kAq1HROoBVAAAGwNjlsPI649.png-wh_50 

export  JAVA_HOME=/usr/local/jdk1.6

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@centos1 local]# mv jdk1.6.0_14/  /usr/local/jdk1.6

wKiom1kAq2KSzOI9AAAD8kqa8iE530.png-wh_50 

[root@centos1 local]# java -version

java version "1.6.0_14

OpenJDK Runtime Environment (rhel-2.4.3.3.el6-x86_64 u45-b15)

OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)

java環境已經成功

wKiom1kAq3XxPjynAAAPaYlHANA100.png-wh_50 

 

安裝並配置amoeba軟件

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

wKioL1kAq4yDSfZyAAAD1nvNxDQ509.png-wh_50 

[root@centos1 local]# tar zxf  /mnt/amoeba-mysql-binary-2.2.0.tar.gz  -C  /usr/local/amoeba

wKioL1kAq5vhwGR6AAAFrU5ezPg126.png-wh_50 

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

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

wKioL1kAq66TWmbkAAAGTIavgLs534.png-wh_50 

3.配置amoeba讀寫分離,兩個slave讀負載均衡

masterslave1slave2中開放權限給amoeba訪問

mysql> grant all on *.* to 'test'@'192.168.1.%' identified by '123.com';

wKiom1kAq7_yRnTRAAAGU1DkcDo112.png-wh_50 

②編輯amoeba.xml配置文件.注意修改紅色下劃線處

28 <property name="user">amoeba</property>

30 <property name="password">123456</property>

wKiom1kAq9WTvnc_AAAK2TwhM0E292.png-wh_50 

113 <property name="defaultPool">master</property>

115 <property name="writePool">master</property>

116 <property name="readPool">slaves</property>

wKiom1kAq-ezUAX3AAAJQKiwGKE776.png-wh_50 

③編輯dbServer.xml配置文件

26<property name="user">test</property>

29<property name="password">123.com</property>

wKioL1kAq_zRhKpCAAAGZyv5kco384.png-wh_50 

45 <dbServer name="master"  parent="abstractServer">

wKioL1kArA2zZsPlAAAFEYtn-1g187.png-wh_50 

46<factoryConfig>

47 <!-- mysql ip -->

48 <property name="ipAddress">192.168.1.2</property>

wKiom1kArB-grAUXAAAFBZqXobc768.png-wh_50 

49 </factoryConfig>

50 </dbServer>

52 <dbServer name="slave1"  parent="abstractServer">

53 <factoryConfig>

54 <!-- mysql ip -->

55<property name="ipAddress">192.168.1.3</property>

56</factoryConfig>

wKioL1kArDGxrTCHAAAMpjE3p_I691.png-wh_50 

57</dbServer>

58<dbServer name="slave2"  parent="abstractServer">

59<factoryConfig>

60<!-- mysql ip -->

61<property name="ipAddress">192.168.1.4</property>

62</factoryConfig>

wKioL1kArEODpVWFAAAK4FfpHq8144.png-wh_50 

63</dbServer>

65<dbServer name="slaves" virtual="true">

wKiom1kArFSCKv-ZAAAD2R1fITk164.png-wh_50 

66<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">

67 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->

68 <property name="loadbalance">1</property>

70<!-- Separated by commas,such as: server1,server2,server1 -->

71<property name="poolNames">slave1,slave2</property>

wKiom1kArGfhLhOzAAADviJrvg0752.png-wh_50 

72</poolConfig>

73</dbServer>

④配置無誤後,可以啓動amoeba軟件,默認端口爲tcp8066

wKioL1kArHmQA2GBAAAVfv9QGRE356.png-wh_50 

[root@centos1 amoeba]# bin/amoeba start &

4.測試

①在client主機上

#yum  -y  install  mysql

然後通過代理訪問mysql  本機如果已安裝可不用安裝

[root@centos1 ~]# mysql -u amoeba -p123456 -h 192.168.1.1 -P8066  (-P爲大寫)

wKioL1kArIuC_W4pAAAgsZd1N50220.png-wh_50 

②在master上創建一個表,同步到各個從服務器上,然後關掉各從服務器的slave功能,再插入區別語句

mysql> use db_lxf

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

wKiom1kArJ-xcEeXAAAM9bKkWbE998.png-wh_50 

③分別在兩臺從服務器上

mysql>stop slave;

wKioL1kArLmyE3o2AAAEkbLN3NU065.png-wh_50 

④然後在主服務器上插入數據

mysql> insert inot zang values('1','zhang','this_is_master');

wKioL1kArMzxevAyAAAGLzfDhjw716.png-wh_50 

⑤從服務器同步了表,手動插入其他內容

slave1

mysql> use db_lxf

mysql> insert into zang values('2','zhang','this_is_slave1');

wKioL1kArN7Dr_J9AAAfjPa5sR0848.png-wh_50 

slave2

mysql> use db_lxf

mysql> insert into zang values('2','zhang','this_is_slave2');

wKiom1kArPGRihOoAAAFy7ZUEk0332.png-wh_50 

⑥測試讀操作

client主機上第一次查詢的結果如下:

mysql> use db_lxf

mysql> select * from zang;

+------+-------+----------------+

| id   | name  | address        |

+------+-------+----------------+

|    3 | zhang | this_is_slave1 |

+------+-------+----------------+

1 row in set (0.03 sec)

第二次查詢結果如下:

mysql> select * from zang;

+------+-------+----------------+

| id   | name  | address        |

+------+-------+----------------+

|    2 | zhang | this_is_slave2 |

wKioL1kArQWzwFx-AAASe8YEVuo627.png-wh_50 

測試寫操作在客戶端:

mysql> insert into zang values('4','zhang','write_test');

但是在客戶機上查詢不到

最終只能在主服務器上才能看到這條語句內容,說明寫操作在master服務器上

mysql> select * from zang;

+------+-------+----------------+

| id   | name  | address        |

+------+-------+----------------+

|    1 | zhang | this_is_master |

|    4 | zhang | write_test     |

+------+-------+----------------+

2 rows in set (0.03 sec)

wKioL1kArRiCUaYlAAAFZXwoFi4701.png-wh_50 

在主服務器mysql上進行驗證:

wKiom1kArSiwsemjAAAMGLoPQng739.png-wh_50 

 

其他兩個從服務器上查看:

wKioL1kArUXDX6XpAAAkm4I-Iek776.png-wh_50 

wKioL1kArVvzEuuDAAAMr8buIuc808.png-wh_50 

http://xiaorenwutest.blog.51cto.com/12754924/1920259

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章