mysql主從複製與讀寫分離

主從複製以及主從複製的作用:
在實際的生產環境中,對數據庫的讀和寫都在同一個數據庫服務器中,是不能滿足實際需求的,通過主從複製的方式來同步數據,再通過讀寫分離來提升數據庫的併發負載能力

mysql主從複製與讀寫分離
.

mysql主從複製
mysql主從複製與讀寫分離
mysq支持的複製類型

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

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

  • 混合類型的複製。默認採用基於語句的複製,一旦發現基於語句無法精確複製時,就會採用基於行的複製。
    .
    複製的工作過程
    .
    *在每個事務更新數據完成之前,master在二進制日誌記錄這些改變。寫入二進制日誌完成後,master通知存儲引擎提交事務。
  • Slave將master的binary log複製到其中繼日誌。首先slave開始一個工作線程(I/O),I/O線程在master上打開一個普通的連接,然後開始binlog dump process。binlog dump process從master的二進制日誌中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件,I/O線程將這些事件寫入中繼日誌。

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

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

mysql主從複製與讀寫分離
前較爲常見的Mysql讀寫分離分爲以下兩種:
.

  • 基於程序代碼內部實現

    在代碼中根據select 、insert進行路由分類,這類方法也是目前生產環境下應用最廣泛的。優點是性能較好,因爲程序在代碼中實現,不需要增加額外的硬件開支,缺點是需要開發人員來實現,運維人員無從下手。
    .

  • 基於中間代理層實現

    代理一般介於應用服務器和數據庫服務器之間,代理數據庫服務器接收到應用服務器的請求後根據判斷後轉發到,後端數據庫,有以下代表性的程序。
    .
    環境介紹;
    mysql主從複製與讀寫分離

安裝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)

.
讀寫分離
mysql主從複製與讀寫分離

(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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章