MySQL Scale Out

簡介html

MySQL複製中較常見的複製架構有「一主一從」、「一主多從」、「雙主」、「多級複製」和「多主環形機構」等,見下圖;前端

wKioL1NpEgORcF2XAATJgegMOXY343.jpg

最經常使用,也最靈活的就要數「一主多從」複製架構了,其能知足多種需求,如:mysql

  • 爲不一樣的角色使用不一樣的備庫(例如添加不一樣的索引或使用不一樣的存儲引擎);sql

  • 把一臺備庫當作待用的主庫,除了複製沒有其它數據傳輸;數據庫

  • 將一臺備庫放在遠程數據中心,用做災難恢復;bash

  • 延遲一個或多個備庫,以備災難恢復;服務器

  • 使用其中一個備庫,做爲備份、培訓、開發或者測試使用服務器;架構

而「雙主」複製架構則用於特殊的場景下,如兩個處於不一樣地理位置的辦公室,且都須要一份可寫的數據拷貝;socket

這種架構最大的問題是如何解決數據衝突和不一致,尤爲當兩臺服務器同時修改同一行記錄,或同時在兩臺服務器上向一個包含auto_increment列的表裏插入數據時;ide

而經過將一臺服務器設置爲只讀的被動服務器,則能夠很好的避免數據寫入衝突的問題,這種主動-被動模式下的主-主複製架構使得反覆切換主動和被動服務器很是方便,能夠實如今不關閉服務器的狀況下執行維護、優化表、升級操做系統或其餘任務;

配置主動-被動模式的主-主複製架構的通常流程:

  • 確保兩臺服務器上有相同的數據;

  • 啓用二進制日誌,選擇惟一的服務器ID,並建立複製帳號;

  • 啓用備庫更新的日誌記錄,這是故障轉移和故障恢復的關鍵;

  • 把被動服務器配置成只讀,防止可能與主動服務器上的更新產生衝突;

  • 啓動每一個服務器的MySQL實例;

  • 將每一個主庫設置爲對方的備庫,使用新建立的二進制日誌開始工做;

同時爲了消除不一樣地理位置的站點單點故障問題,能夠爲每一個主庫增長冗餘,即爲每個主庫增長一個從庫;

而MMM(=Master-Master Replication Manager for MySQL)則是一套腳本集合,用以監控、管理雙主複製架構,經過設置一個可寫的VIP和多個只讀的VIP,完成故障自動轉移、讀負載分攤等功能;

 

架構設計

wKioL1NpEpCy3ACaAANLNO70Ry8648.jpg

服務器規劃

wKiom1NpEumSkjTxAANRsHszrDg860.jpg

虛IP規劃

wKioL1NpEtqCa90KAAKmQ02Oj3k481.jpg

 

配置部署

雙主複製架構部署

MySQL或MariaDB的安裝初始化可詳見博客「MySQL架構

利用mysqld_multi在一臺主機上啓動多個mysqld實例

數據庫初始化

# 在主機Host1和Host2上
cd /usr/local/mysql
scripts/mysql_install_db --user=mysql --datadir=/data/mariadb_data_3406/
scripts/mysql_install_db --user=mysql --datadir=/data/mariadb_data_3506/

 

數據庫配置

 

# 在主機Host1上
vi /etc/my.cnf
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
[mysqld1]
port = 3406
socket = /tmp/mysql3406.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 2
datadir = /data/mariadb_data_3406
innodb_file_per_table = 1
default_storage_engine = InnoDB
log-bin=mysql-bin
relay-log=/data/relaylogs_3406/relay-bin # 指定中繼日誌路徑
log_slave_updates=1 # 開啓從庫更新操做寫入二進制日誌功能
auto_increment_increment=2 # 雙主複製中自增加字段的步長
auto_increment_offset=1 # 雙主複製中自增加字段的起始值,此爲1
sync_binlog = 1 # 可保證事務日誌及時寫入磁盤文件
binlog_format=row
server-id = 11  # 注意server-id的惟一性
[mysqld2]
port = 3506
socket = /tmp/mysql3506.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 2
datadir = /data/mariadb_data_3506
innodb_file_per_table = 1
default_storage_engine = InnoDB
log-bin=mysql-bin
relay-log=/data/relaylogs_3506/relay-bin
log_slave_updates=1
sync_binlog = 1
binlog_format=row
server-id = 12
# 在主機Host2上
vi /etc/my.cnf
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
[mysqld1]
port = 3406
socket = /tmp/mysql3406.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 2
datadir = /data/mariadb_data_3406
innodb_file_per_table = 1
default_storage_engine = InnoDB
log-bin=mysql-bin
relay-log=/data/relaylogs_3406/relay-bin
log_slave_updates=1
auto_increment_increment=2 # # 雙主複製中自增加字段的步長
auto_increment_offset=2 # 雙主複製中自增加字段的起始值,此爲2
sync_binlog = 1
binlog_format=row
server-id = 21
[mysqld2]
port = 3506
socket = /tmp/mysql3506.sock
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 2
datadir = /data/mariadb_data_3506
innodb_file_per_table = 1
default_storage_engine = InnoDB
log-bin=mysql-bin
relay-log=/data/relaylogs_3506/relay-bin
log_slave_updates=1
sync_binlog = 1
binlog_format=row
server-id = 22
####################################
主:
log-bin=mysql-bin
log-slave-updates=1
sync-binlog=1
binlog_format=row
relay-log= /data/relaylogs/relay-bin
server-id = 11
auto-increment-increment = 2
auto-increment-offset = 2

