Window環境下mysql主從同步以及讀寫分離

(1)基本的理論知識:

首先,要實現mysql的讀寫分離,可以使用mysql的主(master)從(slave)複製(Replication)來實現:

主(master)庫只提供寫數據的服務,而從(slave)庫只提供讀數據的服務。

什麼是主從複製?

簡單來說,就是主(master)庫把對數據改動的操作保存到一個文件裏面,而從(slave)庫會隔一個時間間隔根據這個文件更新自己的數據

(所以讀到的數據是有延遲的,這個延遲取決於從(slave)庫設置的時間間隔)

關於主從複製的詳細內容,可以問度娘

(2)實際操作步驟:

使用以下三臺電腦:

主庫(master)的IP:192.168.1.65

從庫1(slave)的IP:192.168.1.49

從庫2(slave)的IP:192.168.1.64

三臺電腦都安裝了MySQL5.5(實驗室的電腦,版本比較老~)

然後把三臺電腦的mysql服務停掉

A.打開主庫(master)的mysql安裝目錄,打開配置文件my.ini

這裏寫圖片描述

B.在[mysql]的後面添加如下代碼:

?

1

2

3

4

5

server-id=1 #master的標示

log-bin=mysql-bin #slave會基於此log-bin來做replication

binlog-do-db=test #用於master-slave的具體數據庫

binlog_ignore_db=mysql #不用於master-slave的具體數據庫

binlog_ignore_db=information_schema #和binlog-do-db一樣,可以設置多個

C.打開主庫(master)的mysql服務,進入mysql的命令行,輸入如下代碼:

?

1

show master status;

這裏寫圖片描述

重要:記下File(日誌文件)和Position 分別給兩個從庫複製權限(上圖中的)

1

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

其中的’slave’爲登錄賬號,’123456’爲密碼,’192.168.1.%’爲從庫的IP(這裏偷懶使用了通配符~)

這裏寫圖片描述

E.打開從庫1的mysql安裝目錄,打開配置文件my.ini,在[mysql]的後面添加如下代碼:

?

1

2

3

server-id=2 #比剛剛主庫設定的server-id大就行了,且從庫之間不能有一樣

log-bin=mysql-bin #slave會基於此log-bin來做replication

replicate-do-db=test #用於master-slave的具體數據庫

保存後啓動從庫1的mysql服務,進入mysql的命令行,輸入如下代碼:

先停止它的slave:

?

1

stop slave;

再改變它的master:

?

1

2

3

4

5

6

change master to master_host='192.168.1.65',

master_port=3306,

master_user='slave',

master_password='123456',

master_log_file='mysql-bin.000040',上面紅色部分File

master_log_pos=717;上面紅色部分Position

這裏寫圖片描述

再啓動它的slave:

1

start slave;

然後再輸入如下代碼,檢查是否成功:

1

show slave status\G;

這裏寫圖片描述

如果看到上面這句話的,那就沒問題了~

當然你也可以在主庫(master)上做修改數據的操作,看看從庫會不會更新~(注意:從庫(slave)的數據庫需要自己手動創建)

F.對從庫2的操作和從庫1的基本一樣

打開配置文件my.ini,在[mysql]的後面添加如下代碼:

?

1

2

3

server-id=3 #比剛剛主庫設定的server-id大就行了,且從庫之間不能有一樣

log-bin=mysql-bin #slave會基於此log-bin來做replication

replicate-do-db=test #用於master-slave的具體數據庫

因爲從庫1的server-id爲2,所以從庫2的server-id不能爲2

保存後啓動從庫2的mysql服務。

注意要再從主庫上獲取一次最新的File(日誌文件)和Position(日誌位置)

這裏寫圖片描述

先停止它的slave:

1

stop slave;

再改變它的master:

1

2

3

4

5

6

change master to master_host='192.168.1.65',

master_port=3306,

master_user='slave',

master_password='123456',

master_log_file='mysql-bin.000040',

master_log_pos=1751;

剩下的操作和從庫1一毛一樣~

G.到這裏,mysql的讀寫分離就完成了~

但是這樣不夠方便,因爲我們寫數據時需要連接主庫,而讀數據時需要連接從庫。在連接從庫時,不能負載均衡。

這時候就要靠神器Amoeba了~

它就像一箇中轉站,將所有的寫請求分配給主庫,讀請求分配給從庫,並且在從庫之間實現負載均衡,丟個官網的圖~

這裏寫圖片描述

H.配置Amoeba服務器:

這裏最好找另外的一臺電腦充當Amoeba服務器:192.168.1.62

博主使用的版本是amoeba-mysql-3.0.5-RC-distribution,鏈接如下:

下載鏈接

下載完成後解壓,打開conf文件夾,配置amoeba.xml和dbServer.xml:

