MySQL+mmm+proxy實現MySQL讀寫分離及HA

jopen 11年前發布 | 29K 次閱讀 MySQL 數據庫服務器
引言
Master-Slave 的數據庫機構解決了很多問題,特別是read/write比較高的web2.0應用:
1 、寫操作全部在Master結點執行,并由Slave數據庫結點定時(默認60s)讀取Masterbin-log
2 、將眾多的用戶讀請求分散到更多的數據庫節點,從而減輕了單點的壓力
這是對Replication的最基本陳述,這種模式的在系統Scale-out方案中很有引力(如有必要,數據可以先進行Sharding,再使用replication)
它的缺點是:
1 Slave實時性的保障,對于實時性很高的場合可能需要做一些處理
2 、高可用性問題,Master就是那個致命點( SPOF:Single point of failure)
本文主要討論的是如何解決第2個缺點。
DB 的設計對大規模、高負載的系統是極其重要的。高可用性( High availability) 在重要的系統(critical System)是需要架構師事先考慮的。存在 SPOF:Single point of failure 的設計在重要系統中是危險的。
Master-Master Replication
1 、使用兩個MySQL數據庫db01,db02,互為MasterSlave,即:
一邊db01作為db02master,一旦有數據寫向db01時,db02定時從db01更新
另一邊db02也作為db01master,一旦有數據寫向db02時,db01也定時從db02獲得更新
( 這不會導致循環,MySQL Slave默認不會記錄Master同步過來的變化)
2 、但從AppServer的角度來說,同時只有一個結點db01扮演Master,另外一個結點db02扮演Slave,不能同時兩個結點扮演Master。即AppSever總是把write操作分配某個數據庫(db01),除非db01 failed,被切換。
3 、如果扮演Slave的數據庫結點db02 Failed了:
a) 此時appServer要能夠把所有的read,write分配給db01read操作不再指向db02
b) 一旦db02恢復過來后,繼續充當Slave角色,并告訴AppServer可以將read分配給它了
4 、如果扮演Master的數據庫結點db01 Failed
a) 此時appServer要能夠把所有的寫操作從db01切換分配給db02,也就是切換Masterdb02充當
b)db01 恢復過來后,充當Slave的角色,Masterdb02繼續扮演
難點:
3 4要如何自動進行?
Master-Master with n Slaves Replication
MySQL+mmm+proxy實現MySQL讀寫分離及HA
這比上一個還要復雜,即:
當一個Master Fail時,所有的Slave不再從原來失敗的那個Master(db01)獲取更新日志,而應該自動切換到最新充當Master角色的數據庫db02
MMM a greate project!
MMM 的基本信息請參考它的網站(見后"參考資料")
MMM 3個重要的器件:
1 mmmd_mon - monitoring script which does all monitoring work and makes all decisions about roles moving and so on.
2 mmmd_agent - remote servers management agent script, whichprovides monitoring node with simple set of remote services to makeservers management easier, more flexible abd highly portable.
3 mmm_control - simple script dedicated to management of the mmmd_mon processes by commands.
每一個MySQL服務器器結點需要運行mmmd_agent,同時在另外的一個機器上(可以是獨立的一臺機器,也可以是和AppServer共享同一個服務器)運行mmmd_mon。形成1 * mmmd_mon + n * mmmd_agent的部署架構。
MMM 利用了虛擬IP的技術:1個網卡可以同時使用多個IP
( 所以使用MMM時,需要2*n+1IPnmysql數據庫結點個數,包括master,slave)
當有數據庫結點fail時,mmmd_mon檢測不到mmmd_agent的心跳或者對應的MySQL服務器的狀態,mmmd_mon將進行決定,并下指令給某個正常的數據庫結點的mmmd_agent,使得該mmmd_agent“篡位使用()剛才fail的那個結點的虛擬IP,使得虛擬IP實際從指向fail的那個機器自動轉為此時的這個正常機器。
注:據Qieqie猜測是將獲得的虛擬IP設置給網卡,也只能這樣了,改天測試驗證一下。
repeat:  MMM MySQL Master-Slave Replication絕對是一個很有益的補充!
整體架構的原理:
Webclient  數據請求至proxyproxy進行讀寫分發-轉至mmm機制-在檢測存活的機器進行讀與寫操作。在此之前這些機器與為master/slave.
本文測試環境如下:
主機名
IP
Port
App
目錄
備注
Node1
192.168.1.2
3306
mysql
/var/lib/mysql
數據庫服務器1
Node2
192.168.1.3
3306
mysql
/var/lib/mysql
數據庫服務器2
Mon
192.168.1.4
3306
Mysql
/var/lib/mysql
數據庫管理服務器
Proxy
192.168.1.5
4040
Proxy
數據庫代理(NLB)
node1 node2 數據庫服務器replication雙向 master-master 虛擬機有限,只能開4臺,因為node1node2即做讀又做寫。
 MySQL+mmm+proxy實現MySQL讀寫分離及HA


