您好,登錄后才能下訂單哦!
數(shù)據(jù)量上來后,單庫單表承受不住的時(shí)候,我們就需要引入分庫分表。 但是分庫分表后,主鍵id就不能依賴于MySQL,需要從外部去獲取id。
目前我們生產(chǎn)環(huán)境在用的DBLE作為中分庫分表中間件, 其自帶了類似snowflake方案的全局id生成器,也可以基于數(shù)據(jù)庫來實(shí)現(xiàn)。
但是,在一個(gè)大點(diǎn)的公司里面, 全局id 是一個(gè)用處很廣泛的服務(wù),通常會(huì)獨(dú)立作為一個(gè)公共服務(wù)對(duì)外提供。
這里我們就以 美團(tuán)點(diǎn)評(píng)出的 Leaf為例,看下它的效果。
相關(guān)文檔:
https://tech.meituan.com/2019/03/07/open-source-project-leaf.html
https://tech.meituan.com/2017/04/21/mt-leaf.html
https://blog.csdn.net/bskfnvjtlyzmv867/article/details/90175306? 源碼詳解
官方的2篇文檔,介紹的很詳細(xì)了,我們就不啰嗦了。
下面的演示,是基于數(shù)據(jù)庫做id分發(fā) (數(shù)據(jù)庫的SLA可以使用MHA、pxc或mgr來保證)
0 環(huán)境
OS版本:? CentOS7
node1 IP: 192.168.20.10
node2 IP: 192.168.20.17
MySQL地址: 192.168.20.10
1 創(chuàng)建數(shù)據(jù)庫表等
CREATE?DATABASE?leaf?; use?leaf?; CREATE?TABLE?`leaf_alloc`?( ??`biz_tag`?varchar(128)??NOT?NULL?DEFAULT?'',?--?your?biz?unique?name ??`max_id`?bigint(20)?NOT?NULL?DEFAULT?'1', ??`step`?int(11)?NOT?NULL, ??`description`?varchar(256)??DEFAULT?NULL, ??`update_time`?timestamp?NOT?NULL?DEFAULT?CURRENT_TIMESTAMP?ON?UPDATE?CURRENT_TIMESTAMP, ??PRIMARY?KEY?(`biz_tag`) )?ENGINE=InnoDB; --?插入幾條需要分發(fā)id的服務(wù)的標(biāo)識(shí)(我這里在默認(rèn)的基礎(chǔ)上,加了?卡券id、帖子id?這2個(gè)例子) insert?into?leaf_alloc(biz_tag,?max_id,?step,?description)?values('leaf-segment-test',?1,?2000,?'Test?leaf?Segment?Mode?Get?Id'); insert?into?leaf_alloc(biz_tag,?max_id,?step,?description)?values('coupon',?1,?2000,?'Get?coupon?Id'); insert?into?leaf_alloc(biz_tag,?max_id,?step,?description)?values('tid',?1,?1000,?'Get?tiezi?id'); select?*?from?leaf_alloc?; +-------------------+--------+------+-------------------------------+---------------------+ |?biz_tag???????????|?max_id?|?step?|?description???????????????????|?update_time?????????| +-------------------+--------+------+-------------------------------+---------------------+ |?coupon????????????|??????1?|?2000?|?Get?coupon?Id?????????????????|?2019-10-12?17:47:23?| |?leaf-segment-test?|??????1?|?2000?|?Test?leaf?Segment?Mode?Get?Id?|?2019-10-12?17:47:00?| |?tid???????????????|??????1?|?1000?|?Get?tiezi?id??????????????????|?2019-10-12?17:48:21?| +-------------------+--------+------+-------------------------------+---------------------+ 3?rows?in?set?(0.001?sec) --?創(chuàng)建獨(dú)立的數(shù)據(jù)庫賬號(hào) create?user?leaf@'%'?identified?by?'leaf1234'; grant?select,update,delete,insert?on?leaf.*?to?leaf@'%';
2 編譯leaf-server
注意:需要在node1和node2上單獨(dú)執(zhí)行編譯和啟動(dòng)的操作,編譯+啟動(dòng) 依賴到 maven 和 oracle-jdk
cd?/usr/local/ git?clone?https://github.com/Meituan-Dianping/Leaf.git cd?leaf mvn?clean?install?-DskipTests cd?leaf-server
vim leaf-server/src/main/resources/leaf.properties? 修改配置文件中數(shù)據(jù)庫的連接方式
leaf.name=com.sankuai.leaf.opensource.test leaf.segment.enable=true leaf.jdbc.url=jdbc:mysql://192.168.20.10:3306/leaf?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8 leaf.jdbc.username=leaf leaf.jdbc.password=leaf1234 leaf.snowflake.enable=false #leaf.snowflake.zk.address= #leaf.snowflake.port=
3 啟動(dòng)leaf-server:
cd?/usr/local/leaf/leaf-server mvn?spring-boot:run
4 測(cè)試
測(cè)試我上面插入的3個(gè)biz_tag的發(fā)號(hào)器情況:
? ? curl http://192.168.20.10:8080/api/segment/get/leaf-segment-test
? ? curl http://192.168.20.10:8080/api/segment/get/coupon
? ? curl
http://192.168.20.10:8080/api/segment/get/tid5 其它
號(hào)段模式自帶了個(gè)監(jiān)控界面:? ?
http://192.168.20.10:8080/cache測(cè)試id的生成效果:
for?i?in?{1..2000};?do??curl?http://192.168.20.17:8080/api/segment/get/coupon;?done for?i?in?{1..2000};?do??curl?http://192.168.20.10:8080/api/segment/get/coupon;?done
然后,我們?cè)趂or循環(huán)獲取id的時(shí)候,人為的把MySQL關(guān)閉掉,可以看到如下的,可以看到剛開始leaf因?yàn)樘?hào)段+雙buffer的存在,可以繼續(xù)發(fā)號(hào),但是當(dāng)預(yù)分配的id都用光后,就會(huì)報(bào)錯(cuò)了:
只要我們的MySQL數(shù)據(jù)庫故障切換的時(shí)候不要太久,并且配合設(shè)置不同biz_tag以不同大小的step,通不會(huì)對(duì)對(duì)leaf服務(wù)造成影響。
下面是雙buffer在web界面上的體現(xiàn):
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。