面试总被问分布式ID怎么办? 滴滴(Tinyid)甩给他

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

面试总被问分布式ID怎么办? 滴滴(Tinyid)甩给他

程序员内点事   2020-03-14 我要评论
> 整理了一些Java方面的架构、面试资料(微服务、集群、分布式、中间件等),有需要的小伙伴可以关注公众号【程序员内点事】,无套路自行领取 - [一口气说出 9种 分布式ID生成方式,面试官有点懵了](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483785&idx=1&sn=8b828a8ae1701b810fe3969be536cb14&chksm=9b859174acf21862f0b95e0502a1a441c496a5488f5466b2e147d7bb9de072bde37c4db25d7a&token=745402269&lang=zh_CN#rd) - [面试总被问分库分表怎么办?你可以这样怼他](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483882&idx=1&sn=9e0901dd19e3e06a135fe96780c43477&chksm=9b859117acf218017d9273d4328258c01f6a105180ae8534dc0aaa362cc0c3020dd55de3a95e&token=361009039&lang=zh_CN#rd) - [3万字总结,Mysql优化之精髓](https://juejin.im/post/5e3eb616f265da570d734dcb) - [技术部突然宣布:JAVA开发人员全部要会接口自动化测试框架](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483790&idx=1&sn=f2cb1cc3a4159f6565799e7cec45c9d7&chksm=9b859173acf218654de6344b576b02cca619dd09b6df4750828315b3d591df82a03055032e0c&token=745402269&lang=zh_CN#rd) - [9种分布式ID生成之美团(Leaf)实战](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483889&idx=1&sn=35b0eb32de3e63c013585ef1db5d3076&chksm=9b85910cacf2181a23bdc1344a1984e3fa7613cc8dd9e28f3b10196fc73b9022d735f4031e88&token=662935248&lang=zh_CN#rd) #### 引言 接着《一口气说出 9种 分布式ID生成方式,面试官有点懵了》来继续详细的介绍分布式ID生成器,大家比较感兴趣的`美团(Leaf)`、`滴滴(Tinyid)`、`百度(uid-generator)`三个开源项目,美团(Leaf)已经讲完,详见《9种分布式ID生成之美团(Leaf)实战》,今天结合实战搞一下滴滴开源的(`Tinyid`)。 --- #### `Tinyid`介绍 `Tinyid`是滴滴开发的一款分布式ID系统,`Tinyid`是在`美团(Leaf)`的`leaf-segment`算法基础上升级而来,不仅支持了数据库多主节点模式,还提供了`tinyid-client`客户端的接入方式,使用起来更加方便。但和美团(Leaf)不同的是,Tinyid只支持号段一种模式不支持雪花模式。 ##### Tinyid的特性 - 全局唯一的long型ID - 趋势递增的id - 提供 http 和 java-client 方式接入 - 支持批量获取ID - 支持生成1,3,5,7,9...序列的ID - 支持多个db的配置 **适用场景**:只关心ID是数字,趋势递增的系统,可以容忍ID不连续,可以容忍ID的浪费 **不适用场景**:像类似于订单ID的业务,因生成的ID大部分是连续的,容易被扫库、或者推算出订单量等信息 --- #### `Tinyid`原理 `Tinyid`是基于号段模式实现,再简单啰嗦一下号段模式的原理:就是从数据库批量的获取自增ID,每次从数据库取出一个号段范围,例如 `(1,1000]` 代表1000个ID,业务服务将号段在本地生成`1~1000`的自增ID并加载到内存.。 `Tinyid`会将可用号段加载到内存中,并在内存中生成ID,可用号段在首次获取ID时加载,如当前号段使用达到一定比例时,系统会异步的去加载下一个可用号段,以此保证内存中始终有可用号段,以便在发号服务宕机后一段时间内还有可用ID。 原理图大致如下图: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200314110819168.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbnpoaWZ1MQ==,size_16,color_FFFFFF,t_70) #### `Tinyid`实现 `Tinyid`的GitHub地址 : https://github.comhttps://img.qb5200.com/download-x/didi/tinyid.git `Tinyid`提供了两种调用方式,一种基于`Tinyid-server`提供的http方式,另一种`Tinyid-client`客户端方式。 不管使用哪种方式调用,搭建`Tinyid`都必须提前建表`tiny_id_info`、`tiny_id_token`。 ```handlebars CREATE TABLE `tiny_id_info` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '业务类型,唯一', `begin_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '开始id,仅记录初始值,无其他含义。初始化时begin_id和max_id应相同', `max_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '当前最大id', `step` int(11) DEFAULT '0' COMMENT '步长', `delta` int(11) NOT NULL DEFAULT '1' COMMENT '每次id增量', `remainder` int(11) NOT NULL DEFAULT '0' COMMENT '余数', `create_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '创建时间', `update_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新时间', `version` bigint(20) NOT NULL DEFAULT '0' COMMENT '版本号', PRIMARY KEY (`id`), UNIQUE KEY `uniq_biz_type` (`biz_type`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'id信息表'; CREATE TABLE `tiny_id_token` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id', `token` varchar(255) NOT NULL DEFAULT '' COMMENT 'token', `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '此token可访问的业务类型标识', `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注', `create_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '创建时间', `update_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'token信息表'; INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`) VALUES (1, 'test', 1, 1, 100000, 1, 0, '2018-07-21 23:52:58', '2018-07-22 23:19:27', 1); INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`) VALUES (2, 'test_odd', 1, 1, 100000, 2, 1, '2018-07-21 23:52:58', '2018-07-23 00:39:24', 3); INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`) VALUES (1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48'); INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`) VALUES (2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48'); ``` `tiny_id_info`表是具体业务方号段信息数据表 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200314114423657.png) `max_id` :号段的最大值 `step`:步长,即为号段的长度 `biz_type`:业务类型 号段获取对`max_id`字段做一次`update`操作,`update max_id= max_id + step`,更新成功则说明新号段获取成功,新的号段范围是`(max_id ,max_id +step]`。 `tiny_id_token`是一个权限表,表示当前token可以操作哪些业务的号段信息。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020031411444742.png) 修改`tinyid-server`中 `\offline\application.properties` 文件配置数据库,由于`tinyid`支持数据库多`master`模式,可以配置多个数据库信息。启动 `TinyIdServerApplication` 测试一下。 ```sql datasource.tinyid.primary.driver-class-name=com.mysql.jdbc.Driver datasource.tinyid.primary.url=jdbc:mysql://127.0.0.1:3306/xin-master?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 datasource.tinyid.primary.username=junkang datasource.tinyid.primary.password=junkang datasource.tinyid.primary.testOnBorrow=false datasource.tinyid.primary.maxActive=10 datasource.tinyid.secondary.driver-class-name=com.mysql.jdbc.Driver datasource.tinyid.secondary.url=jdbc:mysql://localhost:3306https://img.qb5200.com/download-x/db2?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 datasource.tinyid.secondary.username=root datasource.tinyid.secondary.password=123456 datasource.tinyid.secondary.testOnBorrow=false datasource.tinyid.secondary.maxActive=10 ``` ##### 1、Http方式 `tinyid `内部一共提供了四个` http `接口来获取ID和号段。 ```java package com.xiaoju.uemc.tinyid.server.controller; /** * @author du_imba */ @RestController @RequestMapping("/id/") public class IdContronller { private static final Logger logger = LoggerFactory.getLogger(IdContronller.class); @Autowired private IdGeneratorFactoryServer idGeneratorFactoryServer; @Autowired private SegmentIdService segmentIdService; @Autowired private TinyIdTokenService tinyIdTokenService; @Value("${batch.size.max}") private Integer batchSizeMax; @RequestMapping("nextId") public Response

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们