偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

分庫分表的 9種分布式主鍵ID 生成方案,挺全乎的

運(yùn)維 數(shù)據(jù)庫運(yùn)維 分布式
引入任何一種技術(shù)都是存在風(fēng)險的,分庫分表當(dāng)然也不例外,除非庫、表數(shù)據(jù)量持續(xù)增加,大到一定程度,以至于現(xiàn)有高可用架構(gòu)已無法支撐,否則不建議大家做分庫分表,因?yàn)樽隽藬?shù)據(jù)分片后,你會發(fā)現(xiàn)自己踏上了一段踩坑之路,而分布式主鍵 ID 就是遇到的第一個坑。

 [[351290]]

本文轉(zhuǎn)載自微信公眾號「 程序員內(nèi)點(diǎn)事」,作者 程序員內(nèi)點(diǎn)事。轉(zhuǎn)載本文請聯(lián)系 程序員內(nèi)點(diǎn)事公眾號。

引入任何一種技術(shù)都是存在風(fēng)險的,分庫分表當(dāng)然也不例外,除非庫、表數(shù)據(jù)量持續(xù)增加,大到一定程度,以至于現(xiàn)有高可用架構(gòu)已無法支撐,否則不建議大家做分庫分表,因?yàn)樽隽藬?shù)據(jù)分片后,你會發(fā)現(xiàn)自己踏上了一段踩坑之路,而分布式主鍵 ID 就是遇到的第一個坑。

不同數(shù)據(jù)節(jié)點(diǎn)間生成全局唯一主鍵是個棘手的問題,一張邏輯表 t_order 拆分成多個真實(shí)表 t_order_n,然后被分散到不同分片庫 db_0、db_1... ,各真實(shí)表的自增鍵由于無法互相感知從而會產(chǎn)生重復(fù)主鍵,此時數(shù)據(jù)庫本身的自增主鍵,就無法滿足分庫分表對主鍵全局唯一的要求。

  1. db_0-- 
  2.    |-- t_order_0 
  3.    |-- t_order_1 
  4.    |-- t_order_2 
  5. db_1-- 
  6.    |-- t_order_0 
  7.    |-- t_order_1 
  8.    |-- t_order_2 

盡管我們可以通過嚴(yán)格約束,各個分片表自增主鍵的 初始值 和 步長 的方式來解決 ID 重復(fù)的問題,但這樣會讓運(yùn)維成本陡增,而且可擴(kuò)展性極差,一旦要擴(kuò)容分片表數(shù)量,原表數(shù)據(jù)變動比較大,所以這種方式不太可取。

  1. 步長 step = 分表張數(shù) 
  2.  
  3. db_0-- 
  4.    |-- t_order_0  ID: 0、6、12、18... 
  5.    |-- t_order_1  ID: 1、7、13、19... 
  6.    |-- t_order_2  ID: 2、8、14、20... 
  7. db_1-- 
  8.    |-- t_order_0  ID: 3、9、15、21... 
  9.    |-- t_order_1  ID: 4、10、16、22... 
  10.    |-- t_order_2  ID: 5、11、17、23... 

目前已經(jīng)有了許多第三放解決方案可以完美解決這個問題,比如基于 UUID、SNOWFLAKE算法 、segment號段,使用特定算法生成不重復(fù)鍵,或者直接引用主鍵生成服務(wù),像美團(tuán)(Leaf)和 滴滴(TinyId)等。

而sharding-jdbc 內(nèi)置了兩種分布式主鍵生成方案,UUID、SNOWFLAKE,不僅如此它還抽離出分布式主鍵生成器的接口,以便于開發(fā)者實(shí)現(xiàn)自定義的主鍵生成器,后續(xù)我們會在自定義的生成器中接入 滴滴(TinyId)的主鍵生成服務(wù)。

