(9) MySQL主主複製架構使用方法

来源:https://www.cnblogs.com/huchong/archive/2019/01/15/10262620.html
-Advertisement-
Play Games

一. 回憶主從複製的一些缺點 上節說到主從複製的一些問題 我們再來回憶一下 主從複製,增加了一個資料庫副本,從資料庫和主資料庫的數據最終會是一致的 之所以說是最終一致,因為mysql複製是非同步的,正常情況下主從複製數據之間會有一個微小的延遲 通過這個資料庫副本看似解決了資料庫單點問題,但並不完美 因 ...


一. 回憶主從複製的一些缺點

上節說到主從複製的一些問題
我們再來回憶一下
主從複製,增加了一個資料庫副本,從資料庫和主資料庫的數據最終會是一致的
之所以說是最終一致,因為mysql複製是非同步的,正常情況下主從複製數據之間會有一個微小的延遲
通過這個資料庫副本看似解決了資料庫單點問題,但並不完美
因為這種架構下,如果主伺服器宕機,需要手動切換從伺服器,業務中斷不能忍受,不能滿足應用高可用的要求

如果才能解決當master伺服器宕機後,前端應用自動切換鏈接呢?

二. 引入vip後的資料庫架構

最簡單的方式就是給資料庫複製集群上增加一個虛擬ip

虛擬IP(vip):

就是一個未分配給真實主機的ip,也就是說對外提供伺服器的主機除了有一個真實IP外還有一個虛擬IP

而前端應用程式使用虛擬ip來鏈接資料庫伺服器,當master宕機後,虛擬ip由masterDB遷移到slaveDB上,這樣就不用人為的修改前端應用的配置了

設置虛擬IP有很多種方法

除了腳本來實現這些功能,還可以通過MHA,MMM這樣的集群管理工具來實現

此處採用keepalived來配置虛擬ip

首先,keepalived可以提供vip,並對主從資料庫的健康狀態進行監控
當主DB宕機時,遷移VIP到主備資料庫伺服器上,這樣就解決了當masterDB宕機時,要手動修改應用伺服器的配置,從新連接到主備伺服器上的問題

但是目前還存在一個問題,當master恢復後,由於當前的寫操作遷移到了從上,所以如果要使用到老的master對新的master(也就是老的slave)進行同步,就不得不重新配置主從複製了,特別是在基於日誌點的複製情況下,這時候如果我們資料庫的數據量非常大,在這種情況下,重新初始化數據也是比較耗時的
所以我們要對主從複製的架構進行一些更改,改變原來的主從複製為主主複製,但一定要保證同一個時間只有一個主提供服務,而另一個主(也就是主備)是處於只讀狀態的,只對外提供讀服務,而不提供寫服務

以前說過InnoDB表的主鍵最好採用自增ID的列,而在主主複製中,為了避免兩個主中同時寫帶來的主鍵衝突,我們需要修改自增主鍵的一些配置,使兩個主上的自增主鍵按照不同的步長進行增長 ,這隻是為了以防萬一採取的一個配置,當我們使用主主複製時,還是要保證在任意時間,均只有一個主可以對外提供服務 ,而另一個主只提供只讀的服務

三. 主主複製配置調整

master 資料庫配置修改

auto_increment_increment = 2    # 控制自增ID增長的步長,預設為1
auto_increment_offset = 1 # 控制自增ID從哪個值開始

這樣修改後,id將會變成1,3,7,9...的形式

主備資料庫配置修改

auto_increment_increment = 2    # 控制自增ID增長的步長,預設為1
auto_increment_offset = 2  # 控制自增ID從哪個值開始

這樣修改後,id將會變成2,4,6,8...的形式

Keepalived簡介

Keepalived基於ARRP網路協議,ARRP可以將2台設備虛擬成一個設備,可對外提供一個虛擬IP,也就是我們架構中的vip,在伺服器內部實際上是擁有虛擬IP的設備如果正常工作的話就是MASTER設備,同一組內其他伺服器不能用這個虛擬IP,狀態是屬於BACKUP狀態,處於BACKUP狀態的設備,除了接收MASTER的ARRP狀態通告之外,不執行任何對外的服務,當主機失效時,backup將接管原先的master的虛擬IP以及對外提供的各項服務

安裝

yum install keepalived -y

keepalived配置

在主和主備伺服器上都要安裝和配置keepalived

配置文件所在位置
/etc/keepalived/keepalived.conf

配置文件中是按模塊劃分的

! Configuration File for keepalived