####################################
主:
log-bin=/data/binlogs/master-bin
binlog_format=row
sync_binlog = 1
log_slave_updates = 1
auto-increment-increment = 2
auto-increment-offset = 1
server-id = 21
relay-log = /data/relaylogs/relay-bin

######################################
從:
log-bin=mysql-bin
relay-log = /data/relaylogs/relay-bin
binlog_format=row
sync-binlog = 1
log-slave-updates = 1
datadir=/mydata/data
server-id = 12

#####################################
從:
relay-log=/data/relaylogs/relay-bin
log-bin=mysql-bin
binlog_format=row
log_slave_updates=1
sync-binlog =1
server-id = 22

 

啓動數據庫實例

# 在主機Host1和Host2上
/etc/init.d/mysqld_multi start 1 # 中止服務操做是/etc/init.d/mysqld_multi stop 1
/etc/init.d/mysqld_multi start 2 # 中止服務操做是/etc/init.d/mysqld_multi stop 2

登陸數據庫

# 在主機Host1和Host2上
mysql -S /tmp/mysql3406.sock # 登陸master1或master2
mysql -S /tmp/mysql3506.sock # 登陸slave1或slave2

 

建立所需帳戶(在Master1實例上)

grant replication client on *.* to '3m_moni'@'192.168.0.%' identified by '3m_12345'; # 建立MMM的監控帳戶
grant super,replication client,process on *.* to '3m_agen'@'192.168.0.%' identified by '3m_12345'; # 建立MMM的代理帳戶
grant replication slave on *.* to '3m_repl'@'192.168.0.%' identified by '3m_12345'; # 建立複製帳戶

 

配置數據同步

# 每次從庫鏈接主庫前,需先查詢對應主庫的二進制日誌文件及其事件位置,即在主庫上執行show master status便可,據此決定從庫鏈接時的master_log_file和master_log_pos參數;
# slave1實例上
change master to master_host='192.168.0.45',master_port=3406,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000001',master_log_pos=2448;
# master2實例上
change master to master_host='192.168.0.45',master_port=3406,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000002',master_log_pos=365;
# slave2實例上
change master to master_host='192.168.0.46',master_port=3406,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000004',master_log_pos=342;
# master1實例上
change master to master_host='192.168.0.46',master_port=3406,master_user='3m_repl',master_password='3m_12345',master_log_file='mysql-bin.000004',master_log_pos=342;

查看同步狀態

# 重點檢查Slave_IO_Running、Slave_SQL_Running和Master_Server_Id等參數
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.45
                  Master_User: 3m_repl
                  Master_Port: 3406
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000005
          Read_Master_Log_Pos: 326
               Relay_Log_File: relay-bin.000010
                Relay_Log_Pos: 613
        Relay_Master_Log_File: mysql-bin.000005
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
             Master_Server_Id: 11

 

MMM安裝部署

Host1主機上:部署agent和monitor

 

yum -y install mysql-mmm-*
# 配置公共設置
vi /etc/mysql-mmm/mmm_common.conf
active_master_role      writer
<host default>
    cluster_interface       eth0
    pid_path                /var/run/mysql-mmm/mmm_agentd.pid
    bin_path                /usr/libexec/mysql-mmm/
    replication_user        3m_repl# 複製帳戶
    replication_password    3m_12345# 複製帳戶密碼
    agent_user              3m_agen# agent帳戶
    agent_password          3m_12345# agent帳戶密碼
</host>
<host db1>
    ip      192.168.0.45
    mysql_port 3406# 可指定需鏈接的mysqld的端口
    mode    master
    peer    db2# peer表示db一、db2是同等級別的
</host>
<host db2>
    ip      192.168.0.46
    mysql_port 3406
    mode    master
    peer    db1
</host>
<host db3>
    ip      192.168.0.45
    mysql_port 3506
    mode    slave