前邊介紹過在 sharding-jdbc 中要想為某個字段自動生成主鍵 ID,只需要在 application.properties 文件中做如下配置:

  1. # 主鍵字段 
  2. spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id 
  3. # 主鍵ID 生成方案 
  4. spring.shardingsphere.sharding.tables.t_order.key-generator.type=UUID 
  5. # 工作機(jī)器 id 
  6. spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=123 

key-generator.column 表示主鍵字段,key-generator.type 為主鍵 ID 生成方案(內(nèi)置或自定義的),key-generator.props.worker.id 為機(jī)器ID,在主鍵生成方案設(shè)為 SNOWFLAKE 時機(jī)器ID 會參與位運(yùn)算。

在使用 sharding-jdbc 分布式主鍵時需要注意兩點(diǎn):

  • 一旦 insert 插入操作的實(shí)體對象中主鍵字段已經(jīng)賦值,那么即使配置了主鍵生成方案也會失效,最后SQL 執(zhí)行的數(shù)據(jù)會以賦的值為準(zhǔn)。
  • 不要給主鍵字段設(shè)置自增屬性,否則主鍵ID 會以默認(rèn)的 SNOWFLAKE 方式生成。比如:用 mybatis plus 的 @TableId 注解給字段 order_id 設(shè)置了自增主鍵,那么此時配置哪種方案,總是按雪花算法生成。
  • 下面我們從源碼上分析下 sharding-jdbc 內(nèi)置主鍵生成方案 UUID、SNOWFLAKE 是怎么實(shí)現(xiàn)的。

UUID

打開 UUID 類型的主鍵生成實(shí)現(xiàn)類 UUIDShardingKeyGenerator 的源碼發(fā)現(xiàn),它的生成規(guī)則只有 UUID.randomUUID() 這么一行代碼,額~ 心中默默來了一句臥槽。

UUID 雖然可以做到全局唯一性,但還是不推薦使用它作為主鍵,因?yàn)槲覀兊膶?shí)際業(yè)務(wù)中不管是 user_id 還是 order_id 主鍵多為整型,而 UUID 生成的是個 32 位的字符串。

它的存儲以及查詢對 MySQL 的性能消耗較大,而且 MySQL 官方也明確建議,主鍵要盡量越短越好,作為數(shù)據(jù)庫主鍵 UUID 的無序性還會導(dǎo)致數(shù)據(jù)位置頻繁變動,嚴(yán)重影響性能。

  1. public final class UUIDShardingKeyGenerator implements ShardingKeyGenerator { 
  2.     private Properties properties = new Properties(); 
  3.  
  4.     public UUIDShardingKeyGenerator() { 
  5.     } 
  6.  
  7.     public String getType() { 
  8.         return "UUID"
  9.     } 
  10.  
  11.     public synchronized Comparable<?> generateKey() { 
  12.         return UUID.randomUUID().toString().replaceAll("-"""); 
  13.     } 
  14.  
  15.     public Properties getProperties() { 
  16.         return this.properties; 
  17.     } 
  18.  
  19.     public void setProperties(Properties properties) { 
  20.         this.properties = properties; 
  21.     } 

SNOWFLAKE

SNOWFLAKE(雪花算法)是默認(rèn)使用的主鍵生成方案,生成一個 64bit的長整型(Long)數(shù)據(jù)。

sharding-jdbc 中雪花算法生成的主鍵主要由 4部分組成,1bit符號位、41bit時間戳位、10bit工作進(jìn)程位以及 12bit 序列號位。

符號位(1bit位)

Java 中 Long 型的最高位是符號位,正數(shù)是0,負(fù)數(shù)是1,一般生成ID都為正數(shù),所以默認(rèn)為0

時間戳位(41bit)

41位的時間戳可以容納的毫秒數(shù)是 2 的 41次冪,而一年的總毫秒數(shù)為 1000L * 60 * 60 * 24 * 365,計算使用時間大概是69年,額~,我有生之間算是夠用了。

  1. Math.pow(2, 41) / (365 * 24 * 60 * 60 * 1000L) = = 69年  

工作進(jìn)程位(10bit)

表示一個唯一的工作進(jìn)程id,默認(rèn)值為 0,可通過 key-generator.props.worker.id 屬性設(shè)置。

  1. spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=0000 

序列號位(12bit)

同一毫秒內(nèi)生成不同的ID。

時鐘回?fù)?/strong>