global_defs {
   router_id mysql_ha
}
vrrp_script check_run {
    script "/etc/keepalived/check_mysql.sh"
    interval 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 200
    priority 99
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1200
    }
   
  track_script {
         check_run
     }

   virtual_ipaddress {
      192.168.3.99/24
    }
}

vrrp_script模塊中:
定義用於檢查mysql是否運行正常的腳本,以及檢查的時間間隔
vrrp_instance 模塊中:
定義了keepalived服務所處的狀態,這個狀態只有BACKUP和MASTER兩個值
interface :定義了綁定 虛擬ip的網路介面,一定要是伺服器上可用的網路介面
virtual_router_id :定義了虛擬服務的id,要取0到255之間的數字
priority :定義了優先順序,值越高,優先順序越大,備份的備設備的值要比主設備低
nopreempt:此值代表不搶占資源,意思是原來的主宕機後,即使再恢復後也不會把虛擬IP搶回來,對於資料庫來說,這樣可以避免主從切換的二次傷害的可能
authentication :配置驗證信息,這個在兩個節點必須是一致的
virtual_ipaddress :定義了使用的虛擬ip信息

四. 演示使用

1. 修改主、主備伺服器配置

[client]
port  = 3306     # 客戶端埠號為3306
socket = /home/mysql/data/mysql.sock

[mysqld]

# skip #
skip_name_resolve = 1
skip-external-locking =1

# GENERAL #
user = mysql   # MySQL啟動用戶
default_storage_engine = InnoDB  # 新數據表的預設數據表類型
character-set-server = utf8      #     #服務端預設編碼(資料庫級別)
socket = /home/mysql/data/mysql.sock
pid_file =  /home/mysql/data/mysqld.pid
basedir = /home/mysql    #使用該目錄作為根目錄(Mysql安裝目錄);

port = 3306
bind-address = 0.0.0.0
log_error_verbosity = 3
explicit_defaults_for_timestamp = off
#sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#sql_mode = NO_ENGINE_SUBSTITUTION

# undo log
# innodb_undo_directory = /home.mysql/undo
# innodb_undo_tablespaces = 32

# MyISAM #
key_buffer_size =32M

# SAFETY #
max_allowed_packet    = 100M
max_connect_errors    = 1000000
sysdate_is_now    =1
#innodb = FORCE
#innodb_strict_mode = 1  

# Replice #
server-id = 100
relay_log =  /home/mysql/sql_log/mysqld-relay-bin 

#plugin-load = semisync_master.so
log_slave_updates = on
master_info_repository = TABLE
relay_log_info_repository =TABLE

#######主主複製新增的配置###########
auto_increment_increment = 2    # 控制自增ID增長的步長,預設為1
auto_increment_offset = 1 # 控制自增ID從哪個值開始
#####################

# gtid_mode = on
# enforce_gtid_consistency =on
# skip-slave-start =1
#rpl_semi_sync_master_enabled = 1
#rpl_semi_sync_master_timeout=200    # 0.2 second
master_info_respository = TABLE
# gtid_mode= on
# enforce_gtid_consistency = on
# skip-slave-start = 1

# DATA STORAGE #

datadir = /home/mysql/data     #mysql 數據文件存放的目錄
tmpdir = /tmp    # MySQL存放臨時文件的目錄

# BINARY LOGGING #

log_bin = /home/mysql/sql_log/mysql-bin
max_binlog_size  = 1000M
binlog_format = row
expire_log_days = 7
sync_binlog = 1

# CACHES AND LIMITS #

tmp_table_size = 32M
max_heap_table_size = 32M
query_cache_type = 0    

auto_increment_increment ,auto_increment_offset 這兩個參數是動態參數,我們可以直接通過命令進行修改,不需要重啟

查看並修改
命令如下

mysql> show variables like 'auto%';
mysql> set global auto_increment_increment=2;
mysql> set global auto_increment_offset =1;

從伺服器配置進行類似修改即可

從伺服器配置

[client]
port  = 3306     # 客戶端埠號為3306
socket = /home/mysql/data/mysql.sock

[mysqld]

# skip #
skip_name_resolve = 1
skip-external-locking =1

# GENERAL #
user = mysql   # MySQL啟動用戶
default_storage_engine = InnoDB  # 新數據表的預設數據表類型
character-set-server = utf8      #     #服務端預設編碼(資料庫級別)
socket = /home/mysql/data/mysql.sock
pid_file =  /home/mysql/data/mysqld.pid
basedir = /home/mysql    #使用該目錄作為根目錄(Mysql安裝目錄);

