您好,登錄后才能下訂單哦!
在實際生產(chǎn)環(huán)境中,如果對數(shù)據(jù)庫的讀寫都在同一塊數(shù)據(jù)庫服務(wù)器中操作,無論是在安全性、高可用性,還是高并發(fā)等各個方面都是完全不能滿足實際需求的,因此,一般都是通過主從復(fù)制(Master- Slave) 的方式來同步數(shù)據(jù),再通過讀取分離來提升數(shù)據(jù)庫的并發(fā)負(fù)載能力。
MySQL 主從復(fù)制原理
MySQL 的主從復(fù)制和MySQL 的讀寫分離兩者有著緊密關(guān)系,首先要部署主從復(fù)制,只有主從復(fù)制完成,才能在此基礎(chǔ)上進(jìn)行讀寫分離
MySQL 支持的復(fù)制類型
1)基于語句的復(fù)制。在主服務(wù)器上執(zhí)行的 SQL 語句,在從服務(wù)器上執(zhí)行同樣的語句。MySQL 默認(rèn)采用基于語句的復(fù)制,效率較高。
2)基于行的復(fù)制。把改變的內(nèi)容復(fù)制過去,而不是把命令在從服務(wù)器上執(zhí)行一遍。
3)混合類型的復(fù)制。默認(rèn)采用基于語句的復(fù)制,一旦發(fā)現(xiàn)基于語句無法精確復(fù)制時,就會采用基于行的復(fù)制。
MySQL 讀寫分離原理
讀寫分離就是基于主服務(wù)器上寫,只在從服務(wù)器上讀?;驹硎亲寯?shù)據(jù)庫處理事務(wù)性查詢,而從數(shù)據(jù)庫處理 select 查詢。數(shù)據(jù)庫被復(fù)制用來把事務(wù)性導(dǎo)致的變更同步到群集中的數(shù)據(jù)庫。
基于中間代理從實現(xiàn),代理一般位于客戶端和服務(wù)器之間,代理服務(wù)器接到客戶端請求通過判斷后轉(zhuǎn)發(fā)到后端數(shù)據(jù)庫。
實驗環(huán)境
本案例使用五臺服務(wù)器模擬搭建,具體拓?fù)鋱D如下:
主機(jī) 操作系統(tǒng) IP地址 主要軟件
Master Centos 7 x86_64 192.168.213.170 mysql-5.5.24.tar.gz
Slave 1 Centos 7 x86_64 192.168.213.168 mysql-5.5.24.tar.gz
Slave 2 Centos 7 x86_64 192.168.213.171 mysql-5.5.24.tar.gz
Amoeba Centos 7 x86_64 192.168.213.166 jdk-6u14-linux-x64.bin
amoeba-mysql-binary-2.2.0.tar.gz
客戶端 Centos 7 x86_64 192.168.213.172
所以需要的軟件包可通過此鏈接到百度云盤下載:
鏈接:https://pan.baidu.com/s/1Wv65-ZmAIasN3EPAzB8J7Q 密碼:5q4b
搭建MySQL 主從復(fù)制
一. 建立時間同步,在主節(jié)點上搭建時間同步服務(wù)器。
檢查是否安裝 NTP.
[root@master ~]# rpm -q ntp
ntp-4.2.6p5-25.el7.centos.2.x86_64
配置 NTP (在末行插入)
[root@master ~]# vim /etc/ntp.conf
server 127.127.213.0 //本地是時鐘源
fudge 127.127.100.0 stratum 8 //設(shè)置時間層級為8
啟動 NTP ,關(guān)閉防火墻和安全性增強(qiáng)功能
[root@master ~]#service ntpd start
Redirecting to /bin/systemctl start ntpd.service
[root@master ~]#systemctl stop firewalld.service
[root@master ~]#setenforce 0
二. 在從節(jié)點服務(wù)器上進(jìn)行時間同步 (節(jié)點服務(wù)器 slave01 和 slave02 配置相同)
檢查是否安裝 NTP.
[root@slave01 ~]# rpm -q ntp
ntp-4.2.6p5-25.el7.centos.2.x86_64
啟動 NTP ,關(guān)閉防火墻和安全性增強(qiáng)功能
[root@slave01 ~]# service ntpd start
Redirecting to /bin/systemctl start ntpd.service
[root@slave01 ~]# systemctl stop firewalld.service
[root@slave01 ~]# setenforce 0
與主服務(wù)器進(jìn)行時間同步
[root@slave01 ~]# /usr/sbin/ntpdate 192.168.213.170 //與主服務(wù)器進(jìn)行時間同步
7 Sep 10:10:30 ntpdate[4940]: the NTP socket is in use, exiting
三. 安裝 MySQL 數(shù)據(jù)庫,三個服務(wù) 器 master 、 slave01 、slave 02 都要安裝
安裝編譯環(huán)境
yum install gcc gcc-c++ make cmake ncurses-devel bison libaio-devel –y
添加 mysql 用戶并加入 mysql 組
[root@master LNMP]# useradd -s /sbin/nologin mysql //創(chuàng)建 mysql 用戶
[root@master LNMP]# mkdir /usr/local/mysql //創(chuàng)建 mysql 目錄
解壓 MySQL 軟件包,配置安裝mysql
[root@master LNMP]# tar zxvf mysql-5.5.24.tar.gz -C /opt/
[root@master mysql-5.5.24]# cmake \
> -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ //mysql 軟件安裝位置
> -DDEFAULT_CHARSET=utf8 \ //默認(rèn)字符集
> -DDEFAULT_COLLATION=utf8_general_ci \ //默認(rèn)字符校驗
> -DWITH_EXTRA_CHARSETS=all \ //額外的編碼,請使用 all
> -DSYSCONFDIR=/etc \
> -DMYSQL_DATADIR=/home/mysql/ \
> -DMYSQL_UNIX_ADDR=/home/mysql/mysql.sock \
> -DWITH_MYISAM_STORAGE_ENGINE=1 \ //存儲引擎
> -DWITH_INNOBASE_STORAGE_ENGINE=1 \
> -DWITH_ARCHIVE_STORAGE_ENGINE=1 \
> -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
> -DENABLED_LOCAL_INFILE=1 \ //啟用本地加載數(shù)據(jù)
> -DWITH_SSL=system \
> -DMYSQL_TCP_PORT=3306 \ //mysql 的端口默認(rèn)時3306
> -DENABLE_DOWNLOADS=1 \
> -DWITH_SSL=bundled
編譯及編譯安裝(此過程時間會長一些)
[root@master mysql-5.5.24]# make && make install
修改 mysql 安裝目錄的所有者,所屬組
[root@master mysql-5.5.24]# chown -R mysql.mysql /usr/local/mysql
修改環(huán)境變量
[root@master mysql-5.5.24]# echo "PATH=$PATH:/usr/local/mysql/bin/" >> /etc/profile
[root@master mysql]# source /etc/profile //刷新環(huán)境變量
創(chuàng)建修改 my.cnf 配置文件
[root@master mysql-5.5.24]# cd /usr/local/mysql/
[root@master mysql]# ls
bin data include lib mysql-test scripts sql-bench
COPYING docs INSTALL-BINARY man README share support-files[root@master mysql]# cp support-files/my-medium.cnf /etc/my.cnf
cp:是否覆蓋"/etc/my.cnf"? yes
[root@master mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@master mysql]# chmod 755 /etc/init.d/mysqld //添加執(zhí)行權(quán)限
[root@master mysql]# chkconfig --add /etc/init.d/mysqld //將 mysql 添加為系統(tǒng)使用
[root@master mysql]# chkconfig mysqld --level 35 on
初始化數(shù)據(jù)庫
[root@master mysql]# /usr/local/mysql/scripts/mysql_install_db \
> --user=mysql \ //指定數(shù)據(jù)庫管理員
> --ldata=/var/lib/mysql \
> --basedir=/usr/local/mysql \ //指定mysql 軟件安裝位置
> --datadir=/home/mysql //指定mysql 數(shù)據(jù)庫安裝位置
在配置文件中指定安裝位置
[root@master mysql]# vim /etc/init.d/mysqld
basedir=/usr/local/mysql
datadir=/home/mysql
創(chuàng)建軟連接
[root@master mysql]# ln -s /var/lib/mysql/mysql.sock /home/mysql/mysql.sock
啟動數(shù)據(jù)庫
[root@master mysql]# service mysql start
Redirecting to /bin/systemctl start mysql.service
Warning: mysql.service changed on disk. Run 'systemctl daemon-reload' to reload units.
[root@master mysql]# systemctl daemon-reload
[root@master mysql]# service mysql start
Redirecting to /bin/systemctl start mysql.service
[root@master mysql]# netstat -ntap | grep 3306 //查看3306端口
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 56229/mysqld
給數(shù)據(jù)庫 root 用戶設(shè)置登錄密碼,并登錄 mysql 數(shù)據(jù)庫
[root@master mysql]# mysqladmin -u root password 'abc123'
[root@master mysql]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
四. 在三臺 服務(wù)器的 mysql 安裝完成后,分別對其進(jìn)行配置。
(1)mysql 主服務(wù)器配置
[root@master mysql]# vim /etc/my.cnf
server-id = 11 //唯一標(biāo)識,三臺服務(wù)器的 server-id 不能一樣
log-bin=mysql-bin //主服務(wù)器的日志文件
log-slave-updates=true //從服務(wù)器的二進(jìn)制文件
重啟mysql 服務(wù)
[root@master mysql]# systemctl restart mysqld.service
授權(quán)從服務(wù)器
[root@master mysql]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.213.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)Query OK, 0 rows affected (0.00 sec) //授權(quán)所有從服務(wù)器復(fù)制權(quán)限,進(jìn)行二進(jìn)制的日志權(quán)限管理
mysql> FLUSH PRIVILEGES; //刷新
Query OK, 0 rows affected (0.01 sec)mysql> show master status; //查看主服務(wù)器狀態(tài)
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 | 1086| | | //文件名及位置者兩個參數(shù)記錄下來,配置同步時會使用
+-------------------+----------+--------------+------------------+ 注意:如果對數(shù)據(jù)庫 、表、數(shù)據(jù) 進(jìn)行編輯,文件名和位置會變化
1 row in set (0.00 sec)
(2)mysql 從服務(wù)器 slave 01 配置
[root@slave01 mysql]# vim /etc/my.cnf
server-id = 22
relay-log=relay-log-bin //IO線程通過讀取日志要放入relay-log 中
relay-log-index=slave-relay-bin.index //索引日志位置
重啟mysql 服務(wù)
[root@slave01 mysql]# systemctl restart mysqld.service
mysql> change master to master_host='192.168.213.170',master_user='myslave',master_password=''123456',master_log_file='master-bin.000001',master_log_pos=1086; //按主服務(wù)器結(jié)果更改命令中 master_log_file 和 master_log_pos 的參數(shù)
Query OK, 0 rows affected (0.01 sec)mysql> start slave; //啟動slave
Query OK, 0 rows affected (0.00 sec)mysql> show slave status\G; //查看slave狀態(tài)
Slave_IO_Running: Yes //讀取與重放日志兩個參數(shù)一定為 Yes
Slave_SQL_Running: Yes
(3)mysql 從服務(wù)器 slave 02 配置
[root@slave01 mysql]# vim /etc/my.cnf
server-id = 22
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
重啟mysql 服務(wù)
[root@slave01 mysql]# systemctl restart mysqld.service
mysql> change master to master_host='192.168.213.170',master_user='myslave',master_password=''123456',master_log_file='master-bin.000001',master_log_pos=1086;
Query OK, 0 rows affected (0.01 sec)mysql> start slave;
Query OK, 0 rows affected (0.00 sec)mysql> show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
五. 驗證主從同步
在 主服務(wù)器上創(chuàng)建一個庫,看從服務(wù)器上能否同步
mysql> create database school;
Query OK, 1 row affected (0.00 sec)
在從服務(wù)器查看數(shù)據(jù)庫
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| #mysql50#.mozilla |
| mysql |
| performance_schema |
| schoo |
| school |
| test |
+--------------------+
搭建 MySQL 讀寫分離
Amoeba(變形蟲)項目開源框架與2008年發(fā)布了一款 Amoeba for MySQL 軟件。這個軟件致力于 MySQL 的分布式數(shù)據(jù)庫前段代理層,它主要為應(yīng)用層訪問 MySQL 是充當(dāng) SQL 路由,并具有負(fù)載均衡、高可用性、SQL過濾、讀寫分離、可路由到相關(guān)目標(biāo)數(shù)據(jù)庫、可并發(fā)請求多臺數(shù)據(jù)庫。通過 Amoeba 能夠完成多數(shù)據(jù)源的高可用、負(fù)載均衡、數(shù)據(jù)切片的功能。
1. 在Amoeba 上安裝 Java 環(huán)境。
因為 Amoeba 是基于jdk 1.5 開發(fā)的,所以官方推薦使用jdk 1.5 或1.6 版本
[root@bogon Y2C]#systemctl stop firewalld.service #關(guān)閉防護(hù)墻
[root@bogon Y2C]#setenforce 0
[root@bogon Y2C]# cp jdk-6u14-linux-x64.bin /usr/local/ #將壓縮包復(fù)制到 /usr/local/ 目錄下
[root@bogon Y2C]# ./jdk-6u14-linux-x64.bin #根據(jù)提示輸入yes,按回車鍵完成即可
Do you agree to the above license terms? [yes or no]
Press Enter to continue.....
[root@bogon Y2C]# mv jdk1.6.0_14/ /usr/local/jdk1.6 #將壓縮包剪切到/usr/local/
[root@bogon Y2C]# vim /etc/profile #編輯系統(tǒng)環(huán)境變量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@bogon Y2C]# source /etc/profile #重新讀取系統(tǒng)環(huán)境變量
2 . 安裝并配置 Amoeba 軟件
[root@bogon Y2C]# mkdir /usr/local/amoeba #創(chuàng)建amoeba 安裝目錄
[root@bogon Y2C]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ #解壓amoeba 軟件包[root@bogon Y2C]# chmod -R 755 /usr/local/amoeba/ #遞歸修改權(quán)限
[root@bogon Y2C]# /usr/local/amoeba/bin/amoeba #查看amoeba 安裝狀態(tài)
amoeba start|stop //顯示此內(nèi)容說明 Amoeba 安裝成功
3. 配置Amoeba 讀寫分離,兩個 Slave 讀負(fù)載均衡
(1)在 Master 、slave1、slave2 數(shù)據(jù)庫中開放權(quán)限給 Amoeba 訪問
mysql> grant all on *.* to test@'192.168.213.%' identified by '123.com';
Query OK, 0 rows affected (0.00 sec)
(2)編輯 amoeba.xml 配置文件
[root@bogon Y2C]#cd /usr/local/amoeba/conf/
[root@bogon Y2C]#vim amoeba.xml
30 <property name="user">amoeba</property> #在30行作用 ,設(shè)置客戶端連接anoeba 的賬戶
31
32 <property name="password">123456</property> #設(shè)置客戶端連接amoeba 的密碼115 <property name="defaultPool">master</property> #編輯默認(rèn)地址池為名稱 master
116
117
118 <property name="writePool">master</property> #關(guān)閉注釋,寫入池名稱為 master
119 <property name="readPool">slaves</property> #關(guān)閉注釋,讀入池名稱為 slaves
(3)編輯 dbServers.xml 配置文件
[root@bogon Y2C]#cd /usr/local/amoeba/conf/
[root@bogon Y2C]#vim dbServers.xml
26 <property name="user">test</property> #編輯連接數(shù)據(jù)庫用戶
27
28
29 <property name="password">123.com</property> #編輯連接數(shù)據(jù)庫賬戶密碼45 <dbServer name="master" parent="abstractServer"> #指定 master 服務(wù)器
46 <factoryConfig>
47
48 <property name="ipAddress">192.168.213.170</property> #指定主服務(wù)器的IP 地址<dbServer name="slave1" parent="abstractServer"> #指定 slave 1 服務(wù)器
53 <factoryConfig>
54
55 <property name="ipAddress">192.168.213.168</property> #指定slave 1 服務(wù)器的IP59 <dbServer name="slave2" parent="abstractServer"> #指定 slave 2 服務(wù)器
60 <factoryConfig>
61
62 <property name="ipAddress">192.168.213.171</property> #指定slave 1 服務(wù)器的IP 地址
63 </factoryConfig>
64 </dbServer><dbServer name="slaves" virtual="true"> #設(shè)置群集名稱 slaves
66 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
67 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
68 <property name="loadbalance">1</property>
69
70 <!-- Separated by commas,such as: server1,server2,server1 –>
71 <property name="poolNames">slave1,slave2</property> #定義群集池成員
72 </poolConfig>
73 </dbServer>
4 . 啟動 Amoeba ,器默認(rèn)端口為 tcp 8066
[root@bogon amoeba]# /usr/local/amoeba/bin/amoeba start&
[3] 5133
[root@bogon amoeba]# netstat -anpt | grep java
tcp6 0 0 127.0.0.1:38334 :::* LISTEN 5133/java
tcp6 0 0 :::8066 :::* LISTEN 5133/java
測試讀寫分離
(1)在 Client 端連接 Amoeba,通過代理訪問 MySQL:
[root@client ~]# mysql -uamoeba -p123 -h292.168.213.166 -P 8066
(2)在 Master 上創(chuàng)建表 info ,同步到曾服務(wù)器上,然后關(guān)閉曾服務(wù)器的 Slave 功能,在插入?yún)^(qū)別語句。
mysql> use school;
Database changedmysql> create table info (id int(10),name varchar(10));
Query OK, 0 rows affected (0.23 sec)
(3)分別關(guān)閉從服務(wù)器 slave 功能:
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
(4)在主服務(wù)器上 school 庫中的info 表中插入一條語句
mysql> insert into info values (1,'tom');
Query OK, 1 row affected (0.12 sec)mysql> select * from info;
+------+------+
| id | name |
+------+------+
| 1 | tom |+------+------+
(5)從服務(wù)器上同步了表,手動插入其他內(nèi)容
從服務(wù)器1
mysql> insert into info values (2,'li');
Query OK, 1 row affected (0.06 sec)從服務(wù)器2
mysql> insert into info values (3,'zh');
Query OK, 1 row affected (0.08 sec)
(6)測試讀的的客戶端查看操作,在
MySQL [school]> select * from info; #第一次查詢
+------+------+
| id | name |
+------+------+
| 2 | li |
+------+------+
1 row in set (0.06 sec)MySQL [school]> select * from info; #第二次查詢
+------+------+
| id | name |
+------+------+
| 3 | zh |
+------+------+
1 row in set (0.44 sec)
在客戶端只能讀取曾服務(wù)器上的內(nèi)容,無法讀取主服務(wù)器上的內(nèi)容,說明讀的操作在曾服務(wù)器上
(7)測試寫操作,在客戶端主機(jī)插入語句
MySQL [school]> insert into info values (5,'liu');
Query OK, 1 row affected (0.05 sec)
在客戶端查詢不到,最終只有在 Master 上才能看到這條語句,說明寫入操作在 Master 服務(wù)器上
mysql> select * from info;
+------+------+
| id | name |
+------+------+
| 1 | tom |
| 5 | liu |
+------+------+
由此驗證,已經(jīng)實現(xiàn)了 MySQL 讀寫分離,目前所有的寫操作全部在 Mater 主服務(wù)器上,用來避免數(shù)據(jù)的不同步;所有讀的操作都分?jǐn)偨o了 Slave 服務(wù)器,用來分擔(dān)數(shù)據(jù)庫的壓力。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。