【纯干货】Amoeba实现MySQL主从同步与读写分离
【純干貨】Amoeba實(shí)現(xiàn)MySQL主從同步與讀寫(xiě)分離
一、簡(jiǎn)介
Amoeba(變形蟲(chóng))項(xiàng)目,該開(kāi)源框架于2008年開(kāi)始發(fā)布一款 Amoeba for Mysql軟件。這個(gè)軟件致力于MySQL的分布式數(shù)據(jù)庫(kù)前端代理層,它主要在應(yīng)用層訪問(wèn)MySQL的 時(shí)候充當(dāng)SQL路由功能,專(zhuān)注于分布式數(shù)據(jù)庫(kù)代理層(Database Proxy)開(kāi)發(fā)。座落與 Client、DB Server(s)之間,對(duì)客戶(hù)端透明。具有負(fù)載均衡、高可用性、SQL 過(guò)濾、讀寫(xiě)分離、可路由相關(guān)的到目標(biāo)數(shù)據(jù)庫(kù)、可并發(fā)請(qǐng)求多臺(tái)數(shù)據(jù)庫(kù)合并結(jié)果。 通過(guò)Amoeba你能夠完成多數(shù)據(jù)源的高可用、負(fù)載均衡、數(shù)據(jù)切片的功能,目前Amoeba已在很多企業(yè)的生產(chǎn)線上面使用
優(yōu)點(diǎn):
(1)降低費(fèi)用,簡(jiǎn)單易用
(2)提高系統(tǒng)整體可用性
(3)易于擴(kuò)展處理能力與系統(tǒng)規(guī)模
(4)可以直接實(shí)現(xiàn)讀寫(xiě)分離及負(fù)載均衡效果,而不用修改代碼
缺點(diǎn):
(1)不支持事務(wù)與存儲(chǔ)過(guò)程
(2)暫不支持分庫(kù)分表,amoeba目前只做到分?jǐn)?shù)據(jù)庫(kù)實(shí)例
(3)不適合從amoeba導(dǎo)數(shù)據(jù)的場(chǎng)景或者對(duì)大數(shù)據(jù)量查詢(xún)的query并不合適(比如一次請(qǐng)求返回10w以上甚至更多數(shù)據(jù)的場(chǎng)合)
3.什么是讀寫(xiě)分離
讀寫(xiě)分離(Read/Write Splitting),基本的原理是讓主數(shù)據(jù)庫(kù)處理事務(wù)性增、改、刪操作(INSERT、UPDATE、DELETE),而從數(shù)據(jù)庫(kù)處理SELECT查詢(xún)操作。
數(shù)據(jù)庫(kù)復(fù)制被用來(lái)把事務(wù)性操作導(dǎo)致的變更同步到集群中的從數(shù)據(jù)庫(kù)。
二、實(shí)驗(yàn)拓?fù)錁?gòu)架
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服務(wù)器 centos7-3 IP:192.168.234.181
讀寫(xiě)分離實(shí)驗(yàn)配置
源碼編譯安裝MySQL5.5
yum install gcc 、 gcc-c++ 、make、cmake
ncurses-devel、bison、libaio-devel -y
groupadd -r mysql
useradd -g mysql -r -d /mydata/data 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環(huán)境變量
echo "export PATH=\$PATH:/usr/local/mysql/bin" > /etc/profile.d/mysql.sh
source /etc/profile.d/mysql.sh
6.復(fù)制MySQL啟動(dòng)腳本和服務(wù)配置文件分別到/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.給予相應(yīng)的權(quán)限并且加入開(kāi)機(jī)自啟動(dòng)項(xiàng)
chmod 755 /etc/init.d/mysqld
chkconfig --add /etc/init.d/mysqld
chkconfig mysqld --level 35 on
8.初始化數(shù)據(jù)庫(kù)
/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.配置啟動(dòng)腳本
vim /etc/init.d/mysqld
basedir=/usr/local/mysql
datadir=/home/mysql
11.啟動(dòng)MySQL服務(wù)
systemctl start mysqld.service
12.設(shè)置MySQL用戶(hù)的密碼
mysqladmin -u root password 'abc123'
MySQL主服務(wù)器(master CentOS7-1)配置
[root@localhost ~]# vim /etc/my.cnf ...省略 log-bin=master-bin //這里原來(lái)的mysql修改為master log-slave-updates=true //添加,表示從服務(wù)器更新二進(jìn)制日志 ...省略 server-id = 11重新啟動(dòng)mysql服務(wù),并且給予從服務(wù)器訪問(wèn)權(quán)限
[root@localhost ~]# systemctl restart mysqld.service //重啟MySQL服務(wù) [root@localhost ~]# mysql -u root -p Enter password: mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.234.%' IDENTIFIED BY '123456'; //給予從服務(wù)器訪問(wèn)權(quán)限 Query OK, 0 rows affected (0.00 sec)mysql> flush privileges; //刷新生成二進(jìn)制文件 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)從服務(wù)器(slave CentOS7-2)配置
[root@localhost ~]# systemctl stop firewalld.service localhost ~]# setenforce 0 [root@localhost ~]# yum install ntpdate -y [root@localhost ~]# systemctl start ntpd.service [root@localhost ~]# vim /etc/my.cnf ...省略 server-id = 22 relay-log=relay-log-bin //從主服務(wù)器上同步日志文件記錄到本地 relay-log-index=slave-relay-bin.index //定義relay-log的位置和名稱(chēng)重啟MySQL服務(wù),并且指定從服務(wù)器同步的對(duì)象服務(wù)器
[root@localhost ~]# mysql -u root -p Enter 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; //設(shè)置同步的對(duì)象服務(wù)器及用戶(hù)密碼 Query OK, 0 rows affected (0.01 sec) mysql> start slave; //開(kāi)啟主從同步 Query OK, 0 rows affected (0.01 sec)mysql> show slave status\G; //查看slave狀態(tài) *************************** 1. row ***************************Slave_IO_State: Reconnecting after a failed master event readMaster_Host: 192.168.234.174Master_User: myslaveMaster_Port: 3306Connect_Retry: 60Master_Log_File: master-bin.000001Read_Master_Log_Pos: 564Relay_Log_File: localhost-relay-bin.001259Relay_Log_Pos: 254Relay_Master_Log_File: master-bin.000001Slave_IO_Running: Yes //這里必須是yesSlave_SQL_Running: Yes //這里必須是yesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 564Relay_Log_Space: 561Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 1360 Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 11 1 row in set (0.00 sec)從服務(wù)器2(slave2 CentOS7-5)和上面一樣的配置
驗(yàn)證主從同步
在主服務(wù)器上添加一個(gè)數(shù)據(jù)庫(kù)school,查看兩個(gè)從服務(wù)器是否能夠同步獲取到school數(shù)據(jù)庫(kù)
主服務(wù)器添加數(shù)據(jù)庫(kù)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數(shù)據(jù)庫(kù) Query OK, 1 row affected (0.00 sec)在兩臺(tái)從服務(wù)器上查看是否同步獲取到school數(shù)據(jù)庫(kù)
slave1 CentOS7-2
mysql> show databases; //查看有哪些數(shù)據(jù)庫(kù) +--------------------+ | Database | +--------------------+ | information_schema | | #mysql50#.mozilla | | mysql | | performance_schema | | school | //這里就同步獲取到school數(shù)據(jù)庫(kù) | test | +--------------------+ 6 rows in set (0.01 sec)slave2 CentOS7-5
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | #mysql50#.mozilla | | mysql | | performance_schema | | school | //這里slave2也同步獲取到一個(gè)school的數(shù)據(jù)庫(kù) | test | +--------------------+ 6 rows in set (0.00 sec)到這里如果兩臺(tái)從服務(wù)器都能獲取到school數(shù)據(jù)庫(kù),就說(shuō)明主從同步已經(jīng)沒(méi)問(wèn)題了,那么接下來(lái)就是在amoeba服務(wù)器(CentOS7-3)上部署讀寫(xiě)分離了
amoeba服務(wù)器(CentOS7-3)的部署設(shè)置
因?yàn)锳moeba是java程序開(kāi)發(fā)的,所以Amoeba服務(wù)器上要先安裝jdk環(huán)境
[root@localhost ~]# systemctl stop firewalld.service [root@localhost ~]# setenforce 0 [root@localhost mysql]# cp jdk-6u14-linux-x64.bin /usr/local/ [root@localhost mysql]# ./jdk-6u14-linux-x64.bin 。。。省略 Do you agree to the above license terms? [yes or no] y //前面一直按Enter直到這里輸入y(yes),然后就等jdk環(huán)境安裝完成然后安裝Amoeba服務(wù)
[root@localhost local]# mv jdk1.6.0_14/ jdk1.6 [root@localhost local]# vim /etc/profile //添加amoeba的環(huán)境變量//G到行尾添加 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@localhost local]# source /etc/profile //刷星使環(huán)境變量立即生效 [root@localhost local]# mkdir /usr/local/amoeba //創(chuàng)建一個(gè)amoeba的工作目錄 [root@localhost local]# tar zxvf /abc/mysql/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ //解壓安裝amoeba至工作目錄[root@localhost local]# chmod -R 755 amoeba/ //遞歸給予amoeba及子文件執(zhí)行權(quán)限 [root@localhost local]# /usr/local/amoeba/bin/amoeba //檢查amoeba是否安裝成功 amoeba start|stop //看到這樣的提示就說(shuō)明amoeba服務(wù)安裝完成然后在三臺(tái)MySQL服務(wù)器上添加權(quán)限開(kāi)放給amoeba訪問(wèn),用戶(hù)使用test,密碼是123123
grant all on . to test@'192.168.234.%' identified by '123123';
修改amoeba服務(wù)器的配置文件
[root@localhost amoeba]# vim conf/amoeba.xml 。。。省略<!-- --> //刪除這里,表示開(kāi)啟 30 <property name="user">amoeba</proper ty> //這里修改用戶(hù)為之前設(shè)置的amoeba31 <!-- --> //刪除這里,表示開(kāi)啟32 <property name="password">123456</pr operty> //添加密碼為之前設(shè)置的密碼12345633 。。。省略 115 <property name="defaultPool">master</property> //這里修改為默認(rèn)使用master主服務(wù)器 116 117 118 <property name="writePool">master</property> //允許主服務(wù)器寫(xiě)入 119 <property name="readPool">slaves</property> //允許從服務(wù)器讀取[root@localhost amoeba]# vim conf/dbServers.xml //修改數(shù)據(jù)庫(kù)的配置文件<!-- mysql user -->26 <property name="user">test</property> //這里修改為test,即使用test用戶(hù)去讀取MySQL的數(shù)據(jù)27 <!-- mysql pseeword //這里有一個(gè)<!--表示注釋的意思,所以要?jiǎng)h除28 <property name="password">123123</property> //密碼為前面設(shè)置的密碼123123--> //刪除<dbServer name="master" parent="abstractServer"> //修改原來(lái)的server1為master45 <factoryConfig>46 <!-- mysql ip -->47 <property name="ipAddress">192.168.234.174</property> //這里改為主服務(wù)器的IP地址48 </factoryConfig>49 </dbServer>50 51 <dbServer name="slave1" parent="abstractServer"> //server2改為slave152 <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"> //服務(wù)器池名為slaves65 <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> //服務(wù)器池內(nèi)的兩臺(tái)服務(wù)器的名稱(chēng)71 </poolConfig>72 </dbServer>開(kāi)啟amoeba服務(wù),并且檢查端口是否開(kāi)啟
[root@localhost amoeba]# /usr/local/amoeba/bin/amoeba start & //開(kāi)啟amoeba服務(wù)器,并且放入后臺(tái)執(zhí)行 [2] 3996 [root@localhost amoeba]# log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml 2018-07-08 15:02:45,493 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0 log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf 2018-07-08 15:02:46,450 INFO net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066. //這里可以看到開(kāi)始監(jiān)聽(tīng)端口8066 2018-07-08 15:02:46,476 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:38438. ^C [root@localhost amoeba]# netstat -ntap | grep java //查看java的程序 tcp6 0 0 :::8066 :::* LISTEN 3996/java //然后就可以看到有一個(gè)8066的端口已經(jīng)開(kāi)啟了 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然后這里該部署的部署完成了,剩下的就是驗(yàn)證是否能夠?qū)崿F(xiàn)讀寫(xiě)分離了
驗(yàn)證
這里先簡(jiǎn)單說(shuō)明下驗(yàn)證過(guò)程:先在主服務(wù)器的school庫(kù)中創(chuàng)建一個(gè)表zyc,然后兩臺(tái)從服務(wù)器關(guān)閉slave,在主服務(wù)器的zyc表中插入數(shù)據(jù)1,從服務(wù)器1的zyc表(注:創(chuàng)建表時(shí)同步并未關(guān)閉,所以從服務(wù)器會(huì)同步生成一個(gè)zyc表)中插入數(shù)據(jù)2,從服務(wù)器2的zyc表中插入數(shù)據(jù)3,然后使用客戶(hù)機(jī)Linux6-1訪問(wèn)amoeba服務(wù)器,會(huì)看到顯示的數(shù)據(jù)會(huì)在兩個(gè)從服務(wù)器的2、3數(shù)據(jù)間切換,并不會(huì)顯示主服務(wù)器寫(xiě)入的數(shù)據(jù)1;在客戶(hù)機(jī)Linux6-1上寫(xiě)入數(shù)據(jù),然后只有在主MySQL服務(wù)器能查詢(xún)到,兩個(gè)從服務(wù)器卻查看不到;最后開(kāi)啟兩個(gè)從服務(wù)器的同步,在客戶(hù)機(jī)查看數(shù)據(jù),就會(huì)看到數(shù)據(jù)顯示為214、314間切換。
//主服務(wù)器添加表 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)//兩個(gè)從服務(wù)器即會(huì)同步獲取表信息 #從服務(wù)器1 CentOS7-2 mysql> use school; Database changed mysql> show tables; +------------------+ | Tables_in_school | +------------------+ | zyc | +------------------+ 1 row in set (0.00 sec)mysql> stop slave; Query OK, 0 rows affected (0.00 sec)#從服務(wù)器2 CentOS7-5 mysql> use school; Database changed mysql> show tables; +------------------+ | Tables_in_school | +------------------+ | zyc | +------------------+ 1 row in set (0.01 sec)mysql> stop slave; Query OK, 0 rows affected (0.01 sec)#主服務(wù)器插入數(shù)據(jù)1 mysql> 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)#從服務(wù)器1插入數(shù)據(jù)2 mysql> 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)#從服務(wù)器2插入數(shù)據(jù)3 mysql> 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)#此時(shí)使用客戶(hù)機(jī)去訪問(wèn)amoeba服務(wù)器會(huì)看到數(shù)據(jù)只顯示兩個(gè)從服務(wù)器的 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)#然后打開(kāi)兩個(gè)從服務(wù)器的同步,在客戶(hù)機(jī)插入數(shù)據(jù)4 mysql> 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 | +------+----------+最后的實(shí)驗(yàn)結(jié)論為:主服務(wù)器負(fù)責(zé)寫(xiě)入數(shù)據(jù);從服務(wù)器負(fù)責(zé)讀取數(shù)據(jù);且兩個(gè)從服務(wù)器會(huì)與主服務(wù)器進(jìn)行同步,而兩個(gè)從服務(wù)器間則不會(huì)同步
如果您實(shí)驗(yàn)到最后得到的也是這樣的結(jié)果,那么恭喜您讀寫(xiě)分離的實(shí)驗(yàn)?zāi)晒α?#xff01;
這樣就實(shí)現(xiàn)了MySQL的讀寫(xiě)分離及主從同步
轉(zhuǎn)載于:https://blog.51cto.com/13659301/2140840
總結(jié)
以上是生活随笔為你收集整理的【纯干货】Amoeba实现MySQL主从同步与读写分离的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ant-design-pro使用服务器数
- 下一篇: linux cmake编译源码,linu