port = 3306
bind-address = 0.0.0.0
log_error_verbosity = 3
explicit_defaults_for_timestamp = off
#sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#sql_mode = NO_ENGINE_SUBSTITUTION
read_only = on

# undo log
# innodb_undo_directory = /home.mysql/undo
# innodb_undo_tablespaces = 32

# MyISAM #
key_buffer_size =32M

# SAFETY #
max_allowed_packet    = 100M
max_connect_errors    = 1000000
sysdate_is_now    =1
#innodb = FORCE
#innodb_strict_mode = 1  

# Replice #
server-id = 101
relay_log =  /home/mysql/sql_log/mysqld-relay-bin 

#plugin-load = semisync_master.so
log_slave_updates = on
master_info_repository = TABLE
relay_log_info_repository =TABLE

#######主主複製新增的配置###########
auto_increment_increment = 2    # 控制自增ID增長的步長,預設為1
auto_increment_offset = 2 # 控制自增ID從哪個值開始
#####################

# gtid_mode = on
# enforce_gtid_consistency =on
# skip-slave-start =1
#rpl_semi_sync_master_enabled = 1
#rpl_semi_sync_master_timeout=200    # 0.2 second
master_info_respository = TABLE
# gtid_mode= on
# enforce_gtid_consistency = on
# skip-slave-start = 1

# DATA STORAGE #

datadir = /home/mysql/data     #mysql 數據文件存放的目錄
tmpdir = /tmp    # MySQL存放臨時文件的目錄

# BINARY LOGGING #

log_bin = /home/mysql/sql_log/mysql-bin
max_binlog_size  = 1000M
binlog_format = row
expire_log_days = 7
sync_binlog = 1

# CACHES AND LIMITS #

tmp_table_size = 32M
max_heap_table_size = 32M
query_cache_type = 0    
mysql> show variables like 'auto%';
mysql> set global auto_increment_increment=2;
mysql> set global auto_increment_offset =2;

從伺服器查看二進位日誌信息
命令

mysql> show master status \G

可以查看當前使用的日誌文件
File:mysql-bin:000003
和日誌點
Position:25423894

然後去主伺服器上使用change master命令

由於從到主的複製鏈路之前已開啟過,現在只需要配置主到從的

2. 配置啟動主到從的複製鏈路

由於是主主複製 是把當前的主當作從,把當前的從當作主,在主上配置的master_host的值是從的ip,

命令如下:

mysql> change master to master_host='192.168.2.100',
        -> master_user='dba_repl',
        -> master_password='123456',
        ->MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=25423894;

mysql> start slave;

3. 在主DB、主備DB的伺服器上分別安裝keepalived

yum install keepalived -y
[root@localhost ~]# cd /etc/keepalived/
[root@localhost keepalived]# ls
check_mysql.sh  keepalived.bak    keepalived.conf

check_mysql.sh 一定要有執行許可權

chmod a+x check_mysql.sh

4. 主從伺服器分別啟動keepalived

[root@localhost keepalived]#  /etc/init.d/keepalived start

啟動成功後,可以通過ip addr命令查看虛擬ip
可以通過手動關閉mysql模式宕機,查看主的ip addr中的虛擬Ip已不存在,此時已虛擬Ip在從伺服器上

五. 目前架構存在的問題

目前架構:

一臺主伺服器,一臺從伺服器,加入了keepalived服務來監控主從伺服器的運行健康狀態,並通過keepalived伺服器生成了一個虛擬IP,前端應用是通過虛擬IP來進行資料庫的訪問,並且為了使主庫宕機後能儘快恢復,把原來的主從複製改為了主主複製

存在的問題:

但是目前的讀寫操作還只是全部通過虛擬IP使用同一臺資料庫伺服器(主伺服器或主備伺服器)來進行訪問的,所以這個架構也沒有解決單台資料庫伺服器讀寫壓力大的問題

對於資料庫伺服器來說,讀負載和寫負載是兩個不同的問題

  1. 寫操作只能在Master資料庫上執行
  2. 讀操作既可以在Master庫上執行,也可以在Slave庫上執行

相對於寫負載,解決讀負載要更容易,因為我們可以很容易的得到多個slave伺服器,並且在正常的業務環境中資料庫所執行的讀操作次數要遠遠高於寫操作的次數
同時那些有性能問題的慢查詢,也都是讀操作產生的

