Linux Centos MyCat資料庫中介軟體安裝與配置
前言
如今隨著網際網路的發展,資料的量級也是撐指數的增長,從GB到TB到PB。對資料的各種操作也是愈加的困難,傳統的關係性資料庫已經無法滿足快速查詢與插入資料的需求。這個時候NoSQL的出現暫時解決了這一危機。它通過降低資料的安全性,減少對事務的支援,減少對複雜查詢的支援,來獲取效能上的提升。
但是,在有些場合NoSQL一些折衷是無法滿足使用場景的,就比如有些使用場景是絕對要有事務與安全指標的。這個時候NoSQL肯定是無法滿足的,所以還是需要使用關係性資料庫。如果使用關係型資料庫解決海量儲存的問題呢?此時就需要做資料庫叢集,為了提高查詢效能將一個數據庫的資料分散到不同的資料庫中儲存。
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的存在。
構架圖
Mycat支援的資料庫
MyCat安裝與啟動
環境要求
- JDK必須是1.7及以上版本
- MySQL推薦使用5.5以上的版本
- 本次安裝
JDK1.8
、MySQL5.7
、MyCat1.5
- Mysql安裝這裡不在進行安裝了,具體的可以看MySQL安裝教程。
1、Mycat官方網站
http://www.mycat.org.cn/
2、下載地址:
https://github.com/MyCATApache/Mycat-download
提供下載連結 百度網盤
3、將下載好的 Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz
4、將壓縮包解壓。建議將Mycat放到/usr/local/mycat目錄下
tar -xzvf Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz
mv mycat /usr/locat
5、修改配置檔案 mycat/conf/wrapper.conf
指定JDK路徑
大概在第5行左右,路徑根據實際自己的情況
wrapper.java.command=/usr/java/jdk1.8.0_171/bin/java
6、先學幾個命令
./mycat start 啟動
./mycat stop 停止
./mycat console 前臺執行
./mycat install 新增到系統自動啟動(暫未實現)
./mycat remove 取消隨系統自動啟動(暫未實現)
./mycat restart 重啟服務
./mycat pause 暫停
./mycat status 檢視啟動狀態
7、進到mycat目錄的bin目錄下,啟動Mycat
./mycat console
出現一堆錯誤
Running Mycat-server...
wrapper | --> Wrapper Started as Console
wrapper | Launching a JVM...
wrapper | JVM exited while loading the application.
jvm 1 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 1 | Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000715550000, 715849728, 0) failed; error='Cannot allocate memory' (errno=12)
jvm 1 | #
jvm 1 | # There is insufficient memory for the Java Runtime Environment to continue.
jvm 1 | # Native memory allocation (mmap) failed to map 715849728 bytes for committing reserved memory.
jvm 1 | # An error report file with more information is saved as:
jvm 1 | # /usr/local/mycat/hs_err_pid7676.log
wrapper | Launching a JVM...
wrapper | JVM exited while loading the application.
jvm 2 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 2 | Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000715550000, 715849728, 0) failed; error='Cannot allocate memory' (errno=12)
jvm 2 | #
jvm 2 | # There is insufficient memory for the Java Runtime Environment to continue.
jvm 2 | # Native memory allocation (mmap) failed to map 715849728 bytes for committing reserved memory.
jvm 2 | # An error report file with more information is saved as:
jvm 2 | # /usr/local/mycat/hs_err_pid7681.log
wrapper | Launching a JVM...
wrapper | JVM exited while loading the application.
jvm 3 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 3 | Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000715550000, 715849728, 0) failed; error='Cannot allocate memory' (errno=12)
jvm 3 | #
jvm 3 | # There is insufficient memory for the Java Runtime Environment to continue.
jvm 3 | # Native memory allocation (mmap) failed to map 715849728 bytes for committing reserved memory.
jvm 3 | # An error report file with more information is saved as:
jvm 3 | # /usr/local/mycat/hs_err_pid7687.log
wrapper | Launching a JVM...
wrapper | JVM exited while loading the application.
jvm 4 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 4 | Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000715550000, 715849728, 0) failed; error='Cannot allocate memory' (errno=12)
jvm 4 | #
jvm 4 | # There is insufficient memory for the Java Runtime Environment to continue.
jvm 4 | # Native memory allocation (mmap) failed to map 715849728 bytes for committing reserved memory.
jvm 4 | # An error report file with more information is saved as:
jvm 4 | # /usr/local/mycat/hs_err_pid7692.log
wrapper | Launching a JVM...
wrapper | JVM exited while loading the application.
jvm 5 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 5 | Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000715550000, 715849728, 0) failed; error='Cannot allocate memory' (errno=12)
jvm 5 | #
jvm 5 | # There is insufficient memory for the Java Runtime Environment to continue.
jvm 5 | # Native memory allocation (mmap) failed to map 715849728 bytes for committing reserved memory.
jvm 5 | # An error report file with more information is saved as:
jvm 5 | # /usr/local/mycat/hs_err_pid7697.log
wrapper | There were 5 failed launches in a row, each lasting less than 300 seconds. Giving up.
wrapper | There may be a configuration problem: please check the logs.
wrapper | <-- Wrapper Stopped
在mycat目錄下可以看到一些 hs_err_pid
的檔案
原因是因為我們沒有配置JVM堆記憶體的大小,導致程式無法啟動。
解決辦法
1、修改 mycat/conf/wrapper.conf 加上下面配置
我的是加到檔案最後面
wrapper.java.additional.10=-Xmx1G
wrapper.java.additional.11=-Xms512M
2、修改再次啟動
Running Mycat-server...
wrapper | --> Wrapper Started as Console
wrapper | Launching a JVM...
jvm 1 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
jvm 1 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
jvm 1 |
jvm 1 | log4j 2018-12-04 22:34:38 [./conf/log4j.xml] load completed.
jvm 1 | MyCAT Server startup successfully. see logs in logs/mycat.log
看到上面提示表示Mycat成功啟動,下面看一下啟動埠
這時候可以到 Mycat的預設埠號為:8066
MyCat 分片-海量資料儲存解決方案
什麼分片
簡單來說,就是指通過某種特定的條件,將我們存放在同一個資料庫中的資料分散存放到多個數據庫(主機)上面,以達到分散單臺裝置負載的效果。
資料的切分(Sharding)根據其切分規則的型別,可以分為兩種切分模式。
1、一種是按照不同的表(或者Schema)來切分到不同的資料庫(主機)之上,這種切分可以稱之為資料的垂直(縱向)切分。
2、另外一種則是根據表中的資料的邏輯關係,將同一個表中的資料按照某種條件拆分到多臺資料庫(主機)上面,這種切分稱之為資料的水平(橫向)切分。
MyCat分片策略
1、邏輯庫(Schema)
資料庫中介軟體,通常對實際應用來說,並不需要知道中介軟體的存在,業務開發人員只需要知道資料庫的概念,所以資料庫中介軟體可以被看做是一個或多個數據庫叢集構成的邏輯庫。
2、邏輯表(Table)
既然有邏輯庫,那麼就會有邏輯表,分散式資料庫中,對應用來說,讀寫資料的表就是邏輯表。邏輯表,可以是資料切分後,分佈在一個或多個分片庫中,也可以不做資料切分,不分片,只有一個表構成。
分片表:是指那些原有的很大資料的表,需要切分到多個數據庫的表,這樣,每個分片都有一部分資料,所有分片構成了完整的資料。 總而言之就是需要進行分片的表。
非分片表:一個數據庫中並不是所有的表都很大,某些表是可以不用進行切分的,非分片是相對分片表來說的,就是那些不需要進行資料切分的表。
3、分片節點(dataNode)
資料切分後,一個大表被分到不同的分片資料庫上面,每個表分片所在的資料庫就是分片節點(dataNode)。
4、節點主機(dataHost)
資料切分後,每個分片節點(dataNode)不一定都會獨佔一臺機器,同一機器上面可以有多個分片資料庫,這樣一個或多個分片節點(dataNode)所在的機器就是節點主機(dataHost),為了規避單節點主機併發數限制,儘量將讀寫壓力高的分片節點(dataNode)均衡的放在不同的節點主機(dataHost)。
5、分片規則(rule)
前面講了資料切分,一個大表被分成若干個分片表,就需要一定的規則,這樣按照某種業務規則把資料分到某個分片的規則就是分片規則,資料切分選擇合適的分片規則非常重要,將極大的避免後續資料處理的難度。
MyCat分片配置
配置檔案說明mycat目錄下
-
–bin 啟動目錄
-
–conf 配置檔案存放配置檔案
-
–lib MyCAT自身的jar包或依賴的jar包的存放目錄。
-
–logs MyCAT日誌的存放目錄。日誌存放在logs/log中,每天一個檔案。
-
conf目錄
--server.xml:是Mycat伺服器引數調整和使用者授權的配置檔案。
--schema.xml:是邏輯庫定義和表以及分片定義的配置檔案。
--rule.xml: 是分片規則的配置檔案,分片規則的具體一些引數資訊單獨存放為檔案,也在這個目錄下,配置檔案修改需要重啟MyCAT。
--log4j.xml: 日誌存放在logs/log中,每天一個檔案,日誌的配置是在conf/log4j.xml中,根據自己的需要可以調整輸出級別為debug,debug級別下,會輸出更多的資訊,方便排查問題。
--autopartition-long.txt,partition-hash-int.txt,sequence_conf.properties, sequence_db_conf.properties 分片相關的id分片規則配置檔案
Mycat最重要的3大配置檔案如圖。
1、配置 schema.xml
- schema.xml作為MyCat中重要的配置檔案之一,管理著MyCat的邏輯庫、邏輯表以及對應的分片規則、DataNode以及DataSource。弄懂這些配置,是正確使用MyCat的前提。這裡就一層層對該檔案進行解析。
- schema 標籤用於定義MyCat例項中的邏輯庫。
- Table 標籤定義了MyCat中的邏輯表 rule用於指定分片規則,auto-sharding-long的分片規則是按ID值的範圍進行分片 1-5000000 為第1片 5000001-10000000 為第2片… 具體的後面會講解
- dataNode 標籤定義了MyCat中的資料節點,也就是我們通常說所的資料分片。
- dataHost標籤在mycat邏輯庫中也是作為最底層的標籤存在,直接定義了具體的資料庫例項、讀寫分離配置和心跳語句。
在伺服器上建立3個數據庫,分別為 db1、db2、db3
myslq -u root -p
CREATE DATABASE db1 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
CREATE DATABASE db2 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
CREATE DATABASE db3 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
Navicat上可以看到建立了三個空資料庫
修改mycat/conf/schema.xml。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/" >
name對應邏輯庫的庫名
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
dataNode 對應下面 dataNode的name
<table name="tb_test" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
dataHost 對應下面的dataHostname
database 對應剛剛新建的三個資料庫
<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="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
修改主機地址及使用者名稱密碼
<writeHost host="hostM1" url="119.23.74.34:3306" user="root"
password="123456">
</writeHost>
</dataHost>
</mycat:schema>
2、配置 server.xml
server.xml幾乎儲存了所有mycat需要的系統配置資訊。最常用的是在此配置使用者名稱、密碼及許可權。在system中新增UTF-8字符集設定,否則儲存中文會出現問號。mycat/conf/server.xml
新增
<property name="charset">utf8</property>
修改 user 的配置,這裡對我們的邏輯庫 TESTDB設定兩個登入使用者
<user name="test">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<!-- 只讀使用者-->
<property name="readOnly">true</property>
</user>
<user name="root">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
</user>
修改配置之後一定記得重啟
./mycat restart
MyCat分片測試
1、首先先用Navicat資料庫連線工具連線到Mycat
連線之後可以看到我們剛剛配置的邏輯庫 TESTDB
現在還是一個空資料庫
我們現在先建立一張表,Navicat新建查詢
CREATE TABLE tb_test (
id BIGINT(20) NOT NULL,
title VARCHAR(100) NOT NULL ,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8
建立後會發現我們MySQL的3個庫,表都自動建立好了。
接下來就是插入資料,注意,在寫INSERT語句時一定要寫把欄位列表寫出來,否則會出現下列錯誤提示:
錯誤程式碼: 1064
1064 - bad insert sql (sharding column:ID not provided,INSERT INTO tb_test (1, 'java')
我們試著插入一些資料
INSERT INTO tb_test(id,title) VALUES(1,'java1');
INSERT INTO tb_test(id,title) VALUES(2,'java2');
INSERT INTO tb_test(id,title) VALUES(3,'java3');
我們會發現這些資料被寫入到第一個節點中了,那什麼時候資料會寫到第二個節點中呢?
我們插入下面的資料就可以插入第二個節點了
INSERT INTO tb_test(id,title) VALUES(5000001,'java5000001');
因為我們採用的分片規則是每節點儲存500萬條資料,所以當ID大於5000000則會儲存到第二個節點上。
目前只設置了三個節點,如果資料大於1000萬條,會怎麼樣呢?執行下列語句測試一下
INSERT INTO tb_test(id,title) VALUES(10000001,'java10000001');
很明顯插入到第三個節點上。
測試結果
Mycat分片規則
mycat/conf/rule.xml
用於定義分片規則,這裡說一下兩種常見的分片規則
1、按主鍵範圍分片 rang-long
在配置檔案中找到
schema.xml
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="tb_test" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
rule.xml
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
tableRule
是定義具體某個表或某一類表的分片規則名稱columns
用於定義分片的列 algorithm代表演算法名稱,接著找rang-long的定義。
<function name="rang-long"
class="org.opencloudb.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
Function用於定義演算法mapFile
用於定義演算法需要的資料,開啟 mycat/conf/autopartition-long.txt
。
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
這裡可以看到最大的ID只能是 1500萬,如果需要新增更多資料可以修改配置,如果超過了插入會出現錯誤。
這裡插入一條ID為2000M
INSERT INTO tb_test(id,title)VALUES(20000000,"java20000000");
出現錯誤
1064 - can't find any valid datanode :TB_TEST -> ID -> 20000000
意思找不到2000M這個節點,因為沒有配置這個節點。
2、一致性雜湊murmur
當我們需要將資料平均分在幾個分割槽中,需要使用一致性hash規則。
找到function的name為murmur 的定義,將count屬性改為3,因為我要將資料分成3片。
rule.xml
<function name="murmur"
class="org.opencloudb.route.function.PartitionByMurmurHash">
<property name="seed">0</property><!-- 預設是0 -->
<property name="count">3</property><!-- 要分片的資料庫節點數量,必須指定,否則沒法分片 -->
<property name="virtualBucketTimes">160</property><!-- 一個實際的資料庫節點被對映為這麼多虛擬節點,預設是160倍,也就是虛擬節點數是物理節點數的160倍 -->
<!-- <property name="weightMapFile">weightMapFile</property> 節點的權重,沒有指定權重的節點預設是1。以properties檔案的格式填寫,以從0開始到count-1的整數值也就是節點索引為key,以節點權重值為值。所有權重值必須是正整數,否則以1代替 -->
<!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property>
用於測試時觀察各物理節點與虛擬節點的分佈情況,如果指定了這個屬性,會把虛擬節點的murmur hash值與物理節點的對映按行輸出到這個檔案,沒有預設值,如果不指定,就不會輸出任何東西 -->
</function>
再配置檔案中可以找到表規則定義
rule.xml
<tableRule name="sharding-by-murmur">
<rule>
<columns>id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
這個規則指定的列是id,如果資料庫表的主鍵不是Id,是其它欄位可以重新定義一個tableRule。
<tableRule name="sharding-by-murmur-order">
<rule>
<columns>order_id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
在 mycat/conf/schema.xml 中配置邏輯表時,指定規則為上面定義好的 sharding-by-murmur-order
。
name 邏輯為表名
dataName 對應資料庫
rule 對應剛剛新建好的規則
<table name="tb_order" dataNode="dn1,dn2,dn3" rule="sharding-by-murmur-order" />
重啟mycat,下面建立一個 tb_order 表新增一些資料進行測試。
可以看到資料表的基本是平均分佈插入到不同的表,每張表相關資料就是一到兩條。
最後感謝閱讀,講得不好的地方,有問題等歡迎留言,看到第一時間修改和答覆。
注意點
1、修改配置檔案後記得重啟服務。