amoeba.xml:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

    <proxy>

        <!-- service class must implements com.meidusa.amoeba.service.Service -->

        <service class="com.meidusa.amoeba.mysql.server.MySQLService" name="Amoeba for Mysql">

            <!-- amoeba代理端口號 -->

            <property name="port">8066</property>

            <!-- amoeba服務器IP地址 -->

            <property name="ipAddress">192.168.1.62</property>

            <property name="connectionFactory">

                <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">

                    <property name="sendBufferSize">128</property>

                    <property name="receiveBufferSize">64</property>

                </bean>

            </property>

            <property name="authenticateProvider">

                <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">

                    <!-- amoeba服務器用戶名 -->

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

                    <!-- amoeba服務器密碼 -->

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

                    <property name="filter">

                        <bean class="com.meidusa.toolkit.net.authenticate.server.IPAccessController">

                            <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>

                        </bean>

                    </property>

                </bean>

            </property>

        </service>

        <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">

            <!-- proxy server client process thread size -->

            <property name="executeThreadSize">128</property>

            <!-- per connection cache prepared statement size  -->

            <property name="statementCacheSize">500</property>

            <!-- default charset -->

            <property name="serverCharset">utf8</property>

            <!-- query timeout( default: 60 second , TimeUnit:second) -->

            <property name="queryTimeout">60</property>

        </runtime>

    </proxy>

    <!--

        Each ConnectionManager will start as thread

        manager responsible for the Connection IO read , Death Detection

    -->

    <connectionmanagerlist>

        <connectionmanager class="com.meidusa.toolkit.net.MultiConnectionManagerWrapper" name="defaultManager">

            <property name="subManagerClassName">com.meidusa.toolkit.net.AuthingableConnectionManager</property>

        </connectionmanager>

    </connectionmanagerlist>

        <!-- default using file loader -->

    <dbserverloader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">

        <property name="configFile">${amoeba.home}/conf/dbServers.xml</property>

    </dbserverloader>

    <queryrouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">

        <property name="ruleLoader">

            <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">

                <property name="ruleFile">${amoeba.home}/conf/rule.xml</property>

                <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>

            </bean>

        </property>

        <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>

        <property name="LRUMapSize">1500</property>

       <!-- 設定默認節點-->

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

        <!-- 設定可寫節點-->

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

        <!-- 設定只讀節點-->

        <property name="readPool"> multiPool </property>

        <property name="needParse">true</property>

    </queryrouter>

</amoeba:configuration>

dbServers.xml:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

        <!--

            Each dbServer needs to be configured into a Pool,

            If you need to configure multiple dbServer with load  balancing that can be simplified by the following configuration:

             add attribute with name  virtual = "true" in  dbServer, but the configuration does not allow the element with name  factoryConfig

             such as 'multiPool'  dbServer  

        -->

    <dbserver abstractive="true" name="abstractServer">

        <factoryconfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">

            <property name="connectionManager">${defaultManager}</property>

            <property name="sendBufferSize">64</property>

            <property name="receiveBufferSize">128</property>

            <!-- mysql port(數據庫端口) -->

            <property name="port">3306</property>

            <!-- mysql schema(數據庫名稱,數據庫中必須存在此數據庫) -->

            <property name="schema">test</property>

            <!-- mysql user(控制數據庫用戶名) -->

            <property name="user">proxy</property>

            <!-- mysql password(控制數據庫密碼) -->

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

        </factoryconfig>

        <poolconfig class="com.meidusa.toolkit.common.poolable.PoolableObjectPool">

            <property name="maxActive">500</property>

            <property name="maxIdle">500</property>

            <property name="minIdle">1</property>

            <property name="minEvictableIdleTimeMillis">600000</property>

            <property name="timeBetweenEvictionRunsMillis">600000</property>

            <property name="testOnBorrow">true</property>

            <property name="testOnReturn">true</property>

            <property name="testWhileIdle">true</property>

        </poolconfig>

    </dbserver>

       <!-- 主數據庫配置 -->

 

    <dbserver name="master" parent="abstractServer">

        <factoryconfig>

            <!-- mysql ip -->

            <property name="ipAddress">192.168.1.65</property>

        </factoryconfig>

    </dbserver>

    <!-- 從數據庫配置 -->

    <dbserver name="slave1" parent="abstractServer">

        <factoryconfig>

            <!-- mysql ip -->

            <property name="ipAddress">192.168.1.64</property>

        </factoryconfig>

    </dbserver>

    <dbserver name="slave2" parent="abstractServer">

        <factoryconfig>

            <!-- mysql ip -->

            <property name="ipAddress">192.168.1.49</property>

        </factoryconfig>

    </dbserver>

    <!-- 定義虛擬服務器組,即只讀池 -->

    <dbserver name="multiPool" virtual="true">

        <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>

        </poolconfig>

    </dbserver>

</amoeba:dbservers>

I.給Amoeba授權:

分別到主庫、從庫1、從庫2的mysql控制檯下給Amoeba服務器授權,代碼如下:

1

grant all  on  *.* to 'proxy'@'192.168.1.62' identified by '123456';

這裏的賬號和密碼必須和dbServers.xml中的配置一毛一樣:

這裏寫圖片描述

連接Amoeba數據庫,這裏的賬號、密碼、Ip、端口必須和amoeba.xml的配置一毛一樣:

這裏寫圖片描述

然後使用這個連接對數據庫test做數據修改操作,再到主庫從庫上面查看是否有同步修改,如果有,那就完成了讀寫分離~

如果想看看有沒有實現負載均衡,可以打開Amoeba安裝目錄的logs/root.log查看查詢日誌。

然後我們的應用就可以通過連接Amoeba服務器來訪問數據庫中的數據了

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