了解了雪花算法的主鍵 ID 組成后不難發(fā)現(xiàn),這是一種嚴(yán)重依賴于服務(wù)器時間的算法,而依賴服務(wù)器時間的就會遇到一個棘手的問題:時鐘回?fù)堋?/p>

為什么會出現(xiàn)時鐘回?fù)苣?

互聯(lián)網(wǎng)中有一種網(wǎng)絡(luò)時間協(xié)議 ntp 全稱 (Network Time Protocol) ,專門用來同步、校準(zhǔn)網(wǎng)絡(luò)中各個計算機(jī)的時間。

這就是為什么,我們的手機(jī)現(xiàn)在不用手動校對時間,可每個人的手機(jī)時間還都是一樣的。

我們的硬件時鐘可能會因?yàn)楦鞣N原因變得不準(zhǔn)( 快了 或 慢了 ),此時就需要 ntp 服務(wù)來做時間校準(zhǔn),做校準(zhǔn)的時候就會發(fā)生服務(wù)器時鐘的 跳躍 或者 回?fù)? 的問題。

雪花算法如何解決時鐘回?fù)?/strong>

服務(wù)器時鐘回?fù)軙?dǎo)致產(chǎn)生重復(fù)的 ID,SNOWFLAKE 方案中對原有雪花算法做了改進(jìn),增加了一個最大容忍的時鐘回?fù)芎撩霐?shù)。

如果時鐘回?fù)艿臅r間超過最大容忍的毫秒數(shù)閾值,則程序直接報錯;如果在可容忍的范圍內(nèi),默認(rèn)分布式主鍵生成器,會等待時鐘同步到最后一次主鍵生成的時間后再繼續(xù)工作。

最大容忍的時鐘回?fù)芎撩霐?shù),默認(rèn)值為 0,可通過屬性 max.tolerate.time.difference.milliseconds 設(shè)置。

  1. # 最大容忍的時鐘回?fù)芎撩霐?shù) 
  2. spring.shardingsphere.sharding.tables.t_order.key-generator.max.tolerate.time.difference.milliseconds=5 

下面是看下它的源碼實(shí)現(xiàn)類 SnowflakeShardingKeyGenerator,核心流程大概如下:

最后一次生成主鍵的時間 lastMilliseconds 與 當(dāng)前時間currentMilliseconds 做比較,如果 lastMilliseconds > currentMilliseconds則意味著時鐘回調(diào)了。