配置步驟:
Node1 node2 replication 雙向 master-master
Node1 node2  安裝mmm并配置mmm_regent.conf
Mon  安裝mmm并配置mmm_mon.conf
proxy 安裝mysql-proxy

一、配置node1 node2數據庫服務器replication雙向 master-master
1 、配置node1 同步
Mkdir /var/log/mysql
Chown mysql.mysql /var/log/mysql
my.cnf at db1 should have following options:
server-id =
1
log_bin =
mysql-bin
master_host
192.168.1.2
master_port
3306
master_user
replication
master_password
slave
mysql> grant replication slave on *.* to 'replication'@'%' identified by 'slave';
show slave status\G; 的結果:
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
         
2 、配置node2同步
Mkdir /var/log/mysql
Chown mysql.mysql /var/log/mysql
my.cnf at db1 should have following options:
server-id =
2
log_bin =
mysql-bin
master_host
192.168.1.3
master_port
3306
master_user
replication
master_password
slave
mysql> grant replication slave on *.* to 'replication'@'%' identified by 'slave';
show slave status\G; 的結果:
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
二、安裝部署MMM
目標主機:
Node1
192.168.1.2
Node2
192.168.1.3
Mon
192.168.1.4
1 、安裝mon主機軟件包
前提:
--
Algorithm-Diff-1.1902.tar.gz
--
Proc-Daemon-0.03.tar.gz
RPM
mysql-server-5.0.22-2.1
RPM
mysql-5.0.22-2.1
RPM
perl-DBD-MySQL-3.0007-1.fc6
--
mmm-1.0.tar.bz2
先安裝2perl的包:
--
Algorithm-Diff-1.1902.tar.gz
--
Proc-Daemon-0.03.tar.gz
perl 包的安裝過程都是:
perl Makefile.PL
make
make test
make install
安裝mmm
./install.pl
2 、安裝node1 node2 agent軟件包(使用agent功能)
mmm-1.0.tar.bz2
安裝mmm
./install.pl
三臺主機安裝以上軟件后進行配置過程
三:node1 node2 agent配置過程
$cd /usr/local/mmm/etc
$cp examples/mmm_agent.conf.examples ../mmm_agent.conf
node1 配置文件所需要修改的地方如下
cluster_interface eth0   --配置IP所用的網卡
# Define current server id this db1
this db1
mode master
# For masters peer db2
Peer db2
# Cluster hosts addresses and access params
host db1
ip 192.168.1.2
port 3306
user rep_agent
password RepAgent
host db2
ip 192.168.1.3
port 3306
user rep_agent
password RepAgent
Node2 配置文件所需要修改的地方如下
# Cluster interface
cluster_interface eth0   --配置IP所用的網卡
# Define current server id this db1
this db2
mode master
# For masters peer db2
Peer db1
# Cluster hosts addresses and access params
host db1
ip 192.168.1.2
port 3306
user rep_agent
password RepAgent
host db2
ip 192.168.1.3
port 3306
user rep_agent
password RepAgent
設置權限(node1/node2 
GRANT ALL PRIVILEGES on *.* to 'rep_monitor'@'%' identified by 'RepMonitor';
四、修改mon主機的配置文件 所需要修改的地方如下:
文件位置:/usr/local/mmm/etc/mmm_mon.conf
# Cluster interface
cluster_interface eth0  ----配置IP所用的網卡
# Cluster hosts addresses and access params
host db1
數據庫名
ip 192.168.1.2
node1 ip
port 3306
node1 port
user rep_monitor
node1  用戶(供mon監控使用,該用戶需要在db上添加)
password RepMonitor
對應密碼
mode master
模式
peer db2
slave 指定
host db2
意義同上
ip 192.168.1.3
port 3306
user rep_monitor
password RepMonitor
mode master
peer db1
# 后續如有添加需求,請按照上面格式填寫
active_master_role writer
# Mysql Reader role
讀規則
role reader
mode balanced
模式為均攤
servers db1,db2
規則覆蓋db1 db2(如有更多slave 繼續填寫,別忘了ip
ip 192.168.1.7 192.168.1.8
對應ip 虛擬的IP
# Mysql Writer role
role writer
寫規則
mode exclusive
模式為獨占
servers db1,db2
規則負載db1 db2
ip 192.168.1.9
兩臺數據庫公用一個ip為寫,采用HA模式,默認db1使用,db1下線db2接管此ip
五:測試MMM
db1/db2上啟動agent功能
/usr/local/mmm/scripts/init.d/mmm_agent start
mon上啟動mon功能
/usr/local/mmm/scripts/init.d/mmm_mon start
并對mon進行檢測
# mmm_control set_online db1
# mmm_control set_online db2
# mmm_control show   查看分配情況
正常情況下:
# mmm_control show
Servers status:
  db1(192.168.1.2): master/ONLINE. Roles: reader(192.168.1.7;), writer(192.168.1.9;)
  db2(192.168.1.3): master/ONLINE. Roles: reader(192.168.1.8;)
stop 192.168.1.3
# mmm_control show
Servers status:
  db1(192.168.1.2): master/ONLINE. Roles: reader(192.168.1.7;), writer(192.168.1.9;)
  db2(192.168.1.3): master/REPLICATION_FAIL. Roles: None
檢測出1.3出了故障.
等一會..進行了切換!因為讀寫是輪循的.這時寫切到了3
# mmm_control show
Servers status:
  db1(192.168.1.2): master/ONLINE. Roles: reader(192.168.1.7;)
  db2(192.168.1.3): master/ONLINE. Roles: reader(192.168.1.8;), writer(192.168.1.9;)
Telnet  任何一個虛擬IP 3306都是通的
五、mysql_proxymysql MMM集成的必要性
1 、實現mysql數據庫層的負載均衡
2 、數據庫節點實現HA動態切換
3 、讀寫分離,降低主數據庫負載
六、安裝mysql proxy
1 、下載proxy代碼包
svn上獲取最新代碼
2 、安裝
編譯好的版本安裝方法如下:
# tar zxf mysql-proxy-0.6.0-linux-rhas4-x86.tar.gz
# cd mysql-proxy-0.6.0-linux-rhas4-x86
# 可以看到有2個目錄
# ls
sbin share
# mv sbin/mysql-proxy /usr/local/sbin/
# ls share
mysql-proxy tutorial-constants.lua tutorial-packets.lua tutorial-rewrite.lua tutorial-warnings.lua tutorial-basic.lua tutorial-inject.lua tutorial-query-time.lua tutorial-states.lua
# lua腳本放到/usr/local/share下,以備他用
# mv share/mysql-proxy /usr/local/share/
# 刪除符號連接等垃圾代碼
# strip /usr/local/sbin/mysql-proxy
proxy MMM集成
連接接管
Proxy 192.168.1.5
4040
讀操作
Db1 192.168.1.7:3306
Db2 192.168.1.8:3306
寫操作
Db1/db2 192.168.1.9
默認db1先用,db1當機,db2接管
mysql-proxy --proxy-read-only-backend-addresses=192.168.1.7:3306 --proxy-read-only-backend-addresses=192.168.1.8:3306 --proxy-backend-addresses=192.168.1.9:3306  --proxy-lua-script=/usr/local/share/mysql-proxy/rw-splitting.lua &
現在解釋一下:
--proxy-backend-addresses=192.168.1.9:3306  指定mysql寫主機的端口
--proxy-read-only-backend-addresses=192.168.1.7:3306  指定只讀的mysql主機端口
--proxy-read-only-backend-addresses=192.168.1.8:3306  指定另一個只讀的mysql主機端口
--proxy-lua-script=/usr/local/share/mysql-proxy/rw-splitting.lua  指定lua腳本,在這里,使用的是rw-splitting腳本,用于讀寫分離
完整的參數可以運行以下命令查看:
mysql-proxy --help-all
運行以下命令啟動/停止/重啟mysql proxy
# /etc/init.d/mysql-proxy start
# /etc/init.d/mysql-proxy stop
# /etc/init.d/mysql-proxy restart
Ps -ef | grep mysql-proxy
七、測試結果
web server apache 中部署的網站,數據庫連接地址改為----proxyip端口為4040
1 、往數據庫db1里寫入數據,查看2個數據庫同步情況
2 、使用mon服務器mmm_control show 查看狀態
簡單的測試可以連接proxy 4040 查看讀寫情況
方法我就不再詳細寫了。
編譯過程有可能會遇到一些錯誤。下面是錯誤的總結:
1 )如在make 階段出錯
   (1) 類、、、、make: *** [dbdimp.o] 錯誤 1
多半是庫文件的問題,(--cflags=-I/usr/local/mysql/include/mysq 細查,少個“y"
    2)類 LD_RUN_PATH="/usr/lib/mysql:/lib:/usr/lib" gcc
    -o blib/arch/auto/DBD/mysql/mysql.so  -shared
    -L/usr/local/lib dbdimp.o mysql.o -L/usr/lib/mysql
    -lmysqlclient -lm -L/usr/lib/gcc-lib/i386-redhat-linux/2.96
    -lgcc -lz
  /usr/bin/ld: cannot find -lz
  collect2: ld returned 1 exit status
  make: *** [blib/arch/auto/DBD/mysql/mysql.so] Error 1
   與壓縮包有關。可用 ldconfig -p | grep libz
                     ldconfig -p | grep libgz
    查找,如有并指定路徑!否則安裝 libz-develibgz-develzlib-devel    gzlib-devel
2) make test 階段出錯:
  (1) : install_driver(mysql) failed: Can't load
  '/usr/lib/perl5/site_perl/i586-linux/auto/DBD/mysql/mysql.so'
  for module DBD::mysql: File not found at
  /usr/lib/perl5/i586-linux/5.00404/DynaLoader.pm line 166
    /usr/lib/mysql/libmysqlclient.a有關 (cp libmysqlclient.a /us/lib)
  (2) 類: t/00base............install_driver(mysql) failed: Can't load
  '../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql:
  ../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol: _umoddi3
  at /usr/local/perl-5.005/lib/5.005/i586-linux-thread/DynaLoader.pm
  line 168.
   libgcc.a 有關 (cp /usr/lib/gcc/i386-redhat-linux/4.1.1/libgcc.a /usr/local/lib/
  (3)  類:Can't load  libmysqlclient.so.15 、、、、
      cp libmysqlclient.so.15 /us/lib)
----------------------------------------
$perl Makefile.PL  --libs="-L/usr/local/mysql/lib/mysql -lmysqlclient -L/usr/lib -lz " --cflags=-I/usr/local/mysql/include/mysql  --mysql_config=/usr/local/mysql/bin/mysql_config  --testhost=127.0.0.1--testsocket=/usr/local/mysql/tmp/mysql.sock --testdb=test --testuser=abc --testpassword=abc
------------------
$
; make; make test ;sudo  make install;

地址:http://liuyu.blog.51cto.com/183345/98867
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!