六. 如何解決讀壓力大的問題?

  1. 進行讀寫分離,主伺服器主要執行寫操作
  2. 讀操作的壓力平均分攤到不同的SLAVE伺服器上
  3. 增加前端緩存伺服器如Redis,memcache等
    推薦使用redis緩存伺服器,redis優點:可持久化,可主從複製,可集群

解決方式見:如何解決MySQL讀壓力大的問題

七. 如何解決寫壓力大的問題

MySQL複製無法緩解寫壓力

利用緩存,合併多次寫為一次寫
緩解寫壓力需要對MasterDB進行拆分

前面資料庫操作規範中說過,程式所使用的資料庫賬號只能在同一個資料庫下進行操作,不允許跨庫查詢資料庫

對MasterDB進行拆分的步驟

MasterDB中有mc_userdb、mc_productdb、mc_orderdb三個資料庫

步驟1:按需求建立新的DB集群

建立好新的資料庫集群後,就可以在新老集群之間建立主從同步關係,把要拆分的DB同步到新的集群中
即 把mc_productdb同步到商品集群中 ,mc_orderdb同步到訂單集群中

步驟2:同步要拆分的DB到新的集群中

當資料庫同步成功後,找一個業務的低峰時間段,比如凌晨3、4點時,把老集群上資料庫的賬號,遷移到新的資料庫集群中

步驟3:遷移資料庫賬號到對應的新集群

遷移成功後,修改老集群的應用在老集群資料庫上的鏈接,把
對mc_productdb和mc_orderdb上的鏈接修改到新的集群上

步驟4:修改前臺應用的資料庫鏈接

步驟5:刪除之前建立的老資料庫集群到新資料庫集群的資料庫同步鏈接,將老集群上的mc_productdb和mc_orderdb備份後進行刪除


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Ubuntu安裝好後,自帶Firefox瀏覽器,有時我們需要再安裝幾個瀏覽器,那麼Google Chrome,就是首選, 安裝如下: 下載瀏覽器安裝包, 下載鏈接:https://dl.google.com/linux/direct/google-chrome-stable_current_amd6 ...
  • 當安裝好了 Windows 和 Ubuntu 雙系統之後,預設的啟動項是 Ubuntu,我們可以來設置預設的啟動項, 開機時,在啟動項選擇處,可以通過↑↓ 鍵來選擇啟動哪個系統,第一行序號是 0 ,第二行 序號是 1,依次類推, 博主的只有 4 項,也就是 4 行,Ubuntu 在第一行,對應序號 ...
  • 對於使用校園網的學生來說,安裝好Ubuntu之後,很多人需要用 DrClient 客戶端來上網,那麼怎麼操作呢, 這裡介紹 DrClient 客戶端在Ubuntu上的使用方法, 首先下載 對應版本的軟體包,,有 Linux 64位 和 Linux 32位,然後解壓,打開文件夾, 這個時候雙擊 DrC ...
  • 《Orange'S 一個操作系統的實現》源代碼 《Linux 0.11 內核完全註釋》源代碼 閑來無事,在 64 位 ubuntu-16 中,把 Orange'S 和 linux-0.11 又重新實現了一遍,運行無誤。 這兩本書,可在百度中搜索獲取,自不待言。 Orange‘S 需要註意的是,為 < ...
  • 目錄 一、製作linux啟動盤 1.1. 準備工作 1.2. 製作linux系統U盤 二、使用U盤安裝Centos7.6 2.1. 使用U盤啟動 2.2. 更改安裝配置 2.3. 開始安裝 回到頂部 一、製作linux啟動盤 使用光碟刻錄軟體將系統鏡像刻錄到U盤後使用U盤安裝系統。 1、 準備 1個 ...
  • 自上而下從應用層到底層分析 app: QQ、微信、游戲、控制界面 GUI圖形用戶界面(Graphical User Interface,簡稱 GUI,又稱圖形用戶介面):QT(C++)、Android(java)、GTK(C) 文件系統 內核:Linux、Android、windows Bootlo ...
  • [root@nfs01 backup]# rsync -avz /backup [email protected]::backupPassword: @ERROR: auth failed on module backuprsync error: error starting clie ...
  • 博主的電腦是Win10系統,在修改完系統的用戶文件夾名後,桌面右擊出現了反應卡頓的現象,並且點擊輸入法,也變得卡頓。問題解決後,於是想簡單記錄一下。 還是註冊表的問題,使用Win+R快捷鍵,打開運行,輸入regedit,開啟註冊表編輯器,按照路徑順序打開 HKEY_CLASSES_ROOT\Dire ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...