MYSQL CLUSTER方案介紹

                                 本文的大致框架來自羅志威、黃川的報告, 在它的基礎上進行簡化和修改一些bug並且添加了主從複製的章節,最後做出該文件

MySQL Cluster 是MySQL適合於分散式計算環境的高實用、高冗餘版本。它採用了NDB Cluster 儲存引擎,允許在1個 Cluster 中執行多個MySQL伺服器。現在mysql cluster 被獨立出來, 作為一個專門的產品進行運營, mysql-server-5.6+ 就不在存在對mysql cluster的支援,需要獨立下載cluster包進行安裝.

推薦在Linux下完成安裝, 如果一定要在Windows上的話, 則需要考慮使用解壓版本的進行安裝, 且路徑中不能帶有空格字元.

測試環境資訊

伺服器資訊

項 值

作業系統

Ubuntu 14.04 32位

Mysql Cluster 版本

mysql-cluster-gpl-7.3.5-debian6.0-i686

記憶體

2G

CPU

2.20雙核

網路環境

100M區域網

部署

1個數據節點,1 SQL節點,1管理節點

管理節點資訊

機器IP

資料節點編號

192.168.1.37

1

機器IP

資料節點編號

192.168.1.37

2

資料節點資訊

SQL節點資訊

機器IP

資料節點編號

192.168.1.37

3

機器安裝環境

機器IP

使用者名稱、密碼

安裝路徑

路徑說明

192.168.1.37

root/root

/root/mysql/mysqlc

mysql cluster 目錄

/root/mysql/data/mysqld_data

sql節點資料路徑

/root/mysql/data/ndb_data

資料節點資料路徑

/root/mysqldata/mgmd_data

管理節點資料

/root/mysql/conf

配置檔案路徑

節點說明

SQL節點:

這是用來訪問簇資料的節點。對於MySQL簇,客戶端節點是使用NDB簇儲存引擎的傳統MySQL伺服器。典型情況下,SQL節點是使用命令mysqld –-ndbcluster啟動的,或將ndbcluster新增到my.cnf後使用mysqld啟動。簇中所有的表結構都儲存在mysql節點中,為了保證每個資料節點中資料分佈均勻,在進行資料插入的時候sql節點採用了表分片的策略將資料均勻分配到不同的資料節點上。

資料節點:

