成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

滴滴的分布式ID生成器(Tinyid),好用的一批

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù) 分布式
Tinyid是滴滴開(kāi)發(fā)的一款分布式ID系統(tǒng),Tinyid是在美團(tuán)(Leaf)的leaf-segment算法基礎(chǔ)上升級(jí)而來(lái),不僅支持了數(shù)據(jù)庫(kù)多主節(jié)點(diǎn)模式,還提供了tinyid-client客戶端的接入方式,使用起來(lái)更加方便。

 不了解分布式ID生成器的同學(xué),先復(fù)習(xí)一下之前的 《9種分布式ID生成方式》

Tinyid是滴滴開(kāi)發(fā)的一款分布式ID系統(tǒng),Tinyid是在美團(tuán)(Leaf)的leaf-segment算法基礎(chǔ)上升級(jí)而來(lái),不僅支持了數(shù)據(jù)庫(kù)多主節(jié)點(diǎn)模式,還提供了tinyid-client客戶端的接入方式,使用起來(lái)更加方便。但和美團(tuán)(Leaf)不同的是,Tinyid只支持號(hào)段一種模式不支持雪花模式。

Tinyid的特性

  •  全局唯一的long型ID
  •  趨勢(shì)遞增的id
  •  提供 http 和 java-client 方式接入
  •  支持批量獲取ID
  •  支持生成1,3,5,7,9...序列的ID
  •  支持多個(gè)db的配置

適用場(chǎng)景:只關(guān)心ID是數(shù)字,趨勢(shì)遞增的系統(tǒng),可以容忍ID不連續(xù),可以容忍ID的浪費(fèi)

不適用場(chǎng)景:像類似于訂單ID的業(yè)務(wù),因生成的ID大部分是連續(xù)的,容易被掃庫(kù)、或者推算出訂單量等信息

Tinyid原理

Tinyid是基于號(hào)段模式實(shí)現(xiàn),再簡(jiǎn)單啰嗦一下號(hào)段模式的原理:就是從數(shù)據(jù)庫(kù)批量的獲取自增ID,每次從數(shù)據(jù)庫(kù)取出一個(gè)號(hào)段范圍,例如 (1,1000] 代表1000個(gè)ID,業(yè)務(wù)服務(wù)將號(hào)段在本地生成1~1000的自增ID并加載到內(nèi)存.。

Tinyid會(huì)將可用號(hào)段加載到內(nèi)存中,并在內(nèi)存中生成ID,可用號(hào)段在首次獲取ID時(shí)加載,如當(dāng)前號(hào)段使用達(dá)到一定比例時(shí),系統(tǒng)會(huì)異步的去加載下一個(gè)可用號(hào)段,以此保證內(nèi)存中始終有可用號(hào)段,以便在發(fā)號(hào)服務(wù)宕機(jī)后一段時(shí)間內(nèi)還有可用ID。

原理圖大致如下圖:

Tinyid原理圖

Tinyid實(shí)現(xiàn)

Tinyid的GitHub地址 :https://github.com/didi/tinyid.git

