標籤:說明 art 資料顯示 分庫分表 主目錄 插入 medium 通過 test
【純乾貨】Amoeba實現MySQL主從同步與讀寫分離一、簡介
- amoeba簡介
Amoeba(變形蟲)項目,該開源架構於2008年開始發布一款 Amoeba for Mysql軟體。這個軟體致力於MySQL的分散式資料庫前端代理層,它主要在應用程式層訪問MySQL的 時候充當SQL路由功能,專註於分散式資料庫代理層(Database Proxy)開發。座落與 Client、DB Server(s)之間,對用戶端透明。具有負載平衡、高可用性、SQL 過濾、讀寫分離、可路由相關的到目標資料庫、可並發請求多台資料庫合并結果。 通過Amoeba你能夠完成多資料來源的高可用、負載平衡、資料切片的功能,目前Amoeba已在很多企業的生產線上面使用
- Amoeba的優缺點
優點:
(1)降低費用,簡單易用
(2)提高系統整體可用性
(3)易於擴充處理能力與系統規模
(4)可以直接實現讀寫分離及負載平衡效果,而不用修改代碼
缺點:
(1)不支援事務與預存程序
(2)暫不支援分庫分表,amoeba目前只做到分資料庫執行個體
(3)不適合從amoeba導資料的情境或者對大資料量查詢的query並不合適(比如一次請求返回10w以上甚至更多資料的場合)
3.什麼是讀寫分離
讀寫分離(Read/Write Splitting),基本的原理是讓主要資料庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從資料庫處理SELECT查詢操作。
資料庫複寫被用來把事務性操作導致的變更同步到叢集中的從資料庫。
二、實驗拓撲構架
client linux6-1 IP:192.168.234.186
主MySQL centos7-1 IP:192.168.234.174
從MySQL01 centos7-2 IP:192.168.234.177
從MySQL02 centos7-5 IP:192.168.234.184
amoeba伺服器 centos7-3 IP:192.168.234.181
讀寫分離實驗配置源碼編譯安裝MySQL5.5
- 編譯MySQL5.5的依賴環境包
yum install gcc 、 gcc-c++ 、make、cmake
ncurses-devel、bison、libaio-devel -y
- 建立MySQL使用者
groupadd -r mysql
useradd -g mysql -r -d /mydata/data mysql
- 源碼編譯MySQL
tar zxvf mysql-5.5.24.tar.gz -C /opt
cd /opt/mysql-5.5.24.tar.gz
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
-DMYSQL_UNIX_ADDR=/home/mysql/mysql.sock
-DDEFAULT_CHARSET=utf8
-DDEFAULT_COLLATION=utf8_general_ci
-DWITH_EXTRA_CHARSETS=all
-DWITH_MYISAM_STORAGE_ENGINE=1
-DWITH_INNOBASE_STORAGE_ENGINE=1
-DWITH_MEMORY_STORAGE_ENGINE=1
-DWITH_READLINE=1
-DENABLED_LOCAL_INFILE=1
-DMYSQL_DATADIR=/home/mysql
-DMYSQL_USER=mysql
-DMYSQL_TCP_PORT=3306
make && make install
4.更改mysql的主目錄為mysql組
chown -R mysql.mysql /usr/local/mysql
5.配置mysql環境變數
echo "export PATH=\$PATH:/usr/local/mysql/bin" > /etc/profile.d/mysql.sh
source /etc/profile.d/mysql.sh
6.複製MySQL啟動指令碼和服務組態檔分別到/etc/my.cnf和/etc/init.d/mysqld
cp support-files/my-medium.cnf /etc/my.cnf
cp support-files/mysql.server /etc/init.d/mysqld
7.給予相應的許可權並且加入開機自啟動項
chmod 755 /etc/init.d/mysqld
chkconfig --add /etc/init.d/mysqld
chkconfig mysqld --level 35 on
8.初始化資料庫
/usr/local/mysql/scripts/mysql_install_db \
--user=mysql \
--ldata=/var/lib/mysql \
--basedir=/usr/local/mysql \
--datadir=/home/mysql
9.建立軟連結
ln -s /var/lib/mysql/mysql.sock /home/mysql/mysql.sock
10.配置啟動指令碼
vim /etc/init.d/mysqld
basedir=/usr/local/mysql
datadir=/home/mysql
11.啟動MySQL服務
systemctl start mysqld.service
12.設定MySQL使用者的密碼
mysqladmin -u root password ‘abc123‘
MySQL主伺服器(master CentOS7-1)配置
[[email protected] ~]# vim /etc/my.cnf...省略log-bin=master-bin //這裡原來的mysql修改為masterlog-slave-updates=true //添加,表示從伺服器更新二進位日誌...省略server-id = 11
重新啟動mysql服務,並且給予從伺服器存取權限
[[email protected] ~]# systemctl restart mysqld.service //重啟MySQL服務[[email protected] ~]# mysql -u root -pEnter password:mysql> GRANT REPLICATION SLAVE ON *.* TO ‘myslave‘@‘192.168.234.%‘ IDENTIFIED BY ‘123456‘; //給予從伺服器存取權限Query OK, 0 rows affected (0.00 sec)mysql> flush privileges; //重新整理產生二進位檔案Query OK, 0 rows affected (0.00 sec)mysql> show master status; //查看pos位移量 +-------------------+----------+--------------+------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |+-------------------+----------+--------------+------------------+| master-bin.000001 | 477 | | |+-------------------+----------+--------------+------------------+1 row in set (0.01 sec)
從伺服器(slave CentOS7-2)配置
[[email protected] ~]# systemctl stop firewalld.service localhost ~]# setenforce 0[[email protected] ~]# yum install ntpdate -y[[email protected] ~]# systemctl start ntpd.service [[email protected] ~]# vim /etc/my.cnf...省略server-id = 22 relay-log=relay-log-bin //從主伺服器上同步處理記錄檔案記錄到本地relay-log-index=slave-relay-bin.index //定義relay-log的位置和名稱
重啟MySQL服務,並且指定從伺服器同步的物件服務器
[[email protected] ~]# mysql -u root -pEnter password:mysql> change master to master_host=‘192.168.234.174‘,master_user=‘myslave‘,master_password=‘123456‘,master_log_file=‘master-bin.000001‘,master_log_pos=477; //設定同步的物件服務器及使用者密碼Query OK, 0 rows affected (0.01 sec) mysql> start slave; //開啟主從同步Query OK, 0 rows affected (0.01 sec)mysql> show slave status\G; //查看slave狀態*************************** 1. row *************************** Slave_IO_State: Reconnecting after a failed master event read Master_Host: 192.168.234.174 Master_User: myslave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 564 Relay_Log_File: localhost-relay-bin.001259 Relay_Log_Pos: 254 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: Yes //這裡必須是yes Slave_SQL_Running: Yes //這裡必須是yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 564 Relay_Log_Space: 561 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 1360Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 111 row in set (0.00 sec)
從伺服器2(slave2 CentOS7-5)和上面一樣的配置
驗證主從同步
在主伺服器上添加一個資料庫school,查看兩個從伺服器是否能夠同步擷取到school資料庫
主伺服器添加資料庫school
mysql> show databases; +--------------------+| Database |+--------------------+| information_schema || #mysql50#.mozilla || mysql || performance_schema || test |+--------------------+5 rows in set (0.01 sec)mysql> create database school; //添加school資料庫Query OK, 1 row affected (0.00 sec)
在兩台從伺服器上查看是否同步擷取到school資料庫
slave1 CentOS7-2
mysql> show databases; //查看有哪些資料庫+--------------------+| Database |+--------------------+| information_schema || #mysql50#.mozilla || mysql || performance_schema || school | //這裡就同步擷取到school資料庫| test |+--------------------+6 rows in set (0.01 sec)
slave2 CentOS7-5
mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || #mysql50#.mozilla || mysql || performance_schema || school | //這裡slave2也同步擷取到一個school的資料庫| test |+--------------------+6 rows in set (0.00 sec)
到這裡如果兩台從伺服器都能擷取到school資料庫,就說明主從同步已經沒問題了,那麼接下來就是在amoeba伺服器(CentOS7-3)上部署讀寫分離了
amoeba伺服器(CentOS7-3)的部署設定
因為Amoeba是java程式開發的,所以Amoeba伺服器上要先安裝jdk環境
[[email protected] ~]# systemctl stop firewalld.service [[email protected] ~]# setenforce 0[[email protected] mysql]# cp jdk-6u14-linux-x64.bin /usr/local/[[email protected] mysql]# ./jdk-6u14-linux-x64.bin 。。。省略Do you agree to the above license terms? [yes or no] y //前面一直按Enter直到這裡輸入y(yes),然後就等jdk環境安裝完成
然後安裝Amoeba服務
[[email protected] local]# mv jdk1.6.0_14/ jdk1.6[[email protected] local]# vim /etc/profile //添加amoeba的環境變數 //G到行尾添加export JAVA_HOME=/usr/local/jdk1.6export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/libexport PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/binexport AMOEBA_HOME=/usr/local/amoebaexport PATH=$PATH:$AMOEBA_HOME/bin[[email protected] local]# source /etc/profile //刷星使環境變數立即生效[[email protected] local]# mkdir /usr/local/amoeba //建立一個amoeba的工作目錄[[email protected] local]# tar zxvf /abc/mysql/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ //解壓安裝amoeba至工作目錄[[email protected] local]# chmod -R 755 amoeba/ //遞迴給予amoeba及子檔案執行許可權[[email protected] local]# /usr/local/amoeba/bin/amoeba //檢查amoeba是否安裝成功amoeba start|stop //看到這樣的提示就說明amoeba服務安裝完成
然後在三台MySQL伺服器上添加許可權開放給amoeba訪問,使用者使用test,密碼是123123
grant all on . to [email protected]‘192.168.234.%‘ identified by ‘123123‘;
修改amoeba伺服器的設定檔
[[email protected] amoeba]# vim conf/amoeba.xml 。。。省略 <!-- --> //刪除這裡,表示開啟30 <property name="user">amoeba</proper ty> //這裡修改使用者為之前設定的amoeba 31 <!-- --> //刪除這裡,表示開啟 32 <property name="password">123456</pr operty> //添加密碼為之前設定的密碼123456 33 。。。省略115 <property name="defaultPool">master</property> //這裡修改為預設使用master主伺服器116 117 118 <property name="writePool">master</property> //允許主伺服器寫入119 <property name="readPool">slaves</property> //允許從伺服器讀取[[email protected] amoeba]# vim conf/dbServers.xml //修改資料庫的設定檔 <!-- mysql user --> 26 <property name="user">test</property> //這裡修改為test,即使用test使用者去讀取MySQL的資料 27 <!-- mysql pseeword //這裡有一個<!--表示注釋的意思,所以要刪除 28 <property name="password">123123</property> //密碼為前面設定的密碼123123 --> //刪除 <dbServer name="master" parent="abstractServer"> //修改原來的server1為master 45 <factoryConfig> 46 <!-- mysql ip --> 47 <property name="ipAddress">192.168.234.174</property> //這裡改為主伺服器的IP地址 48 </factoryConfig> 49 </dbServer> 50 51 <dbServer name="slave1" parent="abstractServer"> //server2改為slave1 52 <factoryConfig> 53 <!-- mysql ip --> 54 <property name="ipAddress">192.168.234.177</property> //slave1(即CentOS7-2)IP地址 55 </factoryConfig> 56 </dbServer> 57 #添加 58 <dbServer name="slave2" parent="abstractServer"> 59 <factoryConfig> 60 <!-- mysql ip --> 61 <property name="ipAddress">192.168.234.184</property> //slave2(即CentOS7-5)IP地址 62 </factoryConfig> 64 <dbServer name="slaves" virtual="true"> //伺服器集區名為slaves 65 <poolConfig class="com.meidusa.amoeba.server.MultipleServerP ool"> 66 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGH TBASED , 3=HA--> 67 <property name="loadbalance">1</property> 68 69 <!-- Separated by commas,such as: server1,server2,se rver1 --> 70 <property name="poolNames">slave1,slave2</property> //伺服器集區內的兩台伺服器的名稱 71 </poolConfig> 72 </dbServer>
開啟amoeba服務,並且檢查連接埠是否開啟
[[email protected] amoeba]# /usr/local/amoeba/bin/amoeba start & //開啟amoeba伺服器,並且放入後台執行[2] 3996[[email protected] amoeba]# log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml2018-07-08 15:02:45,493 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf2018-07-08 15:02:46,450 INFO net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066. //這裡可以看到開始監聽連接埠80662018-07-08 15:02:46,476 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:38438.^C[[email protected] amoeba]# netstat -ntap | grep java //查看java的程式tcp6 0 0 :::8066 :::* LISTEN 3996/java //然後就可以看到有一個8066的連接埠已經開啟了tcp6 0 0 127.0.0.1:38438 :::* LISTEN 3996/java tcp6 0 0 192.168.234.181:37510 192.168.234.174:3306 ESTABLISHED 3996/java tcp6 0 0 192.168.234.181:38208 192.168.234.177:3306 ESTABLISHED 3996/java tcp6 0 0 192.168.234.181:47642 192.168.234.184:3306 ESTABLISHED 3996/java
然後這裡該部署的部署完成了,剩下的就是驗證是否能夠實現讀寫分離了
驗證
這裡先簡單說明下驗證過程:先在主伺服器的school庫中建立一個表zyc,然後兩台從伺服器關閉slave,在主伺服器的zyc表中插入資料1,從伺服器1的zyc表(註:建立表時同步並未關閉,所以從伺服器會同步產生一個zyc表)中插入資料2,從伺服器2的zyc表中插入資料3,然後使用客戶機Linux6-1訪問amoeba伺服器,會看到顯示的資料會在兩個從伺服器的2、3資料間切換,並不會顯示主伺服器寫入的資料1;在客戶機Linux6-1上寫入資料,然後只有在主MySQL伺服器能查詢到,兩個從伺服器卻查看不到;最後開啟兩個從伺服器的同步,在客戶機查看資料,就會看到資料顯示為214、314間切換。
//主伺服器添加表mysql> create table zyc (id int(5),name varchar(10));Query OK, 0 rows affected (0.03 sec)mysql> show tables;+------------------+| Tables_in_school |+------------------+| zyc |+------------------+1 row in set (0.00 sec)//兩個從伺服器即會同步擷取表資訊#從伺服器1 CentOS7-2mysql> use school;Database changedmysql> show tables;+------------------+| Tables_in_school |+------------------+| zyc |+------------------+1 row in set (0.00 sec)mysql> stop slave;Query OK, 0 rows affected (0.00 sec)#從伺服器2 CentOS7-5mysql> use school;Database changedmysql> show tables;+------------------+| Tables_in_school |+------------------+| zyc |+------------------+1 row in set (0.01 sec)mysql> stop slave;Query OK, 0 rows affected (0.01 sec)#主伺服器插入資料1mysql> insert into zyc values (1,‘zhangsan‘);Query OK, 1 row affected (0.01 sec)mysql> select * from zyc;+------+----------+| id | name |+------+----------+| 1 | zhangsan |+------+----------+1 row in set (0.00 sec)#從伺服器1插入資料2mysql> insert into zyc values (2,‘lisi‘);Query OK, 1 row affected (0.01 sec)mysql> select * from zyc;+------+------+| id | name |+------+------+| 2 | lisi |+------+------+1 row in set (0.01 sec)#從伺服器2插入資料3mysql> insert into zyc values (3,‘wangwu‘);Query OK, 1 row affected (0.01 sec)mysql> select * from zyc;+------+--------+| id | name |+------+--------+| 3 | wangwu |+------+--------+1 row in set (0.00 sec)#此時使用客戶機去訪問amoeba伺服器會看到資料只顯示兩個從伺服器的mysql> select * from zyc;+------+--------+| id | name |+------+--------+| 2 | lisi |+------+--------+1 row in set (0.00 sec)mysql> select * from zyc;+------+--------+| id | name |+------+--------+| 3 | wangwu |+------+--------+1 row in set (0.00 sec)#然後開啟兩個從伺服器的同步,在客戶機插入資料4mysql> insert into zyc values (4,‘zhaoliu‘);Query OK, 1 row affected (0.01 sec)select * from zyc;+------+----------+| id | name |+------+----------+| 2 | lisi |+------+----------+| 1 | zhangsan |+------+----------+| 4 | zhaoliu |+------+----------+select * from zyc;+------+----------+| id | name |+------+----------+| 3 | wangwu |+------+----------+| 1 | zhangsan |+------+----------+| 4 | zhaoliu |+------+----------+
最後的實驗結論為:主伺服器負責寫入資料;從伺服器負責讀取資料;且兩個從伺服器會與主伺服器進行同步,而兩個從伺服器間則不會同步
如果您實驗到最後得到的也是這樣的結果,那麼恭喜您讀寫分離的實驗您成功了!
這樣就實現了MySQL的讀寫分離及主從同步
【純乾貨】Amoeba實現MySQL主從同步與讀寫分離