那么接著判斷兩個時間的差值(timeDifferenceMilliseconds)是否在設(shè)置的最大容忍時間閾值 max.tolerate.time.difference.milliseconds內(nèi),在閾值內(nèi)則線程休眠差值時間 Thread.sleep(timeDifferenceMilliseconds),否則大于差值直接報異常。

  1. /** 
  2.  * @author xiaofu 
  3.  */ 
  4. public final class SnowflakeShardingKeyGenerator implements ShardingKeyGenerator{ 
  5.     @Getter 
  6.     @Setter 
  7.     private Properties properties = new Properties(); 
  8.      
  9.     public String getType() { 
  10.         return "SNOWFLAKE"
  11.     } 
  12.      
  13.     public synchronized Comparable<?> generateKey() { 
  14.      /** 
  15.       * 當(dāng)前系統(tǒng)時間毫秒數(shù)  
  16.       */  
  17.         long currentMilliseconds = timeService.getCurrentMillis(); 
  18.         /** 
  19.          * 判斷是否需要等待容忍時間差,如果需要,則等待時間差過去,然后再獲取當(dāng)前系統(tǒng)時間  
  20.          */  
  21.         if (waitTolerateTimeDifferenceIfNeed(currentMilliseconds)) { 
  22.             currentMilliseconds = timeService.getCurrentMillis(); 
  23.         } 
  24.         /** 
  25.          * 如果最后一次毫秒與 當(dāng)前系統(tǒng)時間毫秒相同,即還在同一毫秒內(nèi)  
  26.          */ 
  27.         if (lastMilliseconds == currentMilliseconds) { 
  28.          /** 
  29.           * &位與運(yùn)算符:兩個數(shù)都轉(zhuǎn)為二進(jìn)制,如果相對應(yīng)位都是1,則結(jié)果為1,否則為0 
  30.           * 當(dāng)序列為4095時,4095+1后的新序列與掩碼進(jìn)行位與運(yùn)算結(jié)果是0 
  31.           * 當(dāng)序列為其他值時,位與運(yùn)算結(jié)果都不會是0 
  32.           * 即本毫秒的序列已經(jīng)用到最大值4096,此時要取下一個毫秒時間值 
  33.           */ 
  34.             if (0L == (sequence = (sequence + 1) & SEQUENCE_MASK)) { 
  35.                 currentMilliseconds = waitUntilNextTime(currentMilliseconds); 
  36.             } 
  37.         } else { 
  38.          /** 
  39.           * 上一毫秒已經(jīng)過去,把序列值重置為1  
  40.           */ 
  41.             vibrateSequenceOffset(); 
  42.             sequence = sequenceOffset; 
  43.         } 
  44.         lastMilliseconds = currentMilliseconds; 
  45.          
  46.         /** 
  47.          * XX......XX XX000000 00000000 00000000 時間差 XX 
  48.          *    XXXXXX XXXX0000 00000000 機(jī)器ID XX 
  49.          *               XXXX XXXXXXXX 序列號 XX 
  50.          *  三部分進(jìn)行|位或運(yùn)算:如果相對應(yīng)位都是0,則結(jié)果為0,否則為1 
  51.          */ 
  52.         return ((currentMilliseconds - EPOCH) << TIMESTAMP_LEFT_SHIFT_BITS) | (getWorkerId() << WORKER_ID_LEFT_SHIFT_BITS) | sequence
  53.     } 
  54.      
  55.     /** 
  56.      * 判斷是否需要等待容忍時間差 
  57.      */ 
  58.     @SneakyThrows 
  59.     private boolean waitTolerateTimeDifferenceIfNeed(final long currentMilliseconds) { 
  60.      /** 
  61.       * 如果獲取ID時的最后一次時間毫秒數(shù)小于等于當(dāng)前系統(tǒng)時間毫秒數(shù),屬于正常情況,則不需要等待  
  62.       */ 
  63.         if (lastMilliseconds <= currentMilliseconds) { 
  64.             return false
  65.         } 
  66.         /** 
  67.          * ===>時鐘回?fù)艿那闆r(生成序列的時間大于當(dāng)前系統(tǒng)的時間),需要等待時間差  
  68.          */ 
  69.         /** 
  70.          * 獲取ID時的最后一次毫秒數(shù)減去當(dāng)前系統(tǒng)時間毫秒數(shù)的時間差  
  71.          */ 
  72.         long timeDifferenceMilliseconds = lastMilliseconds - currentMilliseconds; 
  73.         /** 
  74.          * 時間差小于最大容忍時間差,即當(dāng)前還在時鐘回?fù)艿臅r間差之內(nèi)  
  75.          */ 
  76.         Preconditions.checkState(timeDifferenceMilliseconds < getMaxTolerateTimeDifferenceMilliseconds(),  
  77.                 "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", lastMilliseconds, currentMilliseconds); 
  78.         /** 
  79.          * 線程休眠時間差  
  80.          */ 
  81.         Thread.sleep(timeDifferenceMilliseconds); 
  82.         return true
  83.     } 
  84.      
  85.     // 配置的機(jī)器ID 
  86.     private long getWorkerId() { 
  87.         long result = Long.valueOf(properties.getProperty("worker.id", String.valueOf(WORKER_ID))); 
  88.         Preconditions.checkArgument(result >= 0L && result < WORKER_ID_MAX_VALUE); 
  89.         return result; 
  90.     } 
  91.      
  92.     private int getMaxTolerateTimeDifferenceMilliseconds() { 
  93.         return Integer.valueOf(properties.getProperty("max.tolerate.time.difference.milliseconds", String.valueOf(MAX_TOLERATE_TIME_DIFFERENCE_MILLISECONDS))); 
  94.     } 
  95.      
  96.     private long waitUntilNextTime(final long lastTime) { 
  97.         long result = timeService.getCurrentMillis(); 
  98.         while (result <= lastTime) { 
  99.             result = timeService.getCurrentMillis(); 
  100.         } 
  101.         return result; 
  102.     } 

但從 SNOWFLAKE 方案生成的主鍵ID 來看,order_id 它是一個18位的長整型數(shù)字,是不是發(fā)現(xiàn)它太長了,想要 MySQL 那種從 0 遞增的自增主鍵該怎么實(shí)現(xiàn)呢?別急,后邊已經(jīng)會給出了解決辦法!

自定義

sharding-jdbc 利用 SPI 全稱( Service Provider Interface) 機(jī)制拓展主鍵生成規(guī)則,這是一種服務(wù)發(fā)現(xiàn)機(jī)制,通過掃描項目路徑 META-INF/services 下的文件,并自動加載文件里所定義的類。

實(shí)現(xiàn)自定義主鍵生成器其實(shí)比較簡單,只有兩步。

第一步,實(shí)現(xiàn) ShardingKeyGenerator 接口,并重寫其內(nèi)部方法,其中 getType() 方法為自定義的主鍵生產(chǎn)方案類型、generateKey() 方法則是具體生成主鍵的規(guī)則。

下面代碼中用 AtomicInteger 來模擬實(shí)現(xiàn)一個有序自增的 ID 生成。

  1. /** 
  2.  * @Author: xiaofu 
  3.  * @Description: 自定義主鍵生成器 
  4.  */ 
  5. @Component 
  6. public class MyShardingKeyGenerator implements ShardingKeyGenerator { 
  7.  
  8.  
  9.     private final AtomicInteger count = new AtomicInteger(); 
  10.  
  11.     /** 
  12.      * 自定義的生成方案類型 
  13.      */ 
  14.     @Override 
  15.     public String getType() { 
  16.         return "XXX"
  17.     } 
  18.  
  19.     /** 
  20.      * 核心方法-生成主鍵ID 
  21.      */ 
  22.     @Override 
  23.     public Comparable<?> generateKey() { 
  24.         return count.incrementAndGet(); 
  25.     } 
  26.  
  27.     @Override 
  28.     public Properties getProperties() { 
  29.         return null
  30.     } 
  31.  
  32.     @Override 
  33.     public void setProperties(Properties properties) { 
  34.  
  35.     } 

第二步,由于是利用 SPI 機(jī)制實(shí)現(xiàn)功能拓展,我們要在 META-INF/services 文件中配置自定義的主鍵生成器類路勁。

  1. com.xiaofu.sharding.key.MyShardingKeyGenerator 

上面這些弄完我們測試一下,配置定義好的主鍵生成類型 XXX,并插入幾條數(shù)據(jù)看看效果。

  1. spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id 
  2. spring.shardingsphere.sharding.tables.t_order.key-generator.type=XXX 

通過控制臺的SQL 解析日志發(fā)現(xiàn),order_id 字段已按照有序自增的方式插入記錄,說明配置的沒問題。

舉一反九

既然可以自定義生成方案,那么實(shí)現(xiàn)分布式主鍵的思路就很多了,又想到之前我寫的這篇 《9種 分布式ID生成方案》,發(fā)現(xiàn)可以完美兼容,這里挑選其中的 滴滴(Tinyid)來實(shí)踐一下,由于它是個單獨(dú)的分布式ID生成服務(wù),所以要先搭建環(huán)境了。

Tinyid 的服務(wù)提供Http 和 Tinyid-client 兩種接入方式,下邊使用 Tinyid-client 方式快速使用,更多的細(xì)節(jié)到這篇文章里看吧,實(shí)在是介紹過太多次了。

Tinyid 服務(wù)搭建

先拉源代碼 https://github.com/didi/tinyid.git。

由于是基于號段模式實(shí)現(xiàn)的分布式ID,所以依賴于數(shù)據(jù)庫,要創(chuàng)建相應(yīng)的表 tiny_id_info 、tiny_id_token 并插入默認(rèn)數(shù)據(jù)。

  1. CREATE TABLE `tiny_id_info` ( 
  2.  `id` BIGINT (20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主鍵'
  3.  `biz_type` VARCHAR (63) NOT NULL DEFAULT '' COMMENT '業(yè)務(wù)類型,唯一'
  4.  `begin_id` BIGINT (20) NOT NULL DEFAULT '0' COMMENT '開始id,僅記錄初始值,無其他含義。初始化時begin_id和max_id應(yīng)相同'
  5.  `max_id` BIGINT (20) NOT NULL DEFAULT '0' COMMENT '當(dāng)前最大id'
  6.  `step` INT (11) DEFAULT '0' COMMENT '步長'
  7.  `delta` INT (11) NOT NULL DEFAULT '1' COMMENT '每次id增量'
  8.  `remainder` INT (11) NOT NULL DEFAULT '0' COMMENT '余數(shù)'
  9.  `create_time` TIMESTAMP NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '創(chuàng)建時間'
  10.  `update_time` TIMESTAMP NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新時間'
  11.  `version` BIGINT (20) NOT NULL DEFAULT '0' COMMENT '版本號'
  12.  PRIMARY KEY (`id`), 
  13.  UNIQUE KEY `uniq_biz_type` (`biz_type`) 
  14. ) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COMMENT 'id信息表'
  15.  
  16. CREATE TABLE `tiny_id_token` ( 
  17.  `id` INT (11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增id'
  18.  `token` VARCHAR (255) NOT NULL DEFAULT '' COMMENT 'token'
  19.  `biz_type` VARCHAR (63) NOT NULL DEFAULT '' COMMENT '此token可訪問的業(yè)務(wù)類型標(biāo)識'
  20.  `remark` VARCHAR (255) NOT NULL DEFAULT '' COMMENT '備注'
  21.  `create_time` TIMESTAMP NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '創(chuàng)建時間'
  22.  `update_time` TIMESTAMP NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新時間'
  23.  PRIMARY KEY (`id`) 
  24. ) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COMMENT 'token信息表'
  25.  
  26. INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`) VALUES ('1''0f673adf80504e2eaa552f5d791b644c''order''1''2017-12-14 16:36:46''2017-12-14 16:36:48'); 
  27.  
  28. INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`) VALUES ('1''order''1''1''100000''1''0''2018-07-21 23:52:58''2018-07-22 23:19:27''1'); 

并在 Tinyid 服務(wù)中配置上邊表所在數(shù)據(jù)源信息

  1. datasource.tinyid.primary.url=jdbc:mysql://47.93.6.e:3306/ds-0?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 
  2. datasource.tinyid.primary.username=root 
  3. datasource.tinyid.primary.password=root 

最后項目 maven install ,右鍵 TinyIdServerApplication 啟動服務(wù), Tinyid 分布式ID生成服務(wù)就搭建完畢了。

自定義 Tinyid 主鍵類型

Tinyid 服務(wù)搭建完下邊在項目中引入它,新建個 tinyid_client.properties 文件其中添加 tinyid.server 和 tinyid.token 屬性,token 為之前 SQL 預(yù)先插入的用戶數(shù)據(jù)。

  1. # tinyid 分布式ID 
  2. # 服務(wù)地址 
  3. tinyid.server=127.0.0.1:9999 
  4. # 業(yè)務(wù)token 
  5. tinyid.token=0f673adf80504e2eaa552f5d791b644c 

代碼中獲取 ID更簡單,只需一行代碼,業(yè)務(wù)類型 order 是之前 SQ L 預(yù)先插入的數(shù)據(jù)。

  1. Long id = TinyId.nextId("order"); 

我們開始自定義 Tinyid 主鍵生成類型的實(shí)現(xiàn)類 TinyIdShardingKeyGenerator 。

  1. /** 
  2.  * @Author: xiaofu 
  3.  * @Description: 自定義主鍵生成器 
  4.  */ 
  5. @Component 
  6. public class TinyIdShardingKeyGenerator implements ShardingKeyGenerator { 
  7.      
  8.     /** 
  9.      * 自定義的生成方案類型 
  10.      */ 
  11.     @Override 
  12.     public String getType() { 
  13.         return "tinyid"
  14.     } 
  15.  
  16.     /** 
  17.      * 核心方法-生成主鍵ID 
  18.      */ 
  19.     @Override 
  20.     public Comparable<?> generateKey() { 
  21.          
  22.         Long id = TinyId.nextId("order"); 
  23.          
  24.         return id; 
  25.     } 
  26.  
  27.     @Override 
  28.     public Properties getProperties() { 
  29.         return null
  30.     } 
  31.  
  32.     @Override 
  33.     public void setProperties(Properties properties) { 
  34.  
  35.     } 

并在配置文件中啟用 Tinyid 主鍵生成類型,到此配置完畢,趕緊測試一下。

  1. # 主鍵字段 
  2. spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id 
  3. # 主鍵ID 生成方案 
  4. spring.shardingsphere.sharding.tables.t_order.key-generator.type=tinyid 

測試 Tinyid 主鍵

向數(shù)據(jù)庫插入訂單記錄測試發(fā)現(xiàn),主鍵ID字段 order_id 已經(jīng)為趨勢遞增的了, Tinyid 服務(wù)成功接入,完美!

總結(jié)

后續(xù)的八種生成方式大家參考 《9種 分布式ID生成方案》 按需接入吧,整體比較簡單這里就不依次實(shí)現(xiàn)了。

案例 GitHub 地址:https://github.com/chengxy-nds/Springboot-Notebook/tree/master/springboot-sharding-jdbc劉一手

原文鏈接:https://mp.weixin.qq.com/s/x1gVtnKh2OEAzSwv0sFDxg

 

責(zé)任編輯:武曉燕 來源: 程序員內(nèi)點(diǎn)事
相關(guān)推薦

2025-03-28 10:27:29

2024-11-22 15:32:19

2024-04-18 09:24:32

分布式ID分庫分表

2017-06-19 17:55:22

CASID分布式

2016-11-29 09:12:21

數(shù)據(jù)庫分布式ID

2024-02-22 17:02:09

IDUUID雪花算法

2023-09-03 22:14:23

分布式ID

2023-08-26 20:08:15

分庫分表Spring

2023-01-12 17:46:37

分庫分表id如何生成

2017-07-01 16:02:39

分布式ID生成器

2017-07-19 16:25:07

數(shù)據(jù)庫開發(fā)DB分庫主鍵生成策略

2021-06-05 07:33:09

ID分布式架構(gòu)

2017-07-04 16:18:15

分布式云應(yīng)用導(dǎo)圖

2020-11-04 14:20:58

分布式數(shù)據(jù)庫MySQL

2020-07-31 10:15:32

分布式ID數(shù)據(jù)庫MySQL

2025-05-27 03:22:00

分布式ID部署

2023-03-05 18:23:38

分布式ID節(jié)點(diǎn)

2023-04-03 10:00:00

Redis分布式

2019-09-05 13:06:08

雪花算法分布式ID

2019-09-03 09:22:08

數(shù)據(jù)庫Redis算法
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號