柚子快報邀請碼778899分享:分布式ID的使用
柚子快報邀請碼778899分享:分布式ID的使用
1.背景
分布式id(Distributed ID)可以用來唯一標(biāo)識分布式系統(tǒng)中的各個實體、任務(wù)或請求。它可以用于多種用途,包括以下幾個方面:
1. 數(shù)據(jù)庫主鍵:在分布式數(shù)據(jù)庫中,每個數(shù)據(jù)記錄需要一個唯一的主鍵標(biāo)識。分布式id可以用作主鍵,確保數(shù)據(jù)記錄的唯一性。
2. 分布式鎖:在分布式系統(tǒng)中,多個節(jié)點之間需要共享鎖來實現(xiàn)同步和互斥。分布式id可以作為鎖的名稱,確保每個節(jié)點使用的鎖是唯一的。
3. 分布式消息隊列:在消息隊列系統(tǒng)中,分布式id可以用來標(biāo)識消息的發(fā)送和接收狀態(tài),以便進行消息的可靠傳輸和處理。
4. 分布式事務(wù):在分布式事務(wù)中,分布式id可以用來標(biāo)識事務(wù)的唯一性,確保事務(wù)的一致性和隔離性。
5. 分布式任務(wù)調(diào)度:在分布式任務(wù)調(diào)度系統(tǒng)中,分布式id可以用來標(biāo)識任務(wù)的唯一性,確保任務(wù)的正確執(zhí)行和結(jié)果的正確處理。
總之,分布式id可以在分布式系統(tǒng)中實現(xiàn)唯一標(biāo)識、數(shù)據(jù)一致性、任務(wù)調(diào)度等功能,提高系統(tǒng)的可靠性和性能。
這里我們采用美團的leaf算法來實現(xiàn)分布式的唯一ID
2.號段模式
官方很懶,到現(xiàn)在還沒有上傳maven倉庫,需要手動git下來。
git clone git@github.com:Meituan-Dianping/Leaf.git
git checkout feature/spring-boot-starter
cd Leaf
mvn clean install -Dmaven.test.skip=true
2.1依賴引入
2.2sql執(zhí)行
CREATE DATABASE leaf
CREATE TABLE `leaf_alloc` (
`biz_tag` varchar(128) NOT NULL DEFAULT '',
`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;
insert into leaf_alloc(biz_tag, max_id, step, description) values('leaf-segment-test', 1, 2000, 'Test leaf Segment Mode Get Id')
2.3?使用
1.在resources文件下創(chuàng)建一個leaf.properties
leaf.name=com.sankuai.leaf.opensource.test
leaf.segment.enable=true
leaf.segment.url=jdbc:mysql://localhost:3306/leaf
leaf.segment.username=root
leaf.segment.password=123456
2.主函數(shù)引入@EnableLeafServer注解
package com.mikey.distributed;
import com.sankuai.inf.leaf.plugin.annotation.EnableLeafServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author mikey
* @create 2024-03-03 21:21
*/
@SpringBootApplication
@EnableLeafServer
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
3.實際應(yīng)用
@RestController
public class IdController {
@Autowired
private SegmentService segmentService;
@GetMapping("/segment")
public Result getId1() {
return segmentService.getId("leaf-segment-test");
}
}
2.4總結(jié)
Leaf 最早期需求是各個業(yè)務(wù)線的訂單ID生成需求。在美團早期,有的業(yè)務(wù)直接通過DB自增的方式生成ID,有的業(yè)務(wù)通過redis緩存來生成ID,也有的業(yè)務(wù)直接用UUID這種方式來生成ID。以上的方式各自有各自的問題,因此我們決定實現(xiàn)一套分布式ID生成服務(wù)來滿足需求。(來自官網(wǎng))
我們會發(fā)現(xiàn)在獲取id的時候,需要一個key,這個key實際就是數(shù)據(jù)庫的biz_tag這個字段,代表著業(yè)務(wù)的標(biāo)簽。max_id就是這次請求拿到的id,step就是步長。
假設(shè)此時數(shù)據(jù)庫是? max_id = 1 , step = 20。
那么這次請求拿到的id就是1,然后他會緩存這1-20的id,下一次請求而不會請求數(shù)據(jù)庫,而是從緩存里面拿,這里就是他性能高的原因。你會發(fā)現(xiàn)當(dāng)你請求多幾次的時候,而id還沒到20,數(shù)據(jù)庫的max_id更新到了21,這是因為他會提前去申請id空間,防止id不夠,而提前做了數(shù)據(jù)庫更新。
3.雪花算法
雪花算法(Snowflake Algorithm)是一種用于生成分布式系統(tǒng)中唯一 ID 的算法。
64 位二進制格式:Snowflake 算法生成的唯一 ID 是一個 64 位的整數(shù),其結(jié)構(gòu)一般是:1位符號位(不使用)、41位的時間戳、10位的機器標(biāo)識(或工作機器 ID)、12位的序列號。 時間戳部分:占據(jù)了整個 64 位中的高位 41 位,可以精確到毫秒級別的時間,可以保證在相同的時間戳內(nèi)生成的 ID 唯一。 機器標(biāo)識部分:占據(jù)了中間的 10 位,用于區(qū)分不同的機器。這部分的信息可以手動配置或者從機器的某些特征中提取,例如數(shù)據(jù)中心 ID 和機器 ID 的組合。 序列號部分:占據(jù)了低位的 12 位,用于解決在同一毫秒內(nèi)產(chǎn)生大量請求時的并發(fā)沖突問題。在同一毫秒內(nèi),序列號會從 0 開始遞增,最多可以生成 4096(2^12)個不同的 ID。 生成 ID 的規(guī)則:Snowflake 算法根據(jù)當(dāng)前時間戳、機器標(biāo)識和序列號生成唯一的 ID。當(dāng)某個節(jié)點生成 ID 時,它會根據(jù)當(dāng)前時間戳計算出時間戳部分,將機器標(biāo)識和序列號部分組合成 ID。
實際上不同的公司都會根據(jù)自己的場景從而去改造雪花算法,可以從時間戳部分或者機器表示部分或者序列號部分去優(yōu)化,可以參考一下百度UidGenerator。
3.1依賴引入
這里需要引入zk的相關(guān)依賴,可以理解成zk在這里做了數(shù)據(jù)庫這樣的角色,存儲了機器的標(biāo)識符(ip)。這里不展開zk的安裝,自行查看相關(guān)資料。
3.2使用
1.在resources文件下創(chuàng)建一個leaf.properties
leaf.name=com.sankuai.leaf.opensource.test
leaf.snowflake.enable=false
leaf.snowflake.address=ip
leaf.snowflake.port=port
2.使用
@Autowired
private SnowflakeService snowflakeService;
@GetMapping("/snowflake")
public Result getId2() {
return snowflakeService.getId("111");
}
我們可以發(fā)現(xiàn)雪花算法這里也要獲取一個key,實際上這里的key是沒有意義的。看看github上的解釋。
柚子快報邀請碼778899分享:分布式ID的使用
精彩鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。