柚子快報(bào)激活碼778899分享:數(shù)據(jù)庫(kù) MySQL-分庫(kù)分表
柚子快報(bào)激活碼778899分享:數(shù)據(jù)庫(kù) MySQL-分庫(kù)分表
目錄
介紹
問(wèn)題分析
拆分策略
垂直拆分
垂直分庫(kù)
垂直分表
水平拆分
水平分庫(kù)
水平分表
實(shí)現(xiàn)技術(shù)
MyCat
介紹
目錄
結(jié)構(gòu)
入門(mén)
配置
schema.xml
schema標(biāo)簽
datanode標(biāo)簽
datahost標(biāo)簽
rule.xml
server.xml
system標(biāo)簽
user標(biāo)簽
分片
垂直拆分
水平拆分
分片規(guī)則
范圍分片auto-sharding-long
取模分片mod-long
一致性hash分片sharding-by-murmur
枚舉分片
應(yīng)用指定算法sharding-by-substring
固定分片hash算法
字符串hash解析算法
按天分片算法
自然月分片
MyCat管理與監(jiān)控
MyCat原理
MyCat管理
MyCat-eye
介紹
問(wèn)題分析
隨著互聯(lián)網(wǎng)及移動(dòng)互聯(lián)網(wǎng)的發(fā)展,應(yīng)用系統(tǒng)的數(shù)據(jù)量也是成指數(shù)式增長(zhǎng),若采用單數(shù)據(jù)庫(kù)進(jìn)行數(shù)據(jù)存儲(chǔ),存在以下性能瓶頸:
IO瓶頸:熱點(diǎn)數(shù)據(jù)太多,數(shù)據(jù)庫(kù)緩存不足,產(chǎn)生大量磁盤(pán)IO,效率較低,請(qǐng)求數(shù)據(jù)太多,帶寬不夠,網(wǎng)絡(luò)IO瓶頸CPU瓶頸:排序、分組、連接查詢、聚合統(tǒng)計(jì)等SQL會(huì)耗費(fèi)大量的CPU資源,請(qǐng)求數(shù)太多,CPU出現(xiàn)瓶頸
為了解決上述問(wèn)題,需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行分庫(kù)分表處理
分庫(kù)分表的中心思想是將數(shù)據(jù)分散存儲(chǔ),使得單一數(shù)據(jù)庫(kù)/表的數(shù)據(jù)量變小來(lái)緩解單一數(shù)據(jù)庫(kù)的性能問(wèn)題,從而達(dá)到提升數(shù)據(jù)庫(kù)性能的目的
拆分策略
分庫(kù)分表的形式主要是兩種:垂直拆分和水平拆分,拆分的粒度又分為分庫(kù)和分表:
垂直拆分
垂直分庫(kù)
以表為依據(jù),根據(jù)業(yè)務(wù)將不同表拆分到不同庫(kù)中
特點(diǎn):
每個(gè)庫(kù)的表結(jié)構(gòu)都不一樣每個(gè)庫(kù)的數(shù)據(jù)也不一樣所有庫(kù)的并集是全量數(shù)據(jù)
垂直分表
以字段為依據(jù),根據(jù)字段屬性將不同字段拆分到不同表中
特點(diǎn):
每個(gè)表的結(jié)構(gòu)都不一樣每個(gè)表的數(shù)據(jù)也不一樣,一般通過(guò)一列(主鍵/外鍵)關(guān)聯(lián)所有表的并集是全量數(shù)據(jù)
水平拆分
水平分庫(kù)
以行(記錄)為依據(jù),按照一定策略,將一個(gè)庫(kù)的數(shù)據(jù)拆分到多個(gè)庫(kù)中
特點(diǎn):
每個(gè)庫(kù)的表結(jié)構(gòu)都一樣每個(gè)庫(kù)的數(shù)據(jù)都不一樣所有庫(kù)的并集是全量數(shù)據(jù)
水平分表
以行(記錄)為依據(jù),按照一定策略,將一個(gè)表的數(shù)據(jù)拆分到多個(gè)表中
特點(diǎn):
每個(gè)表的結(jié)構(gòu)都一樣每個(gè)表的數(shù)據(jù)都不一樣所有表的并集是全量數(shù)據(jù)
實(shí)現(xiàn)技術(shù)
shardingJDBC:基于AOP原理,在應(yīng)用程序中對(duì)本地執(zhí)行的SQL進(jìn)行攔截、解析、改寫(xiě)、路由處理,需要自行編碼配置實(shí)現(xiàn),只支持Java語(yǔ)言,性能較高M(jìn)yCat:數(shù)據(jù)庫(kù)分庫(kù)分表中間件,不用調(diào)整代碼即可實(shí)現(xiàn)分庫(kù)分表,支持多種語(yǔ)言,性能不及前者
MyCat
介紹
MyCat是開(kāi)源的、活躍的、基于Java語(yǔ)言編寫(xiě)的MySQL數(shù)據(jù)庫(kù)中間件,可以像使用MySQL一樣來(lái)使用MyCat
優(yōu)勢(shì):
性能可靠穩(wěn)定強(qiáng)大的技術(shù)團(tuán)隊(duì)體系完善社區(qū)活躍
目錄
bin:存放可執(zhí)行文件,用于啟動(dòng)停止mycatconf:存放mycat的配置文件lib:存放mycat的項(xiàng)目依賴包(jar)logs:存放mycat的日志文件
結(jié)構(gòu)
在MyCat的整體結(jié)構(gòu)中,分為:邏輯結(jié)構(gòu)和物理結(jié)構(gòu)
MyCat的邏輯結(jié)構(gòu)主要負(fù)責(zé)邏輯庫(kù)、邏輯表、分片規(guī)則、分片節(jié)點(diǎn)等邏輯結(jié)構(gòu)的處理,而具體的數(shù)據(jù)存儲(chǔ)還是在物理結(jié)構(gòu),也就是數(shù)據(jù)庫(kù)服務(wù)器中存儲(chǔ)
入門(mén)
tb_order表中數(shù)據(jù)量很大,對(duì)其進(jìn)行數(shù)據(jù)分片,分為三個(gè)數(shù)據(jù)節(jié)點(diǎn),每一個(gè)節(jié)點(diǎn)主機(jī)位于不同的服務(wù)器上
準(zhǔn)備三臺(tái)服務(wù)器,并分別創(chuàng)建數(shù)據(jù)庫(kù)db01:
192.168.200.210:MyCat中間件服務(wù)器,同時(shí)也是第一個(gè)分片服務(wù)器192.168.200.213:第二個(gè)分片服務(wù)器192.168.200.214:第三個(gè)分片服務(wù)器
修改schema.xml配置:
修改server.xml配置:
啟動(dòng):
先啟動(dòng)3臺(tái)分片服務(wù)器,然后啟動(dòng)MyCat服務(wù)器,切換到MyCat的安裝目錄,啟動(dòng)MyCat
#啟動(dòng)
bin/mycat start
#停止
bin/mycat stop
MyCat啟動(dòng)后,占用端口號(hào)8066
連接MyCat:
MyCat在底層模擬了MySQL的協(xié)議
mysql -h 192.168.200.210 -P 8066 -uroot -p123456
在MyCat中創(chuàng)建表,并插入數(shù)據(jù):
CREATE TABLE TB_ORDER (
id BIGINT(20) NOT NULL,
title VARCHAR(100) NOT NULL ,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8 ;
INSERT INTO TB_ORDER(id,title) VALUES(1,'goods1');
INSERT INTO TB_ORDER(id,title) VALUES(2,'goods2');
INSERT INTO TB_ORDER(id,title) VALUES(3,'goods3');
INSERT INTO TB_ORDER(id,title) VALUES(1,'goods1');
INSERT INTO TB_ORDER(id,title) VALUES(2,'goods2');
INSERT INTO TB_ORDER(id,title) VALUES(3,'goods3');
INSERT INTO TB_ORDER(id,title) VALUES(5000000,'goods5000000');
INSERT INTO TB_ORDER(id,title) VALUES(10000000,'goods10000000');
INSERT INTO TB_ORDER(id,title) VALUES(10000001,'goods10000001');
INSERT INTO TB_ORDER(id,title) VALUES(15000000,'goods15000000');
INSERT INTO TB_ORDER(id,title) VALUES(15000001,'goods15000001');
在插入數(shù)據(jù)時(shí):
如果id的值在1-500w之間,數(shù)據(jù)將會(huì)存儲(chǔ)在第一個(gè)分片數(shù)據(jù)庫(kù)中如果id的值在500w-1000w之間,數(shù)據(jù)將會(huì)存儲(chǔ)在第二個(gè)分片數(shù)據(jù)庫(kù)中如果id的值在1000w-1500w之間,數(shù)據(jù)將會(huì)存儲(chǔ)在第三個(gè)分片數(shù)據(jù)庫(kù)中如果id的值超出1500w,在插入數(shù)據(jù)時(shí),將會(huì)報(bào)錯(cuò)
數(shù)據(jù)落在哪一個(gè)分片服務(wù)器是由邏輯表配置時(shí)的一個(gè)參數(shù)rule決定的,這個(gè)參數(shù)配置的就是分片規(guī)則
配置
schema.xml
schema.xml作為MyCat中最重要的配置文件之一,涵蓋了MyCat的邏輯庫(kù)、邏輯表、分片規(guī)則、分片節(jié)點(diǎn)及數(shù)據(jù)源的配置
主要包含三組標(biāo)簽:
schema標(biāo)簽datanode標(biāo)簽datahost標(biāo)簽
schema標(biāo)簽
1.schema定義邏輯庫(kù)
schema標(biāo)簽用于定義 MyCat實(shí)例中的邏輯庫(kù) , 一個(gè)MyCat實(shí)例中, 可以有多個(gè)邏輯庫(kù) , 可以通過(guò)schema標(biāo)簽來(lái)劃分不同的邏輯庫(kù)。MyCat中的邏輯庫(kù)的概念,等同于MySQL中的database概念,需要操作某個(gè)邏輯庫(kù)下的表時(shí), 也需要切換邏輯庫(kù)(use xxx)
核心屬性:
name:指定自定義的邏輯庫(kù)庫(kù)名checkSQLschema:在SQL語(yǔ)句操作時(shí)指定了數(shù)據(jù)庫(kù)名稱,執(zhí)行時(shí)是否自動(dòng)去除;true:自動(dòng)去 除,false:不自動(dòng)去除sqlMaxLimit:如果未指定limit進(jìn)行查詢,列表查詢模式查詢多少條記錄
2.schema中的table定義邏輯表
table標(biāo)簽定義了MyCat中邏輯庫(kù)schema下的邏輯表 , 所有需要拆分的表都需要在table標(biāo)簽中定義
核心屬性:
name:定義邏輯表表名,在該邏輯庫(kù)下唯一dataNode:定義邏輯表所屬的dataNode,該屬性需要與dataNode標(biāo)簽中name對(duì)應(yīng);多個(gè)dataNode逗號(hào)分隔rule:分片規(guī)則的名字,分片規(guī)則名字是在rule.xml中定義的primaryKey:邏輯表對(duì)應(yīng)真實(shí)表的主鍵type:邏輯表的類型,目前邏輯表只有全局表和普通表,如果未配置,就是普通表;全局表,配置為 global
datanode標(biāo)簽
核心屬性:
name:定義數(shù)據(jù)節(jié)點(diǎn)名稱dataHost:數(shù)據(jù)庫(kù)實(shí)例主機(jī)名稱,引用自 dataHost 標(biāo)簽中name屬性database:定義分片所屬數(shù)據(jù)庫(kù)
datahost標(biāo)簽
該標(biāo)簽在MyCat邏輯庫(kù)中作為底層標(biāo)簽存在,直接定義了具體的數(shù)據(jù)庫(kù)實(shí)例、讀寫(xiě)分離、心跳語(yǔ)句
核心屬性:
name:唯一標(biāo)識(shí),供上層標(biāo)簽使用maxCon/minCon:最大連接數(shù)/最小連接數(shù)balance:負(fù)載均衡策略,取值 0,1,2,3writeType:寫(xiě)操作分發(fā)方式(0:寫(xiě)操作轉(zhuǎn)發(fā)到第一個(gè)writeHost,第一個(gè)掛了,切換到第二個(gè);1:寫(xiě)操作隨機(jī)分發(fā)到配置的writeHost)dbDriver:數(shù)據(jù)庫(kù)驅(qū)動(dòng),支持native、jdbc
rule.xml
rule.xml中定義所有拆分表的規(guī)則, 在使用過(guò)程中可以靈活的使用分片算法, 或者對(duì)同一個(gè)分片算法使用不同的參數(shù), 它讓分片過(guò)程可配置化
主要包含兩類標(biāo)簽:tableRule、Function
server.xml
server.xml配置文件包含了MyCat的系統(tǒng)配置信息,主要有兩個(gè)重要的標(biāo)簽:system、user
system標(biāo)簽
主要配置MyCat中的系統(tǒng)配置信息
屬性取值含義charsetutf8設(shè)置Mycat的字符集, 字符集需要與MySQL的字符集保持一致nonePasswordLogin0,10為需要密碼登陸、1為不需要密碼登陸 ,默認(rèn)為0,設(shè)置為1則需要指定默認(rèn)賬戶useHandshakeV100,1使用該選項(xiàng)主要的目的是為了能夠兼容高版本的jdbc驅(qū)動(dòng), 是否采用HandshakeV10Packet來(lái)與client進(jìn)行通信, 1:是, 0:否useSqlStat0,1開(kāi)啟SQL實(shí)時(shí)統(tǒng)計(jì), 1 為開(kāi)啟 , 0 為關(guān)閉 ; 開(kāi)啟之后, MyCat會(huì)自動(dòng)統(tǒng)計(jì)SQL語(yǔ)句的執(zhí)行情況 ; mysql -h 127.0.0.1 -P 9066 -u root -p 查看MyCat執(zhí)行的SQL, 執(zhí)行效率比較低的SQL , SQL的整體執(zhí)行情況、讀寫(xiě)比例等 ; show @@sql ; show @@sql.slow ; show @@sql.sum ;useGlobleTableCheck0,1是否開(kāi)啟全局表的一致性檢測(cè)。1為開(kāi)啟 ,0為關(guān)閉 。sqlExecuteTimeout1000SQL語(yǔ)句執(zhí)行的超時(shí)時(shí)間 , 單位為 s ;sequnceHandlerType0,1,2用來(lái)指定Mycat全局序列類型,0 為本地文件,1 為數(shù)據(jù)庫(kù)方式,2 為時(shí)間戳列方式,默認(rèn)使用本地文件方式,文件方式主要用于測(cè)試sequnceHandlerPattern正則表達(dá)式必須帶有MYCATSEQ或者 mycatseq進(jìn)入序列匹配流程 注意MYCATSEQ_有空格的情況subqueryRelationshipChecktrue,false子查詢中存在關(guān)聯(lián)查詢的情況下,檢查關(guān)聯(lián)字段中是否有分片字段 .默認(rèn) falseuseCompression0,1開(kāi)啟mysql壓縮協(xié)議 , 0 : 關(guān)閉, 1 : 開(kāi)啟fakeMySQLVersion5.5,5.6設(shè)置模擬的MySQL版本號(hào)defaultSqlParser由于MyCat的最初版本使用了FoundationDB的SQL解析器, 在MyCat1.3后增加了Druid解析器, 所以要設(shè)置defaultSqlParser屬性來(lái)指定默認(rèn)的解析器; 解析器有兩個(gè) : druidparser 和 fdbparser, 在MyCat1.4之后,默認(rèn)是druidparser, fdbparser已經(jīng)廢除了processors1,2....指定系統(tǒng)可用的線程數(shù)量, 默認(rèn)值為CPU核心 x 每個(gè)核心運(yùn)行線程數(shù)量; processors 會(huì)影響processorBufferPool, processorBufferLocalPercent, processorExecutor屬性, 所有, 在性能調(diào)優(yōu)時(shí), 可以適當(dāng)?shù)匦薷膒rocessors值processorBufferChunk指定每次分配Socket Direct Buffer默認(rèn)值為4096字節(jié), 也會(huì)影響B(tài)ufferPool長(zhǎng)度, 如果一次性獲取字節(jié)過(guò)多而導(dǎo)致buffer不夠用, 則會(huì)出現(xiàn)警告, 可以調(diào)大該值processorExecutor指定NIOProcessor上共享 businessExecutor固定線程池的大小; MyCat把異步任務(wù)交給 businessExecutor線程池中, 在新版本的MyCat中這個(gè)連接池使用頻次不高, 可以適當(dāng)?shù)匕言撝嫡{(diào)小packetHeaderSize指定MySQL協(xié)議中的報(bào)文頭長(zhǎng)度, 默認(rèn)4個(gè)字節(jié)maxPacketSize指定MySQL協(xié)議可以攜帶的數(shù)據(jù)最大大小, 默認(rèn)值為16MidleTimeout30指定連接的空閑時(shí)間的超時(shí)長(zhǎng)度;如果超時(shí),將關(guān)閉資源并回收, 默認(rèn)30分鐘txIsolation1,2,3,4初始化前端連接的事務(wù)隔離級(jí)別,默認(rèn)為 REPEATED_READ , 對(duì)應(yīng)數(shù)字為3 READ_UNCOMMITED=1; READ_COMMITTED=2; REPEATED_READ=3; SERIALIZABLE=4;sqlExecuteTimeout300執(zhí)行SQL的超時(shí)時(shí)間, 如果SQL語(yǔ)句執(zhí)行超時(shí),將關(guān)閉連接; 默認(rèn)300秒;serverPort8066定義MyCat的使用端口, 默認(rèn)8066managerPort9066定義MyCat的管理端口, 默認(rèn)9066
user標(biāo)簽
配置MyCat中的用戶、訪問(wèn)密碼以及用戶針對(duì)邏輯庫(kù)、邏輯表的權(quán)限信息
分片
垂直拆分
在業(yè)務(wù)系統(tǒng)中, 涉及以下表結(jié)構(gòu) ,但是由于用戶與訂單每天都會(huì)產(chǎn)生大量的數(shù)據(jù), 單臺(tái)服務(wù)器的數(shù)據(jù)存儲(chǔ)及處理能力是有限的, 可以對(duì)數(shù)據(jù)庫(kù)表進(jìn)行拆分, 原有的數(shù)據(jù)庫(kù)表如下:
現(xiàn)在考慮將其進(jìn)行垂直分庫(kù)操作,將商品相關(guān)的表拆分到一個(gè)數(shù)據(jù)庫(kù)服務(wù)器,訂單表拆分的一個(gè)數(shù)據(jù)庫(kù)服務(wù)器,用戶及省市區(qū)表拆分到一個(gè)服務(wù)器,最終結(jié)構(gòu)如下:
準(zhǔn)備三臺(tái)服務(wù)器,并創(chuàng)建數(shù)據(jù)庫(kù)shopping:
schema.xml:
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
server.xml:
上傳測(cè)試SQL腳本到服務(wù)器的/root目錄:
執(zhí)行指令導(dǎo)入測(cè)試數(shù)據(jù), 重新啟動(dòng)MyCat后,在命令行中,通過(guò)source指令導(dǎo)入表結(jié)構(gòu)以及對(duì)應(yīng)的數(shù)據(jù),查看數(shù)據(jù)分布情況:
source /root/shopping-table.sql
source /root/shopping-insert.sql
查詢用戶的收件人及收件人的地址信息(包括省、市、區(qū)),可以正常查詢出數(shù)據(jù):
select ua.user_id, ua.contact, p.province, c.city, r.area , ua.address
from tb_user_address ua ,tb_areas_city c , tb_areas_provinces p ,tb_areas_region r
where ua.province_id = p.provinceid and ua.city_id = c.cityid and ua.town_id = r.areaid;
查詢每一筆訂單及訂單的收件地址信息(包括省、市、區(qū)):
SELECT order_id , payment ,receiver, province , city , area
FROM tb_order_master o, tb_areas_provinces p , tb_areas_city c , tb_areas_region r
WHERE o.receiver_province = p.provinceid AND o.receiver_city = c.cityid AND o.receiver_region = r.areaid ;
訂單相關(guān)的表和省市區(qū)的表不在同一個(gè)服務(wù)器中,SQL語(yǔ)句報(bào)錯(cuò),原因是沒(méi)有一個(gè)數(shù)據(jù)庫(kù)服務(wù)器完全包含了訂單及省市區(qū)的表結(jié)構(gòu)
解決方式:全局表
對(duì)于省、市、區(qū)/縣表tb_areas_provinces , tb_areas_city , tb_areas_region,是屬于數(shù)據(jù)字典表,在多個(gè)業(yè)務(wù)模塊中都可能會(huì)遇到,可以將其設(shè)置為全局表,利于業(yè)務(wù)操作
修改schema.xml中的邏輯表的配置,修改 tb_areas_provinces、tb_areas_city、tb_areas_region三個(gè)邏輯表,增加 type 屬性,配置為global,就代表該表是全局表,就會(huì)在所涉及到的dataNode中創(chuàng)建表。對(duì)于當(dāng)前配置來(lái)說(shuō),也就意味著所有的節(jié)點(diǎn)中都有該表了
重啟MyCat
刪除原來(lái)每一個(gè)數(shù)據(jù)庫(kù)服務(wù)器中的所有表結(jié)構(gòu)
通過(guò)source指令導(dǎo)入表及數(shù)據(jù)
檢查每一個(gè)數(shù)據(jù)庫(kù)服務(wù)器中的表及數(shù)據(jù)分布,三個(gè)節(jié)點(diǎn)中都有這三張全局表
再次執(zhí)行SQL語(yǔ)句
當(dāng)在MyCat中更新全局表時(shí),所有分片中的數(shù)據(jù)都改變,每個(gè)節(jié)點(diǎn)的全局表數(shù)據(jù)時(shí)刻保持一致
水平拆分
在業(yè)務(wù)系統(tǒng)中, 有一張表(日志表), 業(yè)務(wù)系統(tǒng)每天都會(huì)產(chǎn)生大量的日志數(shù)據(jù) , 單臺(tái)服務(wù)器的數(shù)據(jù)存儲(chǔ)及處理能力是有限的, 可以對(duì)數(shù)據(jù)庫(kù)表進(jìn)行拆分
每臺(tái)服務(wù)器上創(chuàng)建數(shù)據(jù)庫(kù)itcast
schema.xml:
server.xml:
重啟MyCat,創(chuàng)建表,插入數(shù)據(jù):
CREATE TABLE tb_log (
id bigint(20) NOT NULL COMMENT 'ID',
model_name varchar(200) DEFAULT NULL COMMENT '模塊名',
model_value varchar(200) DEFAULT NULL COMMENT '模塊值',
return_value varchar(200) DEFAULT NULL COMMENT '返回值',
return_class varchar(200) DEFAULT NULL COMMENT '返回值類型',
operate_user varchar(20) DEFAULT NULL COMMENT '操作用戶',
operate_time varchar(20) DEFAULT NULL COMMENT '操作時(shí)間',
param_and_value varchar(500) DEFAULT NULL COMMENT '請(qǐng)求參數(shù)名及參數(shù)值', operate_class varchar(200) DEFAULT NULL COMMENT '操作類',
operate_method varchar(200) DEFAULT NULL COMMENT '操作方法',
cost_time bigint(20) DEFAULT NULL COMMENT '執(zhí)行方法耗時(shí), 單位 ms',
source int(1) DEFAULT NULL COMMENT '來(lái)源 : 1 PC , 2 Android , 3 IOS', PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class,
operate_user, operate_time, param_and_value, operate_class, operate_method,
cost_time,source)
VALUES('1','user','insert','success','java.lang.String','10001','2022-01-06
18:12:28','{\"age\":\"20\",\"name\":\"Tom\",\"gender\":\"1\"}','cn.itcast.controller.UserController','insert','10',1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class,
operate_user, operate_time, param_and_value, operate_class, operate_method,
cost_time,source)
VALUES('2','user','insert','success','java.lang.String','10001','2022-01-06
18:12:27','{\"age\":\"20\",\"name\":\"Tom\",\"gender\":\"1\"}','cn.itcast.controller.UserController','insert','23',1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class,
operate_user, operate_time, param_and_value, operate_class, operate_method,
cost_time,source)
VALUES('3','user','update','success','java.lang.String','10001','2022-01-06
18:16:45','{\"age\":\"20\",\"name\":\"Tom\",\"gender\":\"1\"}','cn.itcast.controller.UserController','update','34',1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class,
operate_user, operate_time, param_and_value, operate_class, operate_method,
cost_time,source)
VALUES('4','user','update','success','java.lang.String','10001','2022-01-06
18:16:45','{\"age\":\"20\",\"name\":\"Tom\",\"gender\":\"1\"}','cn.itcast.controller.UserController','update','13',2);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class,
operate_user, operate_time, param_and_value, operate_class, operate_method,
cost_time,source)
VALUES('5','user','insert','success','java.lang.String','10001','2022-01-06
18:30:31','{\"age\":\"200\",\"name\":\"TomCat\",\"gender\":\"0\"}','cn.itcast.controller.UserController','insert','29',3);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class,
operate_user, operate_time, param_and_value, operate_class, operate_method,
cost_time,source)
VALUES('6','user','find','success','java.lang.String','10001','2022-01-06
18:30:31','{\"age\":\"200\",\"name\":\"TomCat\",\"gender\":\"0\"}','cn.itcast.controller.UserController','find','29',2);
分片規(guī)則
范圍分片auto-sharding-long
根據(jù)指定的字段及其配置的范圍與數(shù)據(jù)節(jié)點(diǎn)的對(duì)應(yīng)情況,來(lái)決定該數(shù)據(jù)屬于哪一個(gè)分片
schema.xml邏輯表配置:
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
分片規(guī)則配置屬性含義:
在rule.xml中配置分片規(guī)則時(shí),關(guān)聯(lián)了一個(gè)映射配置文件autopartition-long.txt:
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
含義:0-500萬(wàn)之間的值,存儲(chǔ)在0號(hào)數(shù)據(jù)節(jié)點(diǎn)(數(shù)據(jù)節(jié)點(diǎn)的索引從0開(kāi)始) ;500萬(wàn)-1000萬(wàn)之間的數(shù)據(jù)存儲(chǔ)在1號(hào)數(shù)據(jù)節(jié)點(diǎn) ;1000萬(wàn)-1500萬(wàn)的數(shù)據(jù)節(jié)點(diǎn)存儲(chǔ)在2號(hào)節(jié)點(diǎn)?
該分片規(guī)則主要針對(duì)于數(shù)字類型的字段使用
取模分片mod-long
根據(jù)指定的字段值與節(jié)點(diǎn)數(shù)量進(jìn)行取模運(yùn)算,根據(jù)運(yùn)算結(jié)果,來(lái)決定該數(shù)據(jù)屬于哪一個(gè)分片
schema.xml邏輯表配置:
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
分片規(guī)則配置屬性含義:
?該分片規(guī)則主要針對(duì)于數(shù)字類型的字段使用
一致性hash分片sharding-by-murmur
一致性哈希是相同的哈希因子計(jì)算值總是被劃分到相同的分區(qū)表中,不會(huì)因?yàn)榉謪^(qū)節(jié)點(diǎn)的增加而改變?cè)瓉?lái)數(shù)據(jù)的分區(qū)位置,有效解決了分布式數(shù)據(jù)的擴(kuò)容問(wèn)題
schema.xml邏輯表配置:
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
分片規(guī)則配置屬性含義:
重啟,創(chuàng)建表插入數(shù)據(jù):
create table tb_order(
id varchar(100) not null primary key, money int null,
content varchar(200) null
);
INSERT INTO tb_order (id, money, content) VALUES ('b92fdaaf-6fc4-11ec-b831-482ae33c4a2d', 10, 'b92fdaf8-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b93482b6-6fc4-11ec-b831-482ae33c4a2d', 20, 'b93482d5-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b937e246-6fc4-11ec-b831-482ae33c4a2d', 50, 'b937e25d-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b93be2dd-6fc4-11ec-b831-482ae33c4a2d', 100, 'b93be2f9-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b93f2d68-6fc4-11ec-b831-482ae33c4a2d', 130, 'b93f2d7d-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b9451b98-6fc4-11ec-b831-482ae33c4a2d', 30, 'b9451bcc-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b9488ec1-6fc4-11ec-b831-482ae33c4a2d', 560, 'b9488edb-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b94be6e6-6fc4-11ec-b831-482ae33c4a2d', 10, 'b94be6ff-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b94ee10d-6fc4-11ec-b831-482ae33c4a2d', 123, 'b94ee12c-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b952492a-6fc4-11ec-b831-482ae33c4a2d', 145, 'b9524945-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b95553ac-6fc4-11ec-b831-482ae33c4a2d', 543, 'b95553c8-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b9581cdd-6fc4-11ec-b831-482ae33c4a2d', 17, 'b9581cfa-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b95afc0f-6fc4-11ec-b831-482ae33c4a2d', 18, 'b95afc2a-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b95daa99-6fc4-11ec-b831-482ae33c4a2d', 134, 'b95daab2-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b9667e3c-6fc4-11ec-b831-482ae33c4a2d', 156, 'b9667e60-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b96ab489-6fc4-11ec-b831-482ae33c4a2d', 175, 'b96ab4a5-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b96e2942-6fc4-11ec-b831-482ae33c4a2d', 180, 'b96e295b-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b97092ec-6fc4-11ec-b831-482ae33c4a2d', 123, 'b9709306-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b973727a-6fc4-11ec-b831-482ae33c4a2d', 230, 'b9737293-6fc4-11ec-b831-482ae33c4a2d');
INSERT INTO tb_order (id, money, content) VALUES ('b978840f-6fc4-11ec-b831-482ae33c4a2d', 560, 'b978843c-6fc4-11ec-b831-482ae33c4a2d');
枚舉分片
通過(guò)在配置文件中配置可能的枚舉值,指定數(shù)據(jù)分布到不同數(shù)據(jù)節(jié)點(diǎn)上,本規(guī)則適用于按照省份、性別、狀態(tài)拆分?jǐn)?shù)據(jù)等業(yè)務(wù)
schema.xml邏輯表配置:
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
partition-hash-int.txt:狀態(tài)為1對(duì)應(yīng)第一個(gè)節(jié)點(diǎn)(節(jié)點(diǎn)下標(biāo)從0開(kāi)始),為2對(duì)應(yīng)第二個(gè)節(jié)點(diǎn),為3對(duì)應(yīng)第三個(gè)節(jié)點(diǎn)
1=0
2=1
3=2
分片規(guī)則配置屬性含義:
重啟,創(chuàng)建表插入數(shù)據(jù):
CREATE TABLE tb_user (
id bigint(20) NOT NULL COMMENT 'ID',
username varchar(200) DEFAULT NULL COMMENT '姓名',
status int(2) DEFAULT '1' COMMENT '1: 未啟用, 2: 已啟用, 3: 已關(guān)閉',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into tb_user (id,username ,status) values(1,'Tom',1);
insert into tb_user (id,username ,status) values(2,'Cat',2);
insert into tb_user (id,username ,status) values(3,'Rose',3);
insert into tb_user (id,username ,status) values(4,'Coco',2);
insert into tb_user (id,username ,status) values(5,'Lily',1);
insert into tb_user (id,username ,status) values(6,'Tom',1);
insert into tb_user (id,username ,status) values(7,'Cat',2);
insert into tb_user (id,username ,status) values(8,'Rose',3);
insert into tb_user (id,username ,status) values(9,'Coco',2);
insert into tb_user (id,username ,status) values(10,'Lily',1);
應(yīng)用指定算法sharding-by-substring
運(yùn)行階段由應(yīng)用自主決定路由到哪個(gè)分片,直接根據(jù)字符子串(必須是數(shù)字)計(jì)算分片號(hào)
?schema.xml邏輯表配置:
!-- 應(yīng)用指定算法 -->
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
分片規(guī)則配置屬性含義:
示例說(shuō)明id=05-100000002 , 在此配置中代表根據(jù)id中從startIndex=0開(kāi)始,截取siz=2位數(shù)字即05,05就是獲取的分區(qū),如果沒(méi)找到對(duì)應(yīng)的分片則默認(rèn)分配到defaultPartition
重啟,創(chuàng)建表插入數(shù)據(jù):
CREATE TABLE tb_app (
id varchar(10) NOT NULL COMMENT 'ID',
name varchar(200) DEFAULT NULL COMMENT '名稱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into tb_app (id,name) values('0000001','Testx00001');
insert into tb_app (id,name) values('0100001','Test100001');
insert into tb_app (id,name) values('0100002','Test200001');
insert into tb_app (id,name) values('0200001','Test300001');
insert into tb_app (id,name) values('0200002','TesT400001');
固定分片hash算法
該算法類似于十進(jìn)制的求模運(yùn)算,但是二進(jìn)制的操作,例如,取id的二進(jìn)制后10位與1111111111進(jìn)行位&運(yùn)算,位&運(yùn)算最小值為0000000000,最大值為1111111111,轉(zhuǎn)換為十進(jìn)制,也就是位于0-1023之間
特點(diǎn):
如果是求模,連續(xù)的值,分別分配到各個(gè)不同的分片;但是此算法會(huì)將連續(xù)的值可能分配到相同的分片,降低事務(wù)處理的難度可以均勻分配,也可以非均勻分配分片字段必須為數(shù)字類型
?schema.xml邏輯表配置:
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
約束:
分片長(zhǎng)度:默認(rèn)最大1024count、length的長(zhǎng)度必須一致
以上分為三個(gè)分區(qū):0-255,256-511,512-1023
分片規(guī)則配置屬性含義:
?示例說(shuō)明:
重啟,創(chuàng)建表插入數(shù)據(jù):
CREATE TABLE tb_longhash (
id int(11) NOT NULL COMMENT 'ID',
name varchar(200) DEFAULT NULL COMMENT '名稱',
firstChar char(1) COMMENT '首字母',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into tb_longhash (id,name,firstChar) values(1,'七匹狼','Q');
insert into tb_longhash (id,name,firstChar) values(2,'八匹狼','B');
insert into tb_longhash (id,name,firstChar) values(3,'九匹狼','J');
insert into tb_longhash (id,name,firstChar) values(4,'十匹狼','S');
insert into tb_longhash (id,name,firstChar) values(5,'六匹狼','L');
insert into tb_longhash (id,name,firstChar) values(6,'五匹狼','W');
insert into tb_longhash (id,name,firstChar) values(7,'四匹狼','S');
insert into tb_longhash (id,name,firstChar) values(8,'三匹狼','S');
insert into tb_longhash (id,name,firstChar) values(9,'兩匹狼','L');
字符串hash解析算法
截取字符串中的指定位置的子字符串,進(jìn)行hash算法,算出分片
?schema.xml邏輯表配置:
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
分片規(guī)則配置屬性含義:
示例說(shuō)明:
重啟,創(chuàng)建表插入數(shù)據(jù):
create table tb_strhash(
name varchar(20) primary key,
content varchar(100)
)engine=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO tb_strhash (name,content) VALUES('T1001', UUID());
INSERT INTO tb_strhash (name,content) VALUES('ROSE', UUID());
INSERT INTO tb_strhash (name,content) VALUES('JERRY', UUID());
INSERT INTO tb_strhash (name,content) VALUES('CRISTINA', UUID());
INSERT INTO tb_strhash (name,content) VALUES('TOMCAT', UUID());
按天分片算法
按照日期及對(duì)應(yīng)的時(shí)間周期來(lái)分片
?schema.xml邏輯表配置:
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
分片規(guī)則配置屬性含義:
重啟,創(chuàng)建表插入數(shù)據(jù):
create table tb_datepart(
id bigint not null comment 'ID' primary key,
name varchar(100) null comment '姓名',
create_time date null
);
insert into tb_datepart(id,name ,create_time) values(1,'Tom','2022-01-01');
insert into tb_datepart(id,name ,create_time) values(2,'Cat','2022-01-10');
insert into tb_datepart(id,name ,create_time) values(3,'Rose','2022-01-11');
insert into tb_datepart(id,name ,create_time) values(4,'Coco','2022-01-20');
insert into tb_datepart(id,name ,create_time) values(5,'Rose2','2022-01-21');
insert into tb_datepart(id,name ,create_time) values(6,'Coco2','2022-01-30');
insert into tb_datepart(id,name ,create_time) values(7,'Coco3','2022-01-31');
自然月分片
使用場(chǎng)景為按照月份來(lái)分片,每個(gè)自然月為一個(gè)分片
?schema.xml邏輯表配置:
schema.xml數(shù)據(jù)節(jié)點(diǎn)配置:
rule.xml分片規(guī)則配置:
分片規(guī)則配置屬性含義:
重啟,創(chuàng)建表插入數(shù)據(jù):
create table tb_monthpart(
id bigint not null comment 'ID' primary key,
name varchar(100) null comment '姓名',
create_time date null
);
insert into tb_monthpart(id,name ,create_time) values(1,'Tom','2022-01-01');
insert into tb_monthpart(id,name ,create_time) values(2,'Cat','2022-01-10');
insert into tb_monthpart(id,name ,create_time) values(3,'Rose','2022-01-31');
insert into tb_monthpart(id,name ,create_time) values(4,'Coco','2022-02-20');
insert into tb_monthpart(id,name ,create_time) values(5,'Rose2','2022-02-25');
insert into tb_monthpart(id,name ,create_time) values(6,'Coco2','2022-03-10');
insert into tb_monthpart(id,name ,create_time) values(7,'Coco3','2022-03-31');
insert into tb_monthpart(id,name ,create_time) values(8,'Coco4','2022-04-10');
insert into tb_monthpart(id,name ,create_time) values(9,'Coco5','2022-04-30');
MyCat管理與監(jiān)控
MyCat原理
在MyCat中,當(dāng)執(zhí)行一條SQL語(yǔ)句時(shí),MyCat需要進(jìn)行SQL解析、分片分析、路由分析、讀寫(xiě)分離分析等操作,最終經(jīng)過(guò)一系列的分析決定將當(dāng)前的SQL語(yǔ)句到底路由到哪幾個(gè)(或哪一個(gè))節(jié)點(diǎn)數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)將數(shù)據(jù)執(zhí)行完畢后,如果有返回的結(jié)果,則將結(jié)果返回給MyCat,最終還需要在MyCat中進(jìn)行結(jié)果合并、聚合處理、排序處理、分頁(yè)處理等操作,最終再將結(jié)果返回給客戶端
MyCat官方提供了一個(gè)管理監(jiān)控平臺(tái)MyCat-Web(MyCat-eye),?MyCat-Web是MyCat可視化運(yùn)維的管理和監(jiān)控平臺(tái),彌補(bǔ)了MyCat在監(jiān)控上的空白,幫MyCat分擔(dān)統(tǒng)計(jì)任務(wù)和配置管理任務(wù),MyCat-Web還引入了Zookeeper作為配置中心,可以管理多個(gè)節(jié)點(diǎn)。MyCat-Web主要管理和監(jiān)控MyCat的流量、連接、活動(dòng)線程和內(nèi)存等,具備IP白名單、郵件告警等模塊,還可以統(tǒng)計(jì)SQL并分析慢SQL和高頻SQL等,為優(yōu)化SQL提供依據(jù)
MyCat管理
MyCat默認(rèn)開(kāi)通兩個(gè)端口,可以在server.xml中修改:
8066 數(shù)據(jù)訪問(wèn)端口,即進(jìn)行 DML 和 DDL 操作9066 數(shù)據(jù)庫(kù)管理端口,即 mycat 服務(wù)管理控制功能,用于管理mycat的整個(gè)集群狀態(tài)
連接MyCat的管理控制臺(tái):
mysql -h 192.168.200.210 -p 9066 -uroot -p123456
MyCat-eye
MyCat-eye(MyCat-web)是對(duì)mycat-server提供監(jiān)控服務(wù),功能不局限于對(duì)mycat-server使用,它通過(guò)JDBC連接對(duì)MyCat、MySQL監(jiān)控,監(jiān)控遠(yuǎn)程服務(wù)器(目前僅限于Linux系統(tǒng))的cpu、內(nèi)存、網(wǎng)絡(luò)、磁盤(pán)
MyCat-eye運(yùn)行過(guò)程中需要依賴zookeeper
安裝MyCat-eye和zookeeper
訪問(wèn):
配置,開(kāi)啟MyCat的實(shí)時(shí)統(tǒng)計(jì)功能(server.xml):
在MyCat監(jiān)控界面配置服務(wù)地址:
通過(guò)MyCat執(zhí)行一系列的增刪改查的測(cè)試,過(guò)一段時(shí)間后打開(kāi),查看MyCat-eye監(jiān)控到的數(shù)據(jù)信息
性能監(jiān)控:
物理節(jié)點(diǎn):
SQL統(tǒng)計(jì):
SQL表分析:
SQL監(jiān)控:
高頻SQL:
柚子快報(bào)激活碼778899分享:數(shù)據(jù)庫(kù) MySQL-分庫(kù)分表
相關(guān)閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。