主從架構
主從架構的原理就是從節點通過獲取主節點的二進制日志,重放執行sql語句來達到和主節點數據同步。如下圖:
主從架構有基本的一主一從,有一主多從,有循環復制(就是每個是下一個的主,是上一個的從,圍城一個環),級連復制(分配一個從節點,讓他從主節點上獲取二進制日志并發送給其他從節點,用來分擔主節點的壓力,而他自己本身不去重放二進制日志)
然后從另一個角度又可以分為異步主從和半同步主從,主從默認就是異步的,主節點寫數據可以是多線程同時及逆行,而從節點通過主節點的二進制日志去重讀操作的過程是單進程的,所以默認為異步。所謂半同步就是指定一個或者多個從節點,請求的寫操作不僅在主節點寫完,還要在在從節點也同步完成后主節點才返回給客戶端處理完成的信息,而沒有指定的從節點仍然是異步的,所以叫做半同步。
下面我們來實現最簡單的一主一從
我們先來理一下思路,做主從首先將時間同步,然后主節點開啟二進制日志,從節點開啟中繼日志,主節點要創建一個能用來同步的賬號,然后從服務器使用這個賬號去找主節點去同步。
1.環境
- 主節點ip:172.16.200.102
- 從節點ip:172.16.200.101
- 兩個服務器時間同步,都使用centos6.9系統,mysql版本為5.1.73
- 防火墻和selinux確保是關閉的
2.主節點上修改配置文件/etc/my.cnf,在[mydqld]段中添加如下內容
server-id=1
log-bin=binlog
skip_name_resolve
3.從節點上修改配置文件/etc/my.cnf,在[mysqld]段中添加如下內容
server-id=2
relay_log=relaylog #開啟中繼日志
skip_name_resolve
read_only=ON
啟動從節點mysqld
4.主節點上授權用戶
啟動mysqld,然后授權一個能做主從的賬號,根據最小權限準則,我們使用如下權限:
mysql> grant replication client,replication slave on *.* to 'repluser'@'172.16.200.%' identified by '123';
然后查詢binlog日志位置并記錄,方便從節點同步時不會處亂子
mysql> show master status;
+---------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| binlog.000003 | 356 | | |
+---------------+----------+--------------+------------------+
這里看到當前的binlog日志使用的是binlog.000003,位置是在356處
5.配置從節點
登陸到從節點上,執行如下操作
mysql> change master to master_host='172.16.200.102',master_user='repluser',master_pas
sword='123',master_log_file=' binlog.000003',master_log_pos=356;
#master_log_file就是主節點的二進制日志,master_log_pos為二進制日志位置
mysql> start slave; #開啟io線程和sql線程,單獨開一個就在后邊跟上想要開啟的線程名就行
mysql> show slave status\G #查看如下兩個線程是不是已經顯示YES
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
6.此時,一個簡單的主從復制就已經成功了,我們可以在主節點上創建一個表,在從節點看一下有沒有,有的話實驗成功。
半同步實現
之前我們講了半同步的原理,實現需要通過加載插件來完成,步驟如下:
1.環境
半同步基于semisync_master.so和semisync_slave.so這兩個插件來完成,注意較老版本的mysql可能沒有這兩個插件
- 主節點:172.16.200.107,mariadb5.5.52
- 從節點:172.16.200.108,mariadb5.5.52
- 時間同步,selinux和防火墻關閉
2.主節點上加載這兩個插件并啟用
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%'; #查看插件裝載上了,但是處于OFF狀態
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+
MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled=ON; #設置插件為啟用狀態
3.從節點上安裝配套的從節點插件
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
MariaDB [(none)]> stop slave IO_THREAD;
MariaDB [(none)]> start slave IO_THREAD;
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)
主從復制的讀寫分離
主從復制只是將從節點和主節點的數據做了備份,要分散各個節點的壓力,就要讓讀請求去找從節點,而寫請求去找主節點,這樣就可以分散各個節點的壓力。而要實現這種功能,一般的反向代理像nginx,haproxy是實現不了的,需要一個能識別mysql協議的代理,這里我們使用proxysql來實現。
我們到http://www.proxysql.com/去下載一個最新版本的proxysql,進去之后點download后就會跳轉到下載節點,找到當前系統版本對應的包,下載就行,這里我們使用proxysql-1.3.6
實現步驟:
1.環境
這里我們還是使用上面的主從主機,然后添加一臺讀寫分離器主機,ip為172.16.200.109,將下載好的proxysql包放到/root下,關閉selinux和firewalld。
2.安裝proxysql和mysql客戶端
[root@localhost ~]# yum -y install ./proxysql-1.4.2-1-centos7.x86_64.rpm #在/root目錄下用yum安裝本地包
[root@localhost ~]# yum -y install mariadb
3.修改配置文件
[root@localhost ~]# rpm -qc proxysql-1.4.2-1
/etc/proxysql.cnf
[root@localhost ~]# vim /etc/proxysql.cnf
#在mysql_variables段中,修改監聽的端口
interfaces="0.0.0.0:3306;/tmp/proxysql.sock"
#在mysql_servers段中將第一個{}的內容注釋去掉,并在拷貝一份放到下面以此來做模板,然后修改
{
address = "172.16.200.107" #主節點ip
port = 3306
hostgroup = 0 #分組,主一個組,從一個組,編號不能一樣
status = "ONLINE"
weight = 1
compression = 0
max_replication_lag = 10
},
{
address = "172.16.200.108" #從節點ip
port = 3306
hostgroup = 1
status = "ONLINE"
weight = 1
compression = 0
max_replication_lag = 10
}
#mysql_users段中添加下面這段
{
username = "feng"
password = " 123"
default_hostgroup = 0
active = 1
}
#mysql_replication_hostgroups=段中添加
{
writer_hostgroup=0
reader_hostgroup=1
comment="test repl 1"
}
完成后在主節點上創建用戶feng,密碼為123,然后就可以用這個賬號在代理端登陸驗證了
[root@localhost ~]# mysql -S /tmp/proxysql.sock -ufeng -p123
mysql高可用
完成主從復制和讀寫分離之后,我們還需要做高可用,解決主節點是單點的問題,保證主節點掛掉后有從節點可以接管主節點的工作,這里我們使用MHA這款高可用程序。注意這里的高可用不是針對的proxysql這個讀寫分離器來做的,而讀寫分離器如果是單點可以使用別的方案,如keepalived等,這里就不說這些了。
MHA服務分為Manager節點和Node節點,服務端安裝Manager服務,而Node上安裝節點的工具
實現步驟:
1.環境
- 上邊實驗的環境,加上一臺ip為172.16.200.120的centos主機作為MHA.
- MHA需要從節點上一定要增加read_only=ON選項,如果從節點上沒有,就給加上。
- 確保每個節點的id必須唯一。
- 確保有一個賬戶可以在各個節點上都能有管理權限,這里我們上面創建了feng用戶擁有這個權限,所以就不在創建了。
- 下載 mha4mysql-node-0.56-0.el6.noarch.rpm mha4mysql-manager-0.55-0.el6.noarch.rpm這兩個包分別到從節點和主節點/root目錄下
2.由于從節點可能成為主節點,而主節點如果斷了在上線時就是從節點了,所以要在主節點和從節點的配置文件中都設置二進制日志和中繼日志;由于MHA在指定一個 新的主節點時,要讓這個準備升級的從節點和別的從節點做比較,如果有別的從節點上有而本從節點沒有的東西就都要傳過來,讓自己也擁有,這樣能避免不同步的問題,而要實現這個功能就需要通過中繼日志來做比較,而中繼日志默認是會自動清理的,所以需要在配置文件中加入選項,關閉自動清理中繼日志的功能。
主節點/etc/my.cnf配置文件中增加中繼日志選項
relay-log=relay-bin
從節點/etc/my.cnf增加二進制日志選項,關閉自動清理中繼日志
log-bin=bin_log
relay_log_purge=0
重啟這些服務
3.MHA集群中各個節點彼此之間需要基于ssh互相通信,以實現遠程控制及數據管理。所以我們需要在一個節點上配置密鑰對,然后將私鑰和authorized_keys文件拷貝到別的節點上,這樣就能實現集群中各主機之間無密碼直接通信了。
我們在MHA主機上創建密鑰對:
[root@localhost ~]# ssh-keygen -t rsa -P ''
[root@localhost ~]# for i in {7..9};do scp -p -r .ssh/ root@172.16.200.10$i:/root/.ssh
/;done #將生成的鑰匙文件目錄整個復制到各個節點上
測試用ssh連接,發現不用輸入密碼了,就成功了
4.安裝MHA的程序
在MHA主機上安裝Manager
[root@localhost ~]# cd
[root@localhost ~]# yum -y install ./mha4mysql-manager-0.55-0.el6.noarch.rpm
各個節點上安裝node
[root@localhost ~]# cd
[root@localhost ~]# yum -y install ./mha4mysql-node-0.56-0.el6.noarch.rpm
5.在MHA中,每一個被監控的集群叫做一個application,而每個監控的app需要單獨創建一個配置文件。所以下邊我們自己定義配置文件,并加入配置:
[root@localhost ~]# mkdir /etc/mha
[root@localhost ~]# cd /etc/mha
[root@localhost mha]# vim app1.cnf
[server default]
user=feng
password=123
manager_workdir=/data/masterha/app1
manager_log=/data/masterha/app1/manager.log
remote_workdir=/dta/masterha/app1
ssh_user=root
repl_user=repluser
repl_password=123
ping_interval=1
[server1]
hostname=172.16.200.107
candidate_master=1 #設置能成為主節點
[server2]
hostname=172.16.200.108
candidate_master=1
然后測試ssh是否連通
[root@localhost mha]# masterha_check_ssh --conf=/etc/mha/app1.cnf
測試集群是否正確
[root@localhost mha]# masterha_check_repl --conf=/etc/mha/app1.cnf
如果出現ERROR提示User repluser does not exist,原因是之前主從實驗時,在主節點創建的repluser用戶沒有同步到從節點,我們只需要在主節點再次執行授權repluser用戶的語句就可以同步到從節點了,如下
MariaDB [(none)]> grant replication client,replication slave on *.* to 'repluser'@'172
.16.200.%' identified by '123';
在后臺運行程序,并且將日志記錄
[root@localhost mha]# nohup masterha_manager --conf=/etc/mha/app1.cnf > /data/masterha/app1/manager.log 2>&1 &
測試集群運行狀態
[root@localhost mha]# masterha_check_status --conf=/etc/mha/app1.cnf
6.模擬故障
我們手動關閉主節點,然后去恢復集群
主節點關閉后,檢測程序就會自動停止,所以配置完主節點后要再次啟用檢測層序。
在主節點上關閉mariadb
[root@localhost ~]# service mariadb stop
然后在172.16.200.108這個從上查看
MariaDB [feng]> show global variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only | OFF |
+---------------+-------+
我們看到之前在配置文件中設置的只讀選項成為了OFF,證明MHA已經將這個從節點設置成為主節點。
7.恢復
我們接下來要做的就是將之前宕掉的主節點現在設置為從節點,讓他上線正常運行,然后將MHA程序再運行起來。