詳解如何使用MongoDB+Springboot實現(xiàn)分布式ID的方法
一、背景
如何實現(xiàn)分布式id,搜索相關(guān)的資料,一般會給出這幾種方案:
- 使用數(shù)據(jù)庫自增Id
- 使用reids的incr命令
- 使用UUID
- Twitter的snowflake算法
- 利用zookeeper生成唯一ID
- MongoDB的ObjectId
另外,在我通過爬取知乎用戶id發(fā)現(xiàn),知乎的用戶id是32位的,初步斷定知乎采用的是md5加密,然后全部轉(zhuǎn)換成小寫。至于如何爬取知乎用戶信息,見我之前分享的文章。本文采取的技術(shù)方案采取的是mogoodb的objectId。
二.mongodb如何實現(xiàn)分布式ID
MongoDB的ObjectId設(shè)計成輕量型的,不同的機器都能用全局唯一的同種方法方便地生成它。MongoDB 從一開始就設(shè)計用來作為分布式數(shù)據(jù)庫,處理多個節(jié)點是一個核心要求。使其在分片環(huán)境中要容易生成得多。
它的格式:
前4 個字節(jié)是從標(biāo)準(zhǔn)紀元開始的時間戳,單位為秒。時間戳,與隨后的5 個字節(jié)組合起來,提供了秒級別的唯一性。由于時間戳在前,這意味著ObjectId 大致會按照插入的順序排列。這對于某些方面很有用,如將其作為索引提高效率。這4 個字節(jié)也隱含了文檔創(chuàng)建的時間。絕大多數(shù)客戶端類庫都會公開一個方法從ObjectId 獲取這個信息。
接下來的3 字節(jié)是所在主機的唯一標(biāo)識符。通常是機器主機名的散列值。這樣就可以確保不同主機生成不同的ObjectId,不產(chǎn)生沖突。
為了確保在同一臺機器上并發(fā)的多個進程產(chǎn)生的ObjectId 是唯一的,接下來的兩字節(jié)來自產(chǎn)生ObjectId 的進程標(biāo)識符(PID)。
前9 字節(jié)保證了同一秒鐘不同機器不同進程產(chǎn)生的ObjectId 是唯一的。
后3 字節(jié)就是一個自動增加的計數(shù)器,確保相同進程同一秒產(chǎn)生的ObjectId 也是不一樣的。同一秒鐘最多允許每個進程擁有2563(16 777 216)個不同的ObjectId。
三、編碼
在springboot中引入mongodb:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 開啟web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--mongodb --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
創(chuàng)建一個實體類:
public class Customer { @Id public String id; public String firstName; public String lastName; public Customer() {} public Customer(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } @Override public String toString() { return String.format( "Customer[id=%s, firstName='%s', lastName='%s']", id, firstName, lastName); } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
創(chuàng)建mongodb 接口類:
/** * Created by fangzhipeng on 2017/4/1. */ public interface CustomerRepository extends MongoRepository<Customer, String> { public Customer findByFirstName(String firstName); public List<Customer> findByLastName(String lastName); }
測試類:
@Autowired CustomerRepository customerRepository; @Test public void mongodbIdTest(){ Customer customer=new Customer("lxdxil","dd"); customer=customerRepository.save(customer); logger.info( "mongodbId:"+customer.getId()); }
四、參考資料
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Mybatis 動態(tài)SQL搭建環(huán)境的全過程
這篇文章主要給大家介紹了關(guān)于Mybatis動態(tài)SQL搭建環(huán)境的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05SpringAMQP消息隊列(SpringBoot集成RabbitMQ方式)
這篇文章主要介紹了SpringAMQP消息隊列(SpringBoot集成RabbitMQ方式),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04使用Logback設(shè)置property參數(shù)方式
這篇文章主要介紹了使用Logback設(shè)置property參數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03SpringBoot的Security和OAuth2的使用示例小結(jié)
這篇文章主要介紹了SpringBoot的Security和OAuth2的使用,本文通過示例圖文相結(jié)合給大家講解的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-06-06