Tinyid提供了兩種調(diào)用方式,一種基于Tinyid-server提供的http方式,另一種Tinyid-client客戶端方式。不管使用哪種方式調(diào)用,搭建Tinyid都必須提前建表tiny_id_info、tiny_id_token。 

  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 '開(kāi)始id,僅記錄初始值,無(wú)其他含義。初始化時(shí)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 '步長(zhǎng)',  
  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)建時(shí)間',  
  10.   `update_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新時(shí)間',  
  11.   `version` bigint(20) NOT NULL DEFAULT '0' COMMENT '版本號(hào)',  
  12.   PRIMARY KEY (`id`), 
  13.   UNIQUE KEY `uniq_biz_type` (`biz_type`)  
  14. ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'id信息表';  
  15. CREATE TABLE `tiny_id_token` (  
  16.   `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',  
  17.   `token` varchar(255) NOT NULL DEFAULT '' COMMENT 'token',  
  18.   `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '此token可訪問(wèn)的業(yè)務(wù)類型標(biāo)識(shí)',  
  19.   `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '備注',  
  20.   `create_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '創(chuàng)建時(shí)間',  
  21.   `update_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新時(shí)間',  
  22.   PRIMARY KEY (`id`)  
  23. ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'token信息表';  
  24. INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)  
  25. VALUES  
  26.  (1, 'test', 1, 1, 100000, 1, 0, '2018-07-21 23:52:58', '2018-07-22 23:19:27', 1);  
  27. INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)  
  28. VALUES  
  29.  (2, 'test_odd', 1, 1, 100000, 2, 1, '2018-07-21 23:52:58', '2018-07-23 00:39:24', 3);  
  30. INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)  
  31. VALUES  
  32.  (1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48');  
  33. INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)  
  34. VALUES  
  35.  (2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48'); 

tiny_id_info表是具體業(yè)務(wù)方號(hào)段信息數(shù)據(jù)表

max_id :號(hào)段的最大值

step:步長(zhǎng),即為號(hào)段的長(zhǎng)度

biz_type:業(yè)務(wù)類型

號(hào)段獲取對(duì)max_id字段做一次update操作,update max_id= max_id + step,更新成功則說(shuō)明新號(hào)段獲取成功,新的號(hào)段范圍是(max_id ,max_id +step]。

tiny_id_token是一個(gè)權(quán)限表,表示當(dāng)前token可以操作哪些業(yè)務(wù)的號(hào)段信息。

修改tinyid-server中  \offline\application.properties 文件配置數(shù)據(jù)庫(kù),由于tinyid支持?jǐn)?shù)據(jù)庫(kù)多master模式,可以配置多個(gè)數(shù)據(jù)庫(kù)信息。啟動(dòng) TinyIdServerApplication 測(cè)試一下。 

  1. datasource.tinyid.primary.driver-class-name=com.mysql.jdbc.Driver  
  2. datasource.tinyid.primary.url=jdbc:mysql://127.0.0.1:3306/xin-master?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8  
  3. datasource.tinyid.primary.username=junkang  
  4. datasource.tinyid.primary.password=junkang  
  5. datasource.tinyid.primary.testOnBorrow=false  
  6. datasource.tinyid.primary.maxActive=10  
  7. datasource.tinyid.secondary.driver-class-name=com.mysql.jdbc.Driver  
  8. datasource.tinyid.secondary.url=jdbc:mysql://localhost:3306/db2?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8  
  9. datasource.tinyid.secondary.username=root  
  10. datasource.tinyid.secondary.password=123456  
  11. datasource.tinyid.secondary.testOnBorrow=false  
  12. datasource.tinyid.secondary.maxActive=10 

1、Http方式