這類節點用於儲存簇的資料。資料節點的數目與副本的數目相關,是片段的倍數。例如,對於兩個副本,每個副本有兩個片段,那麼就有1個數據節點(在測試環境中就採用了兩個副本兩個片段的策略,故有1個數據節點,(ndb_mgmd 配置檔案中NoOfReplicas屬性配置)此時管理節點會將資料節點進行分組, 資料節點是用命令ndbd啟動的。

各個資料節點中都用兩個檢查點:本地檢查點、全域性檢查點。本地檢查點的目的是為了將記憶體中的資料和磁碟上的資料進行同步。全域性檢查點是在各節點中進行通訊,以保證事物的一致性。

管理節點:

管理節點是管理資料節點和sql節點的工具,在系統正常執行期間停止管理節點對整個系統的執行不會有任何影響。在管理節點提供了資料節點和sql節點的全域性配置資訊,包括資料、索引所佔用記憶體大小、資料存放的目錄資訊、各個節點ip資訊等。通過管理節點可以啟動和停止節點、啟動和停止訊息跟蹤(僅對除錯版本)、顯示節點版本和狀態、啟動和停止備份等的命令。

安裝配置說明

軟體下載說明:

1、 軟體下載地址:http://www.mysql.com/downloads/cluster/

2、 安裝版本:mysql-cluster-gpl-7.3.5-debian6.0-i686

安裝步驟說明:

一、 管理節點安裝

1、 登陸系統建立目錄結構

mkdir –p /root/mysql/data/mgmd_data

mkdir /root/mysql/data/ndb_data

mkdir /root/mysql/data/mysqld_data

mkdir /root/mysql/conf

mkdir /root/mysql/mysqlc

2、 安裝mysqlc

dpkg –i mysql-cluster-gpl-7.3.5-debian6.0-i686

mv /opt/mysql/server-5.6/* /root/mysql/mysqlc

3、 設定環境變數

在.bashrc檔案的PATH後面加入如下資訊/root/mysql/mysqlc/bin

vim ~/.bashrc

加入後,檔案如下所示

加入後執行如下命令使配置生效:

. ~/.bashrc

4、 在/root/mysql/conf目錄下建立mgmd.conf檔案,然後在檔案中配置各節點資訊,如下所示:

[ndbd default]

NoOfReplicas=1 #設定冗餘的分數(一個sql節點對應幾個data節點)

DataMemory=100M #指定存放資料的記憶體段大小

IndexMemory=50M#制定索引的記憶體段大小

LockPagesInMainMemory=1 #將程序鎖定在記憶體中

TimeBetweenLocalCheckpoints=20#本地檢查點時間間隔。

TimeBetweenGlobalCheckpoints=1000#全域性檢查點時間間隔。

TimeBetweenEpochs=100#複製同步的間隔時間

TimeBetweenWatchdogCheckInitial=60000

MaxNoOfTables=1024 #該引數為作為整體的簇設定了最大表物件數目

MaxNoOfOrderedIndexes=2048 #設定雜湊索引在系統中同一時間被使用總數

MaxNoOfUniqueHashIndexes=512 #設定最大的唯一索引的總數

MaxNoOfAttributes=20480 #定義了可在簇中定義的屬性數目

MaxNoOfTriggers=10240#設定簇中觸發程式物件的最大數目

DiskCheckpointSpeedInRestart=100M #重啟的時候本地檢查點期間傳送到磁的速度

NoOfFragmentLogFiles=16 #該引數用於設定節點的REDO日誌檔案的個數

RedoBuffer=65M #設定redo日誌快取

MaxNoOfConcurrentOperations=500000 #設定事務中同時更新的最大記錄數

MaxNoOfExecutionThreads=8#執行緒的數量

BatchSizePerLocalScan=512 #該引數用於計算鎖定記錄的數目

SharedGlobalMemory=20M #這個引數設定用於日誌緩衝、磁碟操作和表空間...

DiskPageBufferMemory=80M #設定硬碟上的快取頁的空間總量的大小

#[tcp default]

#portnumber=2202#通訊埠(現在無效)

[ndb_mgmd]

hostname=192.168.1.39#管理節點IP

datadir=/root/mysql/data/mgmd_data#管理節點資料目錄

Nodeid=1#管理節點編號

[ndbd]

hostname=192.168.1.39#資料節點IP

datadir=/root/mysql/data/ndb_data#資料節點資料目錄

NodeId=2#資料節點編號

[mysqld]

hostname=192.168.1.39#sql節點IP

NodeId=3#sql節點編號

5、 管理節點啟動命令

第一次啟動:

ndb_mgmd -f /root/mysql/conf/mgmd.conf --configdir=/root/mysql/conf/ --initial

非第一次啟動:

ndb_mgmd -f /root/mysql/conf/mgmd.conf --configdir=/root/mysql/conf/

注意: 路徑不能使用相對地址, 需要使用絕對地址.

啟動後可以輸入ndb_mgm命令進入管理控制檯,然後輸入show命令檢視節點狀態,如下圖所示:

二、 資料節點安裝

1、 管理節點啟動命令

第一次啟動命令:

ndbd -c 192.168.1.39:1186 --initial

非第一次啟動命令:

ndbd -c 192.168.1.39:1186

注意:如果在啟動的時候加入initial引數,那麼會將用於備份和還原的日誌資訊都會清空,也就是說會將資料庫中的資料刪除掉。在啟動的時候一定要注意。

三、 SQL節點安裝

1、 在/root/mysql/conf目錄下建立mysqld.conf檔案,然後在檔案中配置各節點資訊,如下所示:

[mysqld]

ndbcluster

ndb-wait-setup=1 #等待data節點建立資料表時間限制

datadir=/root/mysql/data/mysqld_data

basedir=/root/mysql/mysqlc

socket=/tmp/mysql.sock #Windows註釋掉

skip-name-resolve #跳過域名解析

port=3306

#ndb-connectstring=192.168.1.39

[mysql_cluster]

ndb-connectstring=192.168.1.39 #指向管理節點

2、 第一次安裝sql節點後要執行如下指令碼,該指令碼只執行一次。

cd  /root/mysql/mysqlc

./scripts/mysql_install_db --no-defaults --datadir=/root/mysql/data/mysqld_data/ --basedir=.

3、 sql節點啟動命令

mysqld --defaults-file=/root/mysql/conf/mysqld.conf --user=root

4、 許可權配置

本地許可權配置:

mysqladmin  –uroot   –proot

非本機訪問許可權配置:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;

FLUSH PRIVILEGES;

關閉mysql cluster

資料節點 和 管理節點通過進入 ndb_mgm , 輸入shutdown 來關閉

sql節點通過 mysqladmin -uroot -p shutdown 來關閉

方案測試

一、 測試工具

壓力測試工具使用的是mysql自帶的mysqlslap壓力測試工具。

mysqlslap:

mysql自帶的一個壓力測試工具,自5.1.4版本之後的MySQL client 包含了此工具,下載mysql client rpm包安裝後可直接使用。在 使用mysqlslap的時候,可以指定sql語句或者是包含sql語句的檔案,如果是檔案,那麼檔案中的每一行至少有一個語句(不能一個sql語句分成 兩行或多行),因為預設的分隔符(delimiter)是換行符,當然,你也可以手動重置新的分隔符。另外,你也不能在檔案中添加註 釋,mysqlslap不支援。

Mysqlslap引數說明:

--concurrency代表併發數量,多個可以用逗號隔開,當然你也可以用自己的分隔符隔 開,這個時候要用到--delimiter開關。

--engines代表要測試的引擎,可以有多個,用分隔符隔開。

--iterations代表要執行這些測試多少次。

--auto-generate-sql 代表用系統自己生成的SQL指令碼來測試。

--auto-generate-sql-load-type 代表要測試的是讀還是寫還是兩者混合的

--number-of-queries 代表總共要執行多少次查詢。每個客戶執行的查詢數量可以 用查詢總數/併發數來計算。比如倒數第二個結果2=200/100。

--debug-info 代表要額外輸出CPU以及記憶體的相關資訊。

--number-int-cols 代表示例表中的INTEGER型別的屬性有幾個。

--number-char-cols 意思同上。

--create-schema 代表自己定義的模式(在MySQL中也就是庫)。

--query 代表自己的SQL指令碼。

--only-print 如果只想列印看看SQL語句是什麼,可以用這個選項。

-h sql節點ip

-u 使用者

-p(小寫) 密碼

-P(大寫) 埠

二、 壓力測試建表及儲存過程

1. 建庫、建表指令碼:

CREATE DATABASE cluster1;

USE cluster1;

CREATE TABLE ndbtest (

id int(11) NOT NULL AUTO_INCREMENT,

regtime DATETIME DEFAULT NULL,

name VARCHAR(200) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=ndb AUTO_INCREMENT=1000001 DEFAULT CHARSET=latin1 PACK_KEYS=0;

2. 儲存過程指令碼

DELIMITER $$

DROP PROCEDURE IF EXISTS `p_test_t1_disk` $$

CREATE PROCEDURE `p_test_t1_disk`()

BEGIN

declare i int default 0;

test: loop

 insert into cluster1.ndbtest(regtime,name) values(sysdate(),md5(rand()));

 set i=i+1;

 if i>=10000 then

   leave test;

 end if;

end loop;

END $$

DELIMITER ;

3. 工具執行命令

mysqlslap -uroot -proot --concurrency=1 --iterations=1 --query='call cluster1.p_test_t1_disk;' --number-of-queries=1 -h 192.168.1.37 --create-schema=cluster1

MYSQL REPLICATION方案介紹

Mysql Replication(MySQL主從複製)是MySQL資料庫使用率非常高的一種技術,它使用某個資料庫伺服器為 主,然後在其他資料庫伺服器上進行復制,後面複製的資料庫也稱從資料庫。MySQL支援單向、非同步複製,複製過程中一個伺服器充當主伺服器,而一個或多個 其它伺服器充當從伺服器。

在設定鏈式複製伺服器時,從伺服器本身也可以充當主伺服器,如:a->b->c,b對於a來說是從伺服器,但是它又 是c的主伺服器。
Mysql Replication(MySQL主從複製)主要用於:

1.使用一個從伺服器執行備份,而不會干擾主伺服器。在備份過程中主伺服器可以繼續處理更新;

2.解決資料庫讀需求很高(讀寫分離), 通常使用amoeba或者mysqlproxy作為中間代理層.

Mysql Replication(MySQL主從複製)的原理:

Mysql的複製(replication)是一個非同步的複製,從一個Mysql instace(稱之為Master)複製到另一個Mysql instance(稱之Slave)。實現整個複製操作主要由三個程序完成的,其中兩個程序在Slave(Sql程序和IO程序),另外一個程序在 Master(IO程序)上。

要實施複製,首先必須開啟Master端的binary log(bin-log)功能,否則無法實現。因為整個複製過程實際上就是Slave從Master端獲取該日誌然後再在自己身上完全順序的執行日誌中所記錄的各種操作。
複製的基本過程如下:
1)、

Slave上面的IO程序連線上Master,並請求從指定日誌檔案的指定位置(或者從最開始的日誌)之後的日誌內容;
2)、

Master接收到來自Slave的IO程序的請求後,通過負責複製的IO程序根據請求資訊讀取制定日誌指定位置之後的日誌資訊,返回給Slave 的IO程序。返回資訊中除了日誌所包含的資訊之外,還包括本次返回的資訊已經到Master端的bin-log檔案的名稱以及bin-log的位置;
3)、

Slave的IO程序接收到資訊後,將接收到的日誌內容依次新增到Slave端的relay-log檔案的最末端,並將讀取到的Master端的 bin-log的檔名和位置記錄到master-info檔案中,以便在下一次讀取的時候能夠清楚的高速Master“我需要從某個bin-log的哪個位置開始往後的日誌內容,請發給我”;
4)、

Slave的Sql程序檢測到relay-log中新增加了內容後,會馬上解析relay-log的內容成為在Master端真實執行時候的那些可執行的內容,並在自身執行。

如果要實現Slave和Master為同一個mysqld, 需要新增log-slave-updates = 1

引數到my.cnf-à[mysqld]

伺服器結構:

A、B、C三臺伺服器; 其中A為新聞資料來源,A為B的Master,B為A的Slave,同時也是C的Master;

B伺服器從A複製部分資料,C備份A的所有資料;

注意:

如果資料庫在做主從的時候已經有資料了, 則需要進行鎖表操作.

mysql> flush tables with read lock;

記住資料導完後要解鎖:

mysql> unloclk tables;

Master A的配置

sudo vi /etc/mysql/my.cnf

刪除以下引數前的註釋並修改

server-id       = 1 //分配server-id

log-bin         = master-bin //預設mysql-bin,可以不修改

log-bin-index   = master-bin.index  //非必須

bind-adress     = 0.0.0.0 //預設127.0.0.1 不修改可能導致無法訪問

修改系統防火牆使B伺服器可以訪問3306埠,(詳查ufw命令)

重啟mysql:

sudo /init.d/mysql restart

通過語句:

GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO user@'ip B' IDENTIFIED BY 'password';

給B伺服器建立一個可以連線到A的帳號

進入mysql,通過:

show master status;

檢視A的狀態,記錄下file的位置和postion的引數

Slave B的配置

sudo vi /etc/mysql/my.cnf

server-id       = 2

log-bin         = slave-bin

bind-address    = 0.0.0.0

relay-log-index =  slave-relay-bin.index //非必須

relay-log       = slave-relay-bin   //非必須

新增引數:

log-slave-updates = 1

//通常情況,從伺服器從主伺服器接收到的更新不記入它的二進位制日誌。

//該選項告訴從伺服器將其SQL執行緒執行的更新記入到從伺服器自己的二進位制日誌。

replicate_wild_do_table = copy_db.copy_table //表示需要複製的庫中的表,可以善用%

replicate_wild_ignore_table = ignore_db.ignore_table //不復制的表

至於為什麼不使用replicate_do_db和replicate_ignore_db引數,

是為了方式跨庫更新時出錯,如果能確保不會跨庫更新可考慮

重啟mysql,進入本機mysql

執行以下語句:

CHANGE MASTER TO MASTER_HOST='server A ip',

MASTER_PORT=3306,

MASTER_USER='user',

MASTER_PASSWORD='password',

MASTER_LOG_FILE='mysql-bin.000001',

MASTER_LOG_POS=0;

//MASTER_LOG_FILE和MASTER_LOG_POS對應A中的file位置和postion引數,表示開始複製的bin檔案和位置

start slave;    //啟動Slave

show slave status;  //檢視Slave_IO_State引數,如果是Waiting for master to send event,則正常

//正常狀態下Slave_IO_Running與Slave_SQL_Running均為yes

//如不能正常連結,根據Slave_IO_State,Slave_IO_Running,Slave_SQL_Running,Last_IO_Error

//等引數查詢失敗原因

通過:

show master status;

命令記錄file位置和postion引數;

給C伺服器分配一個帳號用於同步;

方法參照A,防火牆設定參照A;

Slave C的配置

sudo vi /etc/mysql/my.cnf

server-id  = 3

relay-log-index =  slave-relay-bin.index //非必須

relay-log       = slave-relay-bin   //非必須

通過CHANGE MASTER TO語句來修改master的引數,參照B的配置;

通過

show slave status;

檢查C的狀態,參照B

讀寫分離配置:

推薦使用amoeba, amoeba 相比較mysqlproxy, 優點在於中文文件齊全(國人編寫),穩定性高,免除了mysqlproxy的lua配置的複雜性.

Amoeba讀寫分離:

http://docs.hexnova.com/amoeba/rw-splitting.html

高可用性

可以製作兩個master,它們兩個為雙熱備主機,然後通過keepalive整合master 變為一個VIP, 最後 amoeba和slave都是通過這個VIP 來進行操作,amoeba把insert等操作傳送到這個VIP, slave通過VIP獲得具體的bin日誌,然後進行更新

Keepalive在使用的時候,通常只有一臺master會進行工作,另外一臺進行主從複製,當query傳送到VIP的時候,就會進入工作的master執行。當工作master宕機後,keepaliave會自動切換VIP指向空閒master進行工作, 這樣子就實現了高可用性。

所以在雙擊熱備的環境中 ,總共會佔用3+個IP地址。

負載均衡

負載均衡在IP層上,通常使用LVS軟體,在HTTP層面上可以使用Nginx,lighttpd,apache web server 等軟體。

現在為了實現MySql的master的負載均衡,可以使用LVS, 在IP層面上進行負載均衡,

也可以使用MySql-Cluster(NDB)產品, 它已經實現了高可用性以及負載均衡.

高可用性和負載均衡都可以直接通過NDB來實現,上面提及的是一般方法