Mysql主從同步 讀寫分離java
目錄mysql
一.概述4linux
二. 實驗目的4sql
三.試驗環境4數據庫
四. 方案說明4安全
3. 主從同步配置5負載均衡
3. 修改amoeba的配置文件amoeba.xml和dbServers.xml的配置。14
一.概述
Amoeba是一個以MySQL爲底層數據存儲,並對應用提供MySQL協議接口的proxy。它集中地響應應用的請求,依據用戶事先設置的規則,將SQL請求發送到特定的數據庫上執行。基於此能夠實現負載均衡、讀寫分離、高可用性等需求。與MySQL官方的MySQL Proxy相比,做者強調的是amoeba配置的方便(基於XML的配置文件,用SQLJEP語法書寫規則,比基於lua腳本的MySQL Proxy簡單)。
實際的生產環境中,由單臺Mysql做爲獨立的數據庫是徹底不能知足實際需求的,不管是在安全性,高可用性以及高併發等各個方面。經過主從同步(Master-Slave)的方式來同步數據,再經過讀寫分離(amobe)來提高數據庫的併發負載能力。
部署MySQL主從同步與讀寫分離,同時能夠使咱們真正的瞭解其內部工做原理,更好的認識安暢雲數據庫,快速定位故障並及時解決,爲客戶提供更專業的IT服務。
設備名稱 |
管理IP |
操做系統 |
用途 |
Slave1 |
172.16.200.82 |
Centos 6.5 64bit |
Mysql5.1.73 |
Slave2 |
172.16.200.80 |
Centos 6.5 64bit |
Mysql5.1.73 |
amoeba-mysql-master |
172.16.200.81 |
Centos 6.5 64bit |
Amobe 3.0.5 Mysql5.1.73 |
初始配置:關閉防火牆或將3306與8066添加例外,關閉Selinux。
本方案爲利用amobe實現mysql數據庫讀寫分離,提高數據庫併發負載能力,同時配置mysql主從同步,增長數據庫安全性和高可用性能。
主從服務器均安裝MySQL,並設置開機自啓動。
Yum install mysql mysql-devel mysql-server
/etc/init.d/mysqld start
Chkcofig mysqld on
分別設置MySQL數據庫密碼爲123.com
mysqladmin -u root password "123.com"
注:
全部機器的MySQL數據庫密碼要相同,amoeba配置要求。
mysql> grant all privileges on *.* to root@"172.16.200.%" identified by "123.com";
mysql> flush privileges;
注:
我這裏爲配置簡單,將root用戶開啓遠程登陸,在生產環境中建議新建MySQL用戶並設置相關的登陸權限。例如:限制源IP,容許訪問的庫文件等。
(1). 在amoeba-mysql-master上建立數據庫文件
相關操做命令以下:
create database 數據庫名稱; //建立數據庫
Use 數據庫; //改變所使用的數據庫
create table 表名稱(字段名稱 數據類型);//建立表
description 表名稱; //查看錶結構
select 字段 from 表; //數據庫查詢
查看amoeba-mysql-master目前數據庫列表文件是否建立成功
(2). 分別修改主從服務器的MySQL配置文件對新建數據庫master_test文件進行同步。
修改amoeba-mysql-master服務器的/etc/my.cnf文件配置以下:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
log-bin=mysql-bin #打開mysql二進制日誌
server-id=1 #設置mysql_id,主從不能相同
binlog-do-db=master_test #設置二進制日誌記錄的庫
binlog-ignore-db=mysql ##設置二進制日誌不記錄的庫
sync_binlog=1
symbolic-links=0
# Disabling symbolic-links is recommended to prevent assorted security risks
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
修改slave1服務器/etc/my.cnf配置以下:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
log-bin=mysql-bin
server-id=2
master-user=root
master-host=172.16.200.81
master-password=123.com
master-port=3306
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
修改slave1服務器/etc/my.cnf配置以下:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
log-bin=mysql-bin
server-id=3
master-user=root
master-host=172.16.200.81
master-password=123.com
master-port=3306
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
注:MySQL主與MySQL從服務器server-id 不能相同,MySQL主的ID爲1,其餘從服務器的ID均未1如下,保證不相同便可。
(2). 進行數據同步
將amoeba-mysql-master服務器MySQL數據master_test數據庫打包分別copy到從服務器MySQL數據目錄/var/lib/mysql/下,並進行解壓。拷貝打包好的數據能夠使用scp命令。
scp master_test.tar.gz root@172.16.200.82:/var/lib/mysql/
scp master_test.tar.gz root@172.16.200.83:/var/lib/mysql/
數據解壓完成分別登陸主從服務器查看數據庫主從同步狀態
首先查看master服務器狀態
mysql> show master status;
其次查看slave1和slave2的狀態。分別以下:
mysql> show slave status \G
Slave1狀態以下:
Slave2狀態以下:
(3). 主從同步測試
在amoeba-mysql-master服務器的MySQL新建數據庫文件master_test數據口中新建表tongbu進行測試。
測試數據庫同步配置已完成。
登錄amoeba官網下載相應的版本https://sourceforge.net/projects/amoeba/files/,我這裏下載的是amoeba-mysql-3.0.5-RC-distribution.zip。
將下載好的amoeba解壓至相應的目錄並修改相應的名稱,我這裏講amoeba解壓到了當前用戶目錄下,並改名爲amoeba-mysql-3.0.5-RC,
至此amoeba安裝完成,後面根據須要進行配置文件修改便可。
由於amoeba爲java語言開發,因此須要安裝jdk運行環境。咱們使用yum安裝jdk1.6
yum list available java* (查看java安裝包)
yum install java-1.6.0-openjdk(這裏安裝java1.6)
配置環境變量:
java路徑爲/usr/bin/java, 編輯amoeba bin/下的啓動程序launcher(3.0以上版本)或者amoeba(3.0如下版本)添加以下變量JAVA_HOME=/usr。
(1). 修改後的amoeba.xml的配置文件以下:
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">
<amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">
<proxy>
<!-- service class must implements com.meidusa.amoeba.service.Service -->
<service name="Amoeba for Mysql" class="com.meidusa.amoeba.mysql.server.MySQLService">
<!-- port -->
<property name="port">8066</property> #服務端口
<!-- bind ipAddress -->
<property name="ipAddress">172.16.200.81</property> #主機地址(amoeba)
<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">
<property name="user">root</property> #(amoeba的用戶名)
<property name="password">root</property> #(amoeba的密碼)
<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 name="defaultManager" class="com.meidusa.toolkit.net.MultiConnectionManagerWrapper">
<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">write</property>
<property name="writePool">write</property>
<property name="readPool">read</property>
<property name="needParse">true</property>
</queryRouter>
</amoeba:configuration>
注:對於amoeba.xml配置須要注意修改的地方,主要是管理IP地址和amoeba的服務管理方式截圖以下:
確認池名稱要與dbServer.xml中的名稱相同
(2). 修改後的dbServers.xml的配置文件以下:
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd">
<amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/">
<!--
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 name="abstractServer" abstractive="true">
<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服務端口
<!-- mysql schema -->
<property name="schema">master_test</property> #須要作讀寫分離的庫文件
<!-- mysql user -->
<property name="user">root</property> #MySQL用戶名
<property name="password">123.com</property> #MySQL密碼
</factoryConfig>
<poolConfig class="com.meidusa.toolkit.common.poolable.PoolableObjectPool">
<property name="maxActive">500</property>
<property name="maxIdle">500</property>
<property name="minIdle">10</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="server1" parent="abstractServer"> #命令dbServer
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">172.16.200.81</property> #dbServer 管理IP(主)
</factoryConfig>
</dbServer>
<dbServer name="server2" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">172.16.200.82</property> #dbServer 管理IP(從)
</factoryConfig>
</dbServer>
<dbServer name="server3" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">172.16.200.80</property> #dbServer 管理IP(從)
</factoryConfig>
</dbServer>
<dbServer name="write" virtual="true"> #write是一個虛擬的數據庫的寫節點
<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">server1</property>
</poolConfig>
</dbServer>
<dbServer name="read" virtual="true"> #read是一個虛擬的數據庫的讀節點
<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">server3,server2</property> #負載輪詢設置
</poolConfig>
</dbServer>
</amoeba:dbServers>
注:dbServers.xml須要的配置包括數據庫的端口、用戶名、密碼、進行讀寫分離的庫文件和讀寫地址池,已經輪詢設置。
MySQL的主從服務器密碼最好設置相同。
定義server1爲master,server2和server3爲slave
定義write爲server1,read爲server2、server3所在pool的數據庫輪訓規則,支持輪訓、權重、HA,所在pool的數據庫服務器,多臺配置已」, 」隔開。server2,server3爲輪訓方式工做,默認從server1到server3,也能夠重複添加好比server1,server2,server3,server3,這樣server3在查詢中被連接2次。寫的服務器也能夠不用添加到讀的pool,這樣就實現server1寫,server2,3讀。
地址池中的write和read要與dbServer.xml中設置的池名稱相同
至此amoeba所有配置完成。啓動測試。
進入amoeba的文件路徑下的bin/目錄,執行./launcher(3.0版本)便可。
在從服務器上鍊接amoeba測試:
命令以下mysql -u root -p -h 172.16.200.81 -P 8066 (登陸輸入的密碼爲amoeba的密碼)
使用另一臺安裝了MySQL客戶端服務器的主機遠程鏈接amoeba服務並在master_test庫中建立 write_test表文件,並插入write_wangzx數據測試數據的的寫入庫。(此操做前須要將主從同步中止,更能直觀反映文件寫入是訪問的是mysql-master服務器)
(1). 經過遠程amoeba服務建立write_test表文件。
[root@i-d5g65b9d ~]# mysql -u root -p -h 172.16.200.81 -P 8066
密碼爲amoeba.xml配置文件中設置的密碼
(2). 中止MySQL的主從同步(該操做須要在從服務器上操做便可)。相關操做命令以下:
STOP SLAVE IO_THREAD; #中止IO進程
STOP SLAVE SQL_THREAD; #中止SQL進程
STOP SLAVE; #中止IO和SQL進程
啓動主從同步命令以下:(補充說明)
START SLAVE IO_THREAD; #啓動IO進程
START SLAVE SQL_THREAD; #啓動SQL進程
START SLAVE; #啓動IO和SQL進程
(3). 在遠程MySQL的服務器上使用master_test庫中建立 write_test表文件,並插入write_wangzx相關數據數據,(1,'wangzx','master');。
mysql> insert into write_test values(1,'wangzx','master');
分別登陸主從服務器的MySQL查看上圖新建數據是否存在。
主服務器查看的數據信息以下圖:
兩臺從服務器查看到的信息以下:
Slave1信息以下;
Slave2信息以下;
從以上信息判斷,數據寫入的庫文件寫入到了MySQL主服務器。
2. 讀測試
(1). 分別登陸到兩臺從服務器
使用master_test庫中建立 write_test表文件,並分別插入write_wangzx相關數據數據,(1,'wangzx','slave1');和(1,'wangzx','slave2'); 。
mysql> insert into write_test values(1,'wangzx','slave1');
mysql> insert into write_test values(1,'wangzx','slave2');
(2).測試數據的讀取以及amoeba的輪詢。
經過遠程鏈接到amoeba查看讀取的數據表信息,經過表信息查看輪詢主機。
輸入mysql> select * from write_test;查看相關表信息,將命令連續操做兩次,查看到表信息不一樣,而且未讀取到主服務器表信息,說明讀取數據時只在從服務器上進行讀取,而且能實現從服務器輪詢讀取數據,實現負載功能。