一、NDB Cluster (分佈式存儲引擎)存儲引擎簡單簡介
NDB 存儲引擎也叫NDB Cluster 存儲引擎,主要用於MySQL Cluster 分佈式集羣環境,
Cluster 是MySQL 從5.0 版本纔開始提供的新功能。這部分我們可能並不僅僅只是介紹NDB
存儲引擎,因爲離開了MySQL CLuster 整個環境,NDB 存儲引擎也將失去太多意義。所以
接下來會和MySQL Cluster的搭建一塊介紹。
Mysql Cluster 是一種技術,其主要功能是在無共享的相關係統中部署內存中數據庫的Cluster,其主要是通過NDB Cluster(簡稱NDB)存儲引擎來實現的。
在通過無共享體系結構,系統能夠使用廉價的硬件,而且對軟硬件無特殊要求。
一般來說,一個Mysql Cluster 的環境結構主要如下:
主要由以下三部分組成:
1). 負責管理各個節點的Manage 節點主機:
管理節點負責整個Cluster 集羣中各個節點的管理工作,包括集羣的配置,啓動關閉
各節點,以及實施數據的備份恢復等。管理節點會獲取整個Cluster 環境中各節點的狀態和
錯誤信息,並且將各Cluster 集羣中各個節點的信息反饋給整個集羣中其他的所有節點。由
於管理節點上保存在整個Cluster 環境的配置,同時擔任了集羣中各節點的基本溝通工作,
所以他必須是最先被啓動的節點。
2). SQL 層的SQL 服務器節點(後面簡稱爲SQL 節點),也就是我們常說的Mysql Server:
主要負責實現一個數據庫在存儲層之上的所有事情,比如連接管理,query 優化和響
應,cache 管理等等,只有存儲層的工作交給了NDB 數據節點去處理了。也就是說,在純粹
的Mysql Cluster 環境中的SQL 節點,可以被認爲是一個不需要提供任何存儲引擎的Mysql
服務器,因爲他的存儲引擎有Cluster 環境中的NDB 節點來擔任。所以,SQL 層各Mysql 服
務器的啓動與普通的Mysql 啓動有一定的區別,必須要添加ndbcluster 項,可以添加在
my.cnf 配置文件中,也可以通過啓動命令行來指定。
3). Storage 層的NDB 數據節點,也就是上面說的NDB Cluster:
NDB 是一個內存式存儲引擎也就是說,他會將所有的數據和索引數據都load 到內存中,
但也會將數據持久化到存儲設備上。不過,最新版本,已經支持用戶自己選擇數據可以不全
部Load 到內存中了,這對於有些數據量太大或者基於成本考慮而沒有足夠內存空間來存放
所有數據的用戶來說的確是一個大好消息。
NDB 節點主要是實現底層數據存儲的功能,保存Cluster 的數據。每一個NDB 節點保存
完整數據的一部分(或者一份完整的數據,視節點數目和配置而定),在MySQL CLuster 裏
面叫做一個fragment。而每一個fragment,正常情況來講都會在其他的主機上面有一份(或
者多分)完全相同的鏡像存在。這些都是通過配置來完成的,所以只要配置得當,Mysql
Cluster 在存儲層不會出現單點的問題。
一般來說,NDB 節點被組織成一個一個的NDB Group,一個NDB Group 實際上就是一組存有完全相同的物理數據的NDB 節點羣。
上面提到了NDB 各個節點對數據的組織,可能每個節點都存有全部的數據也可能只保存
一部分數據,主要是受節點數目和參數來控制的。首先在Mysql Cluster 主配置文件(在管
理節點上面,一般爲config.ini)中,有一個非常重要的參數叫NoOfReplicas,這個參數
指定了每一份數據被冗餘存儲在不同節點上面的份數,該參數一般至少應該被設置成2,也
只需要設置成2 就可以了。因爲正常來說,兩個互爲冗餘的節點同時出現故障的概率還是非
常小的,當然如果機器和內存足夠多的話,也可以繼續增大。一個節點上面是保存所有的數
據還是一部分數據,還受到存儲節點數目的限制。NDB 存儲引擎首先保證NoOfReplicas 參
數配置的要求對數據冗餘,來使用存儲節點,然後再根據節點數目將數據分段來繼續使用多
餘的NDB 節點,分段的數目爲節點總數除以NoOfReplicas 所得。
二、MySQL Cluster集羣架構的實現
管理節點上:
rpm -ivh MySQL-Cluster-gpl-management-7.1.18-1.el6.x86_64.rpm
rpm -ivh MySQL-Cluster-gpl-tools-7.1.18-1.el6.x86_64.rpm
mkdir /usr/mysql-cluster
vi /usr/mysql-cluster/config.ini [ndbd default] noofreplicas=1 //運行NDB存儲引擎 datamemory=30M indexmemory=10M [ndb_mgmd] nodeid=1 hostname=192.168.1.21 //管理節點ip datadir=/usr/mysql-cluster [ndbd] nodeid=2 hostname=192.168.1.22 //存儲節點ip datadir=/usr/mysql-cluster [mysqld] //客戶端 nodeid=3 hostname=192.168.1.23
ndb_mgmd -f /usr/mysql-cluster/config.ini --initial //指定配置文件,初始化
ndb_mgm //就可以查看各個節點的信息了
存儲節點上:
rpm -ivh MySQL-Cluster-gpl-storage-7.1.18-1.el6.x86_64.rpm
vi /etc/my.cnf [mysqld] ndbcluster //運行ndb集羣引擎 ndb-connectstring=192.168.1.21 //指定管理節點 [mysql_cluster] ndb-connectstring=192.168.1.21
ndbd --initial //初始化後,在manager節點上ndb_mgm查看存儲節點已經連接上了
SQL節點 上:
MySQL-Cluster-gpl-client-7.1.18-1.el6.x86_64.rpm
MySQL-Cluster-gpl-server-7.1.18-1.el6.x86_64.rpm
SQL節點上若安裝了mysql、mysql-server、mysql-libs,需要將其卸載才能安裝MySQL-Cluster,否則會報錯
error: Failed dependencies:
mysql conflicts with MySQL-Cluster-gpl-server-7.1.18-1.el6.x86_64
mysql-server conflicts with MySQL-Cluster-gpl-server-7.1.18-1.el6.x86_64
rpm -e mysql-libs --nodeps //強制卸載
rpm -ivh MySQL-Cluster-gpl-*
vi /etc/my.cnf [mysqld] .... ndbcluster (以下數據添加在[mysqld]區域的最下方) ndb-connectstring=192.168.1.21 [mysql_cluster] ndb-connectstring=192.168.1.21
/etc/init.d/mysql start //啓動mysql,然後在管理節點上ndb_mgm查看
sql節點上如初始化時會在目錄 /var/lib/mysql/mysql 中生成數據庫的好多文件,如啓動時初始化失敗,可以手動執行命令 mysql_install_db --user=mysql 生成。
--------------------
添加新的存儲節點和sql節點:
添加新的存儲節點和sql節點前,必須先將已有的管理節點、存儲節點、sql節點關閉
在管理節點上執行ndb_mgm -e shutdown只能關閉存儲節點和管理節點自己的服務,sql節點仍需手工stop,之後再添加。
先在管理節點的配置文件中加入要添加的節點:
vi /usr/mysql-cluster/config.ini [ndbd default] noofreplicas=2 //定義兩個節點爲一個節點組, datamemory=30M indexmemory=10M [ndb_mgmd] nodeid=1 hostname=192.168.1.21 datadir=/usr/mysql-cluster [ndbd] nodeid=2 hostname=192.168.1.22 datadir=/usr/mysql-cluster [ndbd] //加入的存儲節點 nodeid=4 hostname=192.168.1.10 datadir=/usr/mysql-cluster [mysqld] nodeid=3 hostname=192.168.1.23 [mysqld] //加入的sql節點 nodeid=5 hostname=192.168.1.24 [mysqld] //加個空閒連接,數據恢復要用到,需要時再加也可以
然後再配置新加的節點(和原來的配置一致)
ndb_mgmd -f /usr/mysql-cluster/config.ini --initial //重新初始化管理端
ndbd --initial //啓動各個數據節點
/etc/init.d/mysql start //啓動SQL節點
在管理節點上ndb_mgm show,就可以看見各個節點已經正常工作
# ndb_mgm -- NDB Cluster -- Management Client -- ndb_mgm> show Connected to Management Server at: localhost:1186 Cluster Configuration --------------------- [ndbd(NDB)] 2 node(s) id=2 @192.168.1.22 (mysql-5.1.56 ndb-7.1.18, Nodegroup: 0, Master) id=4 @192.168.1.10 (mysql-5.1.56 ndb-7.1.18, Nodegroup: 0) [ndb_mgmd(MGM)] 1 node(s) id=1 @192.168.1.21 (mysql-5.1.56 ndb-7.1.18) [mysqld(API)] 2 node(s) id=3 @192.168.1.23 (mysql-5.1.56 ndb-7.1.18) id=5 @192.168.1.24 (mysql-5.1.56 ndb-7.1.18)
從以上信息顯示,節點2和4作爲一個數據組,兩個節點的數據是一樣的,互爲冗餘;兩個sql節點存儲的表結構也互爲冗餘。
--------------
建立集羣數據
在任一sql節點插入數據,都可以在另一節點看到,
mysql> create database ty; mysql> create table tjf( -> name varchar(20) not null, -> age int(8), -> sex varchar(8) not null -> )engine ndbcluster; //指定MySQL爲該表使用NDB存儲引擎,數據存儲於各數據節點,不然mysql使用 //默認的MyISAM存儲引擎,所有數據將會存儲於本機,和單機一樣 Query OK, 0 rows affected (0.81 sec)
//導入數據 mysql> insert into tjf values('tjf',21,'f'); mysql> insert into tjf values('ty',22,'m'); mysql> insert into tjf values('jn',20,'f'); mysql> insert into tjf values('fx',21,'f'); mysql> insert into tjf values('cs',22,'m');
在另一節點查看錶,已經同步過來
mysql> select * from tjf; +------+------+-----+ | name | age | sex | +------+------+-----+ | jn | 20 | f | | cs | 22 | m | | ty | 22 | m | | tjf | 21 | f | | fx | 21 | f | +------+------+-----+ 5 rows in set (0.01 sec)
MySQL Cluster備份恢復
在管理節點上執行備份數據命令,數據將分別備份到各個存儲節點上,恢復時需要在各個存儲節點上都執行恢復命令;
ndb_mgm> start backup Waiting for completed, this may take several minutes Node 2: Backup 1 started from node 1 Node 2: Backup 1 started from node 1 completed StartGCP: 1443 StopGCP: 1446 #Records: 2062 #LogRecords: 0 Data: 51136 bytes Log: 0 bytes
在數據節點/usr/mysql-cluster/BACKUP目錄中就可以看到備份的數據;
當在sql節點上刪除數據,就可以利用此備份恢復(只能恢復數據,如將表或庫直接刪掉了,需要手動加上,纔可以恢復);
恢復數據需要命令 ndb_restore (由包MySQL-Cluster-gpl-tools-7.1.18-1.el6.x86_64.rpm提供),若存儲節點上沒有此命令,可以將其直接由管理節點上覆制過去,也可以安裝tools包。
注意:恢復數據時,管理節點上一定要有空閒連接,否則無法恢復。
由於數據備份在兩個數據節點,因此在各個數據節點都得執行恢復操作
在數據節點2恢復:
[root@node1 ~]# ls /usr/mysql-cluster/BACKUP/BACKUP-1/ BACKUP-1-0.2.Data BACKUP-1.2.ctl BACKUP-1.2.log [root@node1 ~]# ndb_restore -n 2 -b 1 -r /usr/mysql-cluster/BACKUP/BACKUP-1/ Nodeid = 2 Backup Id = 1 backup path = /usr/mysql-cluster/BACKUP/BACKUP-1/ Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1.2.ctl' File size 9408 bytes Backup version in files: ndb-6.3.11 ndb version: mysql-5.1.56 ndb-7.1.18 Stop GCP of Backup: 1445 Connected to ndb!! Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1-0.2.Data' File size 26388 bytes _____________________________________________________ Processing data in table: ty/def/tjf(7) fragment 0 _____________________________________________________ Processing data in table: sys/def/NDB$EVENTS_0(3) fragment 0 _____________________________________________________ Processing data in table: mysql/def/ndb_apply_status(6) fragment 0 _____________________________________________________ Processing data in table: mysql/def/NDB$BLOB_4_3(5) fragment 0 _____________________________________________________ Processing data in table: sys/def/SYSTAB_0(2) fragment 0 _____________________________________________________ Processing data in table: mysql/def/ndb_schema(4) fragment 0 Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1.2.log' File size 52 bytes Restored 3 tuples and 0 log entries NDBT_ProgramExit: 0 - OK
SQL節點上查看恢復情況,數據恢復了一部分
mysql> select * from tjf; +------+------+-----+ | name | age | sex | +------+------+-----+ | jn | 20 | f | | cs | 22 | m | | ty | 22 | m | +------+------+-----+ 3 rows in set (0.01 sec)
在數據節點4恢復:
[root@rhcs1 ~]# ls /usr/mysql-cluster/BACKUP/BACKUP-1/ BACKUP-1-0.4.Data BACKUP-1.4.ctl BACKUP-1.4.log [root@rhcs1 ~]# ndb_restore -n 4 -b 1 -r /usr/mysql-cluster/BACKUP/BACKUP-1/ Nodeid = 4 Backup Id = 1 backup path = /usr/mysql-cluster/BACKUP/BACKUP-1/ Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1.4.ctl' File size 9408 bytes Backup version in files: ndb-6.3.11 ndb version: mysql-5.1.56 ndb-7.1.18 Stop GCP of Backup: 1445 Connected to ndb!! Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1-0.4.Data' File size 25180 bytes _____________________________________________________ Processing data in table: ty/def/tjf(7) fragment 1 _____________________________________________________ Processing data in table: sys/def/NDB$EVENTS_0(3) fragment 1 _____________________________________________________ Processing data in table: mysql/def/ndb_apply_status(6) fragment 1 _____________________________________________________ Processing data in table: mysql/def/NDB$BLOB_4_3(5) fragment 1 _____________________________________________________ Processing data in table: sys/def/SYSTAB_0(2) fragment 1 _____________________________________________________ Processing data in table: mysql/def/ndb_schema(4) fragment 1 Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1.4.log' File size 52 bytes Restored 2 tuples and 0 log entries NDBT_ProgramExit: 0 - OK
再次在SQL節點查看數據,已經恢復成功
mysql> select * from tjf; +------+------+-----+ | name | age | sex | +------+------+-----+ | jn | 20 | f | | cs | 22 | m | | ty | 22 | m | | tjf | 21 | f | | fx | 21 | f | +------+------+-----+ 5 rows in set (0.00 sec)
-n指節點id -b指備份id -r指備份目錄