1 海量數據的存儲問題 如今隨著互聯網的發展,數據的量級也是撐指數的增長,從GB到TB到PB。對數據的各種操作也是愈加的困難,傳統的關係性資料庫已經無法滿足快速查詢與插入數據的需求。這個時候NoSQL的出現暫時解決了這一危機。它通過降低數據的安全性,減少對事務的支持,減少對複雜查詢的支持,來獲取性能 ...
1 海量數據的存儲問題
如今隨著互聯網的發展,數據的量級也是撐指數的增長,從GB到TB到PB。對數據的各種操作也是愈加的困難,傳統的關係性資料庫已經無法滿足快速查詢與插入數據的需求。這個時候NoSQL的出現暫時解決了這一危機。它通過降低數據的安全性,減少對事務的支持,減少對複雜查詢的支持,來獲取性能上的提升。
但是,在有些場合NoSQL一些折衷是無法滿足使用場景的,就比如有些使用場景是絕對要有事務與安全指標的。這個時候NoSQL肯定是無法滿足的,所以還是需要使用關係性資料庫。如果使用關係型資料庫解決海量存儲的問題呢?此時就需要做資料庫集群,為了提高查詢性能將一個資料庫的數據分散到不同的資料庫中存儲。
1.1 什麼是資料庫分片
簡單來說,就是指通過某種特定的條件,將我們存放在同一個資料庫中的數據分散存放到多個資料庫(主機)上面,以達到分散單台設備負載的效果。
數據的切分(Sharding)根據其切分規則的類型,可以分為兩種切分模式。
(1)一種是按照不同的表(或者Schema)來切分到不同的資料庫(主機)之上,這種切可以稱之為數據的垂直(縱向)切分
(2)另外一種則是根據表中的數據的邏輯關係,將同一個表中的數據按照某種條件拆分到多台資料庫(主機)上面,這種切分稱之為數據的水平(橫向)切分。
1.2 如何實現資料庫分片
當資料庫分片後,數據由一個資料庫分散到多個資料庫中。此時系統要查詢時需要切換不同的資料庫進行查詢,那麼系統如何知道要查詢的數據在哪個資料庫中?當添加一條記錄時要向哪個資料庫中插入呢?這些問題處理起來都是非常的麻煩。
這種情況下可以使用一個資料庫中間件mycat來解決相關的問題。接下來瞭解一下什麼是mycat。
2 Mycat介紹
2.1 什麼是Mycat?
Mycat 背後是阿裡曾經開源的知名產品——Cobar。Cobar 的核心功能和優勢是 MySQL 資料庫分片,此產品曾經廣為流傳,據說最早的發起者對 Mysql 很精通,後來從阿裡跳槽了,阿裡隨後開源的 Cobar,並維持到 2013 年年初,然後,就沒有然後了。
Cobar 的思路和實現路徑的確不錯。基於 Java 開發的,實現了 MySQL 公開的二進位傳輸協議,巧妙地將自己偽裝成一個 MySQL Server,目前市面上絕大多數 MySQL 客戶端工具和應用都能相容。比自己實現一個新的資料庫協議要明智的多,因為生態環境在哪裡擺著。
Mycat 是基於 cobar 演變而來,對 cobar 的代碼進行了徹底的重構,使用 NIO 重構了網路模塊,並且優化了 Buffer 內核,增強了聚合,Join 等基本特性,同時相容絕大多數資料庫成為通用的資料庫中間件。
簡單的說,MyCAT就是:
·一個新穎的資料庫中間件產品支持mysql集群,或者mariadb cluster,提供高可用性數據分片集群。你可以像使用mysql一樣使用mycat。對於開發人員來說根本感覺不到mycat的存在。
2.2 Mycat支持的資料庫
2.3 Mycat的分片策略
2.4 概念說明
2.4.1 邏輯庫(schema) :
前面一節講了資料庫中間件,通常對實際應用來說,並不需要知道中間件的存在,業務開發人員只需要知道資料庫的概念,所以資料庫中間件可以被看做是一個或多個資料庫集群構成的邏輯庫。
2.4.2 邏輯表(table):
既然有邏輯庫,那麼就會有邏輯表,分散式資料庫中,對應用來說,讀寫數據的表就是邏輯表。邏輯表,可以是數據切分後,分佈在一個或多個分片庫中,也可以不做數據切分,不分片,只有一個表構成。
分片表:是指那些原有的很大數據的表,需要切分到多個資料庫的表,這樣,每個分片都有一部分數據,所有分片構成了完整的數據。 總而言之就是需要進行分片的表。
非分片表:一個資料庫中並不是所有的表都很大,某些表是可以不用進行切分的,非分片是相對分片表來說的,就是那些不需要進行數據切分的表。
2.4.3 分片節點(dataNode)
數據切分後,一個大表被分到不同的分片資料庫上面,每個表分片所在的資料庫就是分片節點(dataNode)。
2.4.4 節點主機(dataHost)
數據切分後,每個分片節點(dataNode)不一定都會獨占一臺機器,同一機器上面可以有多個分片資料庫,這樣一個或多個分片節點(dataNode)所在的機器就是節點主機(dataHost),為了規避單節點主機併發數限制,儘量將讀寫壓力高的分片節點(dataNode)均衡的放在不同的節點主機(dataHost)。
2.4.5 分片規則(rule)
前面講了數據切分,一個大表被分成若幹個分片表,就需要一定的規則,這樣按照某種業務規則把數據分到某個分片的規則就是分片規則,數據切分選擇合適的分片規則非常重要,將極大的避免後續數據處理的難度。
3 Mycat的下載及安裝
3.1 安裝環境
1、jdk:要求jdk必須是1.7及以上版本
2、Mysql:推薦mysql是5.5以上版本
3、Mycat:
Mycat的官方網站:
下載地址:
https://github.com/MyCATApache/Mycat-download
3.2 安裝步驟
Mycat有windows、linux多種版本。本教程為linux安裝步驟,windows基本相同。
第一步:下載Mycat-server-xxxx-linux.tar.gz
第二步:將壓縮包解壓縮。建議將mycat放到/usr/local/mycat目錄下。
第三步:進入mycat目錄,啟動mycat
./mycat start
停止:
./mycat stop
mycat 支持的命令{ console | start | stop | restart | status | dump }
Mycat的預設埠號為:8066
4 Mycat的分片
4.1 需求
把商品表分片存儲到三個數據節點上。
4.2 安裝環境分析
兩台mysql資料庫伺服器:
Host1:192.168.25.134
Host2:192.168.25.166
host1環境
操作系統版本 : centos6.4
資料庫版本 : mysql-5.6
mycat版本 :1.4 release
資料庫名 : db1、db3
mysql節點2環境
操作系統版本 : centos6.4
資料庫版本 : mysql-5.6
mycat版本 :1.4 release
資料庫名 : db2
MyCat安裝到節點1上(需要安裝jdk)
4.3 配置schema.xml
4.3.1 Schema.xml介紹
Schema.xml作為MyCat中重要的配置文件之一,管理著MyCat的邏輯庫、表、分片規則、DataNode以及DataSource。弄懂這些配置,是正確使用MyCat的前提。這裡就一層層對該文件進行解析。
schema 標簽用於定義MyCat實例中的邏輯庫
Table 標簽定義了MyCat中的邏輯表
dataNode 標簽定義了MyCat中的數據節點,也就是我們通常說所的數據分片。
dataHost標簽在mycat邏輯庫中也是作為最底層的標簽存在,直接定義了具體的資料庫實例、讀寫分離配置和心跳語句。
註意:若是LINUX版本的MYSQL,則需要設置為Mysql大小寫不敏感,否則可能會發生表找不到的問題。 在MySQL的配置文件中/etc/my.cnf [mysqld] 中增加一行 lower_case_table_names=1 |
4.3.2 Schema.xml配置
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://org.opencloudb/"> <schema name="e3mall" checkSQLschema="false" sqlMaxLimit="100"> <!-- auto sharding by id (long) --> <table name="tb_item" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" /> </schema> <dataNode name="dn1" dataHost="localhost1" database="db1" /> <dataNode name="dn2" dataHost="localhost2" database="db2" /> <dataNode name="dn3" dataHost="localhost1" database="db3" /> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="hostM1" url="192.168.25.134:3306" user="root" password="root"> <!-- can have multi read hosts --> </writeHost> </dataHost> <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="hostM1" url="192.168.25.166:3306" user="root" password="root"> <!-- can have multi read hosts --> </writeHost> </dataHost> </mycat:schema>
4.4 配置server.xml
4.4.1 Server.xml介紹
server.xml幾乎保存了所有mycat需要的系統配置信息。最常用的是在此配置用戶名、密碼及許可權。
4.4.2 Server.xml配置
<user name="test"> <property name="password">test</property> <property name="schemas">e3mall</property> <property name="readOnly">false</property> </user>
4.5 配置rule.xml
rule.xml裡面就定義了我們對錶進行拆分所涉及到的規則定義。我們可以靈活的對錶使用不同的分片演算法,或者對錶使用相同的演算法但具體的參數不同。這個文件裡面主要有tableRule和function這兩個標簽。在具體使用過程中可以按照需求添加tableRule
和function。
此配置文件可以不用修改,使用預設即可。
4.6 測試分片
4.6.1 創建表
配置完畢後,重新啟動mycat。使用mysql客戶端連接mycat,創建表。
-- ---------------------------- -- Table structure for tb_item -- ---------------------------- DROP TABLE IF EXISTS `tb_item`; CREATE TABLE `tb_item` ( `id` bigint(20) NOT NULL COMMENT '商品id,同時也是商品編號', `title` varchar(100) NOT NULL COMMENT '商品標題', `sell_point` varchar(500) DEFAULT NULL COMMENT '商品賣點', `price` bigint(20) NOT NULL COMMENT '商品價格,單位為:分', `num` int(10) NOT NULL COMMENT '庫存數量', `barcode` varchar(30) DEFAULT NULL COMMENT '商品條形碼', `image` varchar(500) DEFAULT NULL COMMENT '商品圖片', `cid` bigint(10) NOT NULL COMMENT '所屬類目,葉子類目', `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '商品狀態,1-正常,2-下架,3-刪除', `created` datetime NOT NULL COMMENT '創建時間', `updated` datetime NOT NULL COMMENT '更新時間', PRIMARY KEY (`id`), KEY `cid` (`cid`), KEY `status` (`status`), KEY `updated` (`updated`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品表';
4.6.2 插入數據
將此文件中的數據插入到資料庫:
4.6.3 分片測試
由於配置的分片規則為“auto-sharding-long”,所以mycat會根據此規則自動分片。
每個datanode中保存一定數量的數據。根據id進行分片
經測試id範圍為:
Datanode1:1~5000000
Datanode2:5000000~10000000
Datanode3:10000001~15000000
當15000000以上的id插入時報錯:
[Err] 1064 - can't find any valid datanode :TB_ITEM -> ID -> 15000001
此時需要添加節點了。
5 Mycat讀寫分離
資料庫讀寫分離對於大型系統或者訪問量很高的互聯網應用來說,是必不可少的一個重要功能。對於MySQL來說,標準的讀寫分離是主從模式,一個寫節點Master後面跟著多個讀節點,讀節點的數量取決於系統的壓力,通常是1-3個讀節點的配置
Mycat讀寫分離和自動切換機制,需要mysql的主從複製機制配合。
5.1 Mysql的主從複製
主從配置需要註意的地方
1、主DB server和從DB server資料庫的版本一致
2、主DB server和從DB server資料庫數據名稱一致
3、主DB server開啟二進位日誌,主DB server和從DB server的server_id都必須唯一
5.2 Mysql主伺服器配置
第一步:修改my.cnf文件:
在[mysqld]段下添加:
binlog-do-db=db1 binlog-ignore-db=mysql #啟用二進位日誌 log-bin=mysql-bin #伺服器唯一ID,一般取IP最後一段 server-id=134 |
第二步:重啟mysql服務
service mysqld restart
第三步:建立帳戶並授權slave
mysql>GRANT FILE ON *.* TO 'backup'@'%' IDENTIFIED BY '123456';
mysql>GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* to 'backup'@'%' identified by '123456';
#一般不用root帳號,“%”表示所有客戶端都可能連,只要帳號,密碼正確,此處可用具體客戶端IP代替,如192.168.145.226,加強安全。
刷新許可權
mysql> FLUSH PRIVILEGES;
查看mysql現在有哪些用戶
mysql>select user,host from mysql.user;
第四步:查詢master的狀態
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 120 | db1 | mysql | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set
5.3 Mysql從伺服器配置
第一步:修改my.cnf文件
[mysqld]
server-id=166
第二步:配置從伺服器
mysql>change master to master_host='192.168.25.128',master_port=3306,master_user='backup',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=120
註意語句中間不要斷開,master_port為mysql伺服器埠號(無引號),master_user為執行同步操作的資料庫賬戶,“120”無單引號(此處的120就是show master status 中看到的position的值,這裡的mysql-bin.000001就是file對應的值)。
第二步:啟動從伺服器複製功能
Mysql>start slave;
第三步:檢查從伺服器複製功能狀態:
mysql> show slave status
……………………(省略部分)
Slave_IO_Running: Yes //此狀態必須YES
Slave_SQL_Running: Yes //此狀態必須YES
……………………(省略部分)
註:Slave_IO及Slave_SQL進程必須正常運行,即YES狀態,否則都是錯誤的狀態(如:其中一個NO均屬錯誤)。
錯誤處理: 如果出現此錯誤: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work. 因為是mysql是克隆的系統所以mysql的uuid是一樣的,所以需要修改。 |
解決方法: 刪除/var/lib/mysql/auto.cnf文件,重新啟動服務。 |
以上操作過程,從伺服器配置完成。
5.4 Mycat配置
Mycat 1.4 支持MySQL主從複製狀態綁定的讀寫分離機制,讓讀更加安全可靠,配置如下:
<dataNode name="dn1" dataHost="localhost1" database="db1" /> <dataNode name="dn2" dataHost="localhost1" database="db2" /> <dataNode name="dn3" dataHost="localhost1" database="db3" /> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100"> <heartbeat>show slave status</heartbeat> <writeHost host="hostM" url="192.168.25.134:3306" user="root" password="root"> <readHost host="hostS" url="192.168.25.166:3306" user="root" password="root" /> </writeHost> </dataHost>
|
(1) 設置 balance="1"與writeType="0"
Balance參數設置:
1. balance=“0”, 所有讀操作都發送到當前可用的writeHost上。
2. balance=“1”,所有讀操作都隨機的發送到readHost。
3. balance=“2”,所有讀操作都隨機的在writeHost、readhost上分發
WriteType參數設置:
1. writeType=“0”, 所有寫操作都發送到可用的writeHost上。
2. writeType=“1”,所有寫操作都隨機的發送到readHost。
3. writeType=“2”,所有寫操作都隨機的在writeHost、readhost分上發。
“readHost是從屬於writeHost的,即意味著它從那個writeHost獲取同步數據,因此,當它所屬的writeHost宕機了,則它也不會再參與到讀寫分離中來,即“不工作了”,這是因為此時,它的數據已經“不可靠”了。基於這個考慮,目前mycat 1.3和1.4版本中,若想支持MySQL一主一從的標準配置,並且在主節點宕機的情況下,從節點還能讀取數據,則需要在Mycat里配置為兩個writeHost並設置banlance=1。”
(2) 設置 switchType="2" 與slaveThreshold="100"
switchType 目前有三種選擇:
-1:表示不自動切換
1 :預設值,自動切換
2 :基於MySQL主從同步的狀態決定是否切換
“Mycat心跳檢查語句配置為 show slave status ,dataHost 上定義兩個新屬性: switchType="2" 與slaveThreshold="100",此時意味著開啟MySQL主從複製狀態綁定的讀寫分離與切換機制。Mycat心跳機制通過檢測 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三個欄位來確定當前主從同步的狀態以及Seconds_Behind_Master主從複製時延。“
6 附:Centos6.5下安裝mysql
第一步:查看mysql是否安裝。
rpm -qa|grep mysql
第二步:如果mysql的版本不是想要的版本。需要把mysql卸載。
yum remove mysql mysql-server mysql-libs mysql-common
rm -rf /var/lib/mysql
rm /etc/my.cnf
第三步:安裝mysql。需要使用yum命令安裝。在安裝mysql之前需要安裝mysql的下載源。需要從oracle的官方網站下載。
1)下載mysql的源包。
我們是centos6.4對應的rpm包為:mysql-community-release-el6-5.noarch.rpm
2)安裝mysql下載源:
yum localinstall mysql-community-release-el6-5.noarch.rpm
()此附件可保存
3)線上安裝mysql:
yum install mysql-community-server
第四步:啟動mysql
service mysqld start
第五步:需要給root用戶設置密碼。
/usr/bin/mysqladmin -u root password 'new-password' // 為root賬號設置密碼
第六步:遠程連接授權。
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
註意:'myuser'、'mypassword' 需要替換成實際的用戶名和密碼。