tinyid內(nèi)部一共提供了四個(gè)http接口來(lái)獲取ID和號(hào)段。 

  1. package com.xiaoju.uemc.tinyid.server.controller;  
  2. /**  
  3.  * @author du_imba  
  4.  */  
  5. @RestController  
  6. @RequestMapping("/id/")  
  7. public class IdContronller {   
  8.     private static final Logger logger = LoggerFactory.getLogger(IdContronller.class);  
  9.     @Autowired  
  10.     private IdGeneratorFactoryServer idGeneratorFactoryServer;  
  11.     @Autowired  
  12.     private SegmentIdService segmentIdService;  
  13.     @Autowired  
  14.     private TinyIdTokenService tinyIdTokenService;  
  15.     @Value("${batch.size.max}")  
  16.     private Integer batchSizeMax;  
  17.     @RequestMapping("nextId") 
  18.     public Response<List<Long>> nextId(String bizType, Integer batchSize, String token) {  
  19.         Response<List<Long>> response = new Response<>();  
  20.         try {  
  21.             IdGenerator idGenerator = idGeneratorFactoryServer.getIdGenerator(bizType);  
  22.             List<Long> ids = idGenerator.nextId(newBatchSize);  
  23.             response.setData(ids);  
  24.         } catch (Exception e) {  
  25.             response.setCode(ErrorCode.SYS_ERR.getCode());  
  26.             response.setMessage(e.getMessage());  
  27.             logger.error("nextId error", e);  
  28.         }  
  29.         return response; 
  30.     }  
  31.     @RequestMapping("nextIdSimple")  
  32.     public String nextIdSimple(String bizType, Integer batchSize, String token) {  
  33.         String response = "" 
  34.         try {  
  35.             IdGenerator idGenerator = idGeneratorFactoryServer.getIdGenerator(bizType);  
  36.             if (newBatchSize == 1) {  
  37.                 Long id = idGenerator.nextId();  
  38.                 response = id + "";  
  39.             } else {  
  40.                 List<Long> idList = idGenerator.nextId(newBatchSize);  
  41.                 StringBuilder sb = new StringBuilder();  
  42.                 for (Long id : idList) { 
  43.                     sb.append(id).append(",");  
  44.                 } 
  45.                  response = sb.deleteCharAt(sb.length() - 1).toString();  
  46.             }  
  47.         } catch (Exception e) {  
  48.             logger.error("nextIdSimple error", e); 
  49.         } 
  50.          return response;  
  51.     }  
  52.     @RequestMapping("nextSegmentId")  
  53.     public Response<SegmentId> nextSegmentId(String bizType, String token) {  
  54.         try {  
  55.             SegmentId segmentId = segmentIdService.getNextSegmentId(bizType);  
  56.             response.setData(segmentId);  
  57.         } catch (Exception e) {  
  58.             response.setCode(ErrorCode.SYS_ERR.getCode());  
  59.             response.setMessage(e.getMessage());  
  60.             logger.error("nextSegmentId error", e);  
  61.         }  
  62.         return response;  
  63.     }  
  64.     @RequestMapping("nextSegmentIdSimple")  
  65.     public String nextSegmentIdSimple(String bizType, String token) {  
  66.         String response = "" 
  67.         try {  
  68.             SegmentId segmentId = segmentIdService.getNextSegmentId(bizType); 
  69.              response = segmentId.getCurrentId() + "," + segmentId.getLoadingId() + "," + segmentId.getMaxId()  
  70.                     + "," + segmentId.getDelta() + "," + segmentId.getRemainder();  
  71.         } catch (Exception e) {  
  72.             logger.error("nextSegmentIdSimple error", e);  
  73.         }  
  74.         return response;  
  75.     }  

nextId、nextIdSimple都是獲取下一個(gè)ID,nextSegmentIdSimple、getNextSegmentId是獲取下一個(gè)可用號(hào)段。區(qū)別在于接口是否有返回狀態(tài)。 

  1. nextId:  
  2. 'http://localhost:9999/tinyid/id/nextId?bizType=test&token=0f673adf80504e2eaa552f5d791b644c 
  3. response :  
  4.  
  5.     "data": [2],  
  6.     "code": 200,  
  7.     "message": ""  
  8.  
  9. nextId Simple:  
  10. 'http://localhost:9999/tinyid/id/nextIdSimple?bizType=test&token=0f673adf80504e2eaa552f5d791b644c 
  11. response: 3 

2、Tinyid-client客戶端

如果不想通過(guò)http方式,Tinyid-client客戶端也是一種不錯(cuò)的選擇。

引用 tinyid-server包 

  1. <dependency>  
  2.     <groupId>com.xiaoju.uemc.tinyid</groupId>  
  3.     <artifactId>tinyid-client</artifactId>  
  4.     <version>${tinyid.version}</version>  
  5. </dependency> 

啟動(dòng) tinyid-server項(xiàng)目打包后得到 tinyid-server-0.1.0-SNAPSHOT.jar ,設(shè)置版本 ${tinyid.version}為0.1.0-SNAPSHOT。

在我們的項(xiàng)目 application.properties 中配置 tinyid-server服務(wù)的請(qǐng)求地址 和 用戶身份token 

  1. tinyid.server=127.0.0.1:9999  
  2. tinyid.token=0f673adf80504e2eaa552f5d791b644c``` 

在Java代碼調(diào)用TinyId也很簡(jiǎn)單,只需要一行代碼。 

  1. // 根據(jù)業(yè)務(wù)類型 獲取單個(gè)ID  
  2. Long id = TinyId.nextId("test");  
  3. // 根據(jù)業(yè)務(wù)類型 批量獲取10個(gè)ID  
  4. List<Long> ids = TinyId.nextId("test", 10);     

Tinyid整個(gè)項(xiàng)目的源碼實(shí)現(xiàn)也是比較簡(jiǎn)單,像與數(shù)據(jù)庫(kù)交互更直接用jdbcTemplate實(shí)現(xiàn) 

  1. @Override  
  2. public TinyIdInfo queryByBizType(String bizType) {  
  3.     String sql = "select id, biz_type, begin_id, max_id," +  
  4.             " step, delta, remainder, create_time, update_time, version" +  
  5.             " from tiny_id_info where biz_type = ?";  
  6.     List<TinyIdInfo> list = jdbcTemplate.query(sql, new Object[]{bizType}, new TinyIdInfoRowMapper());  
  7.     if(list == null || list.isEmpty()) {  
  8.         return null;  
  9.     }  
  10.     return list.get(0);  

總結(jié)

兩種方式推薦使用Tinyid-client,這種方式ID為本地生成,號(hào)段長(zhǎng)度(step)越長(zhǎng),支持的qps就越大,如果將號(hào)段設(shè)置足夠大,則qps可達(dá)1000w+。而且tinyid-client 對(duì) tinyid-server 訪問(wèn)變的低頻,減輕了server端的壓力。 

 

責(zé)任編輯:龐桂玉 來(lái)源: 數(shù)據(jù)庫(kù)開(kāi)發(fā)
相關(guān)推薦

2017-07-01 16:02:39

分布式ID生成器

2019-12-27 10:00:34

開(kāi)源技術(shù) 軟件

2024-10-07 08:52:59

分布式系統(tǒng)分布式 IDID

2021-07-14 07:17:37

Springboot分布式UIDGenerato

2025-03-11 08:50:00

CASID分布式

2022-02-23 07:09:30

分布式ID雪花算法

2024-12-04 09:36:37

2019-09-05 13:06:08

雪花算法分布式ID

2021-11-08 19:25:37

Go生成系統(tǒng)

2023-12-12 07:13:39

雪花算法分布式ID

2016-11-29 09:12:21

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

2023-09-03 22:14:23

分布式ID

2022-05-19 14:57:30

CSS代碼工具

2022-06-16 07:31:15

MySQL服務(wù)器服務(wù)

2025-03-28 10:27:29

2017-06-19 17:55:22

CASID分布式

2017-04-12 09:29:02

HiveMapReduceSpark

2021-06-28 14:45:07

分布式框架操作

2020-07-21 11:35:21

開(kāi)發(fā)技能代碼

2022-02-15 10:30:58

UUID
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 九九九久久国产免费 | 久久99精品国产自在现线小黄鸭 | 综合久久久 | 成年无码av片在线 | 永久精品| 九色国产 | 在线观看中文字幕 | av天天澡天天爽天天av | 久久精品亚洲国产奇米99 | 第一av| 成人av影院 | 91视在线国内在线播放酒店 | 97色综合 | 亚洲超碰在线观看 | www.日韩免费 | 欧美日韩一区二区在线观看 | 欧美日韩在线免费 | 一区二区国产精品 | 精品在线99 | 欧美日韩免费 | 午夜影院在线播放 | 欧美综合国产精品久久丁香 | 亚洲精品成人av久久 | 亚洲 欧美 另类 日韩 | 91人人爽 | 国产日韩欧美 | 九九热精品视频 | 国产日韩一区二区三免费高清 | 国产精品成人品 | 久热精品在线播放 | 18gay男同69亚洲网站 | h片在线观看免费 | 久久综合一区二区 | 亚洲精彩视频在线观看 | 91在线视频在线观看 | 日韩在线视频一区二区三区 | 成人网av| 中文字幕一区在线观看视频 | 国产在线www| 国产精品久久久精品 | 免费黄色片在线观看 |