</host>
<host db4>
    ip      192.168.0.46
    mysql_port 3506
    mode    slave
</host>
<role writer>
    hosts   db1, db2
    ips     192.168.0.11# 可寫VIP只配置一個
    mode    exclusive# 表示排它
</role>
<role reader>
    hosts   db1, db2,db3,db4
    ips     192.168.0.12,192.168.0.13,192.168.0.14,192.168.0.15 # 只讀VIP可配置多個
    mode    balanced# 表示能夠共用
</role>
==========
scp mmm_common.conf 192.168.0.46:/etc/mysql-mmm/ # 將公共配置文件拷貝至其它主機
==========
# 配置監控設置
vi /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
<monitor>
    ip                  127.0.0.1
    pid_path            /var/run/mysql-mmm/mmm_mond.pid
    bin_path            /usr/libexec/mysql-mmm
    status_path         /var/lib/mysql-mmm/mmm_mond.status
    ping_ips            192.168.0.45,192.168.0.46# 健康監測時需ping的主機IP,不是VIP哦
    auto_set_online     60
</monitor>
<host default>
    monitor_user        3m_moni# 監控帳戶
    monitor_password    3m_12345 # 監控帳戶密碼
</host>
debug 0
# 配置agent設置
vi /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1# 由於在一臺主機上啓用了2個mysqld實例,故可配置2個this參數哦
this db3

 

Host2主機上:只需部署agent

yum -y install mysql-mmm-agent
# 配置agent設置
vi /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db2
this db4

服務啓動

# 在主機Host1上
service mysql-mmm-agent  [root@mysql mysql
-mmm]# mmm_control show db1(192.168.0.45) master/ONLINE. Roles: reader(192.168.0.14), writer(192.168.0.11) db2(192.168.0.46) master/ONLINE. Roles: reader(192.168.0.13) db3(192.168.0.45) slave/ONLINE. Roles: reader(192.168.0.15) db4(192.168.0.46) slave/ONLINE. Roles: reader(192.168.0.12)

測試驗證

查看雙主複製架構中基於MMM實現的狀態信息

 service mysql-mmm-monitor  start
# 在主機Host1上 [root@mysql mysql
-mmm]# mmm_control show db1(192.168.0.45) master/ONLINE. Roles: reader(192.168.0.14), writer(192.168.0.11) db2(192.168.0.46) master/ONLINE. Roles: reader(192.168.0.13) db3(192.168.0.45) slave/ONLINE. Roles: reader(192.168.0.15) db4(192.168.0.46) slave/ONLINE. Roles: reader(192.168.0.12)

手動進行各節點的健康監測

# 在主機Host1上
[root@mysql mysql-mmm]# mmm_control checks
db4  ping         [last change: 2014/05/06 22:38:27]  OK
db4  mysql        [last change: 2014/05/06 22:38:27]  OK
db4  rep_threads  [last change: 2014/05/06 22:38:27]  OK
db4  rep_backlog  [last change: 2014/05/06 22:38:27]  OK: Backlog is null
db2  ping         [last change: 2014/05/06 22:38:27]  OK
db2  mysql        [last change: 2014/05/06 22:38:27]  OK
db2  rep_threads  [last change: 2014/05/06 22:38:27]  OK
db2  rep_backlog  [last change: 2014/05/06 22:38:27]  OK: Backlog is null
db3  ping         [last change: 2014/05/06 22:38:27]  OK
db3  mysql        [last change: 2014/05/06 22:38:27]  OK
db3  rep_threads  [last change: 2014/05/06 22:38:27]  OK
db3  rep_backlog  [last change: 2014/05/06 22:38:27]  OK: Backlog is null
db1  ping         [last change: 2014/05/06 22:38:27]  OK
db1  mysql        [last change: 2014/05/06 22:38:27]  OK
db1  rep_threads  [last change: 2014/05/06 22:38:27]  OK
db1  rep_backlog  [last change: 2014/05/06 22:38:27]  OK: Backlog is null 

補充說明

  • 在本篇的演示案例中,前端程序若要與MySQL通訊,則寫庫需鏈接192.168.0.11:3406,讀庫可鏈接192.168.0.12-15中的一個或多個,端口多是3406或3506;

  • 在只讀VIP漂移時,會致使前端程序鏈接的mysqld端口發生變化,因此生產環境下仍是統一使用3306端口爲宜;

  • 利用MMM實現了雙主複製架構中的故障自動轉移後,mysql並不是直接與前端程序通訊,還需配合使用讀寫分離器(如Ameoba),以統一對外的鏈接地址,由讀寫分離器負責讀寫的向下分配;

相關文章
相關標籤/搜索