ID生成方案总结

分布式ID生成方案

  • UUID
  • 数据库自增
  • 号段模式
  • Redis实现
  • 雪花算法(SnowFlake)
  • 百度Uidgenerator
  • 美团Leaf
  • 滴滴TinyID

本文重点介绍能够ID自增的Leaf和TinyID

号段模式

这种模式也是现在生成分布式ID的一种方法,实现思路是会从数据库获取一个号段范围,比如[1,1000],生成1到1000的自增ID加载到内存中,建表结构如:

CREATE TABLE id_generator (id int(10) NOT NULL,max_id bigint(20) NOT NULL COMMENT '当前最大id',step int(20) NOT NULL COMMENT '号段的布长',biz_type int(20) NOT NULL COMMENT '业务类型',version int(20) NOT NULL COMMENT '版本号',PRIMARY KEY (`id`)
) 


biz_type :不同业务类型
max_id :当前最大的id
step :代表号段的步长
version :版本号,就像MVCC一样,可以理解为乐观锁
等ID都用了,再去数据库获取,然后更改最大值

update id_generator set max_id = #{max_id+step}, version = version + 1 where version = # {version} and biz_type = XXX

优点:有比较成熟的方案,像百度Uidgenerator,美团Leaf
缺点:依赖于数据库实现

美团Leaf

Leaf 提供两种生成的ID的方式:号段模式(Leaf-segment)和snowflake模式(Leaf-snowflake)。你可以同时开启两种方式,也可以指定开启某种方式,默认两种方式为关闭状态。

git位置

GitHub - Meituan-Dianping/Leaf: Distributed ID Generate Service

介绍文档

https://github.com/Meituan-Dianping/Leaf/blob/master/README_CN.md

创建数据表

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')

获取项目

git clone git@github.com:Meituan-Dianping/Leaf.git

升级mysql驱动

如果连接的是mysql1.8以上,需要升级mysql驱动,分别是

Leaf/poe.xml以及 leaf_core/poe.xml

# Leaf/poe.xml
<mybatis-spring.version>1.2.5</mybatis-spring.version>#leaf_core/poe.xml<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency>

修改配置

下面是号段模式的配置

leaf_server/resouces/leaf.properties

leaf.name=com.sankuai.leaf.opensource.test
leaf.segment.enable=true
leaf.jdbc.url=jdbc:mysql://127.0.0.1:3306/leaf?useSSL=false
leaf.jdbc.username=root
leaf.jdbc.password=123456leaf.snowflake.enable=false
#leaf.snowflake.zk.address=
#leaf.snowflake.port=

打包

cd leaf
mvn clean install -DskipTests

运行

cd leaf-server
#mvn方式
mvn spring-boot:run
#脚本方式
sh deploy/run.sh 

测试

#segment
curl http://localhost:8080/api/segment/get/leaf-segment-test
#snowflake
curl http://localhost:8080/api/snowflake/get/test
监控页面
号段模式:http://localhost:8080/cache

#注意添加一个biz_type以后,10s以后生效

滴滴TinyID

github位置

GitHub - didi/tinyid: ID Generator id生成器

 介绍文档

Home · didi/tinyid Wiki · GitHub

获取项目

git clone https://github.com/didi/tinyid.git

创建数据表

tinyid-server/db.sql

CREATE TABLE `tiny_id_info` (`id` bigint(20) 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');

修改配置

cd tinyid-server/src/main/resources/offline
vi application.properties

server.port=9999
server.context-path=/tinyidbatch.size.max=100000#datasource.tinyid.names=primary
#如果希望数据库能够高可用,可以设置多个不同节点,两个节点上的数据保持一致。
#注意添加配置的时候,多个节点都要添加
datasource.tinyid.names=primary,secondary
datasource.tinyid.type=org.apache.tomcat.jdbc.pool.DataSourcedatasource.tinyid.primary.driver-class-name=com.mysql.jdbc.Driver
datasource.tinyid.primary.url=jdbc:mysql://localhost:3306/db1?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
datasource.tinyid.primary.username=root
datasource.tinyid.primary.password=123456
#datasource.tinyid.primary.testOnBorrow=false
#datasource.tinyid.primary.maxActive=10datasource.tinyid.secondary.driver-class-name=com.mysql.jdbc.Driver
datasource.tinyid.secondary.url=jdbc:mysql://localhost:3306/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

打包

cd tinyid

mvn clean install -DskipTests

#或者

cd tinyid-server/
sh build.sh offline

运行

cd tinyid-server/
#sh build.sh offline
java -jar output/tinyid-server-xxx.jar

测试

nextId:
curl 'http://localhost:9999/tinyid/id/nextId?bizType=test&token=0f673adf80504e2eaa552f5d791b644c'
response:{"data":[2],"code":200,"message":""}nextId Simple:
curl 'http://localhost:9999/tinyid/id/nextIdSimple?bizType=test&token=0f673adf80504e2eaa552f5d791b644c'
response: 3with batchSize:
curl 'http://localhost:9999/tinyid/id/nextIdSimple?bizType=test&token=0f673adf80504e2eaa552f5d791b644c&batchSize=10'
response: 4,5,6,7,8,9,10,11,12,13Get nextId like 1,3,5,7,9...
bizType=test_odd : delta is 2 and remainder is 1
curl 'http://localhost:9999/tinyid/id/nextIdSimple?bizType=test_odd&batchSize=10&token=0f673adf80504e2eaa552f5d791b644c'
response: 3,5,7,9,11,13,15,17,19,21

 

客户端使用

客户端打包

cd tinyid

mvn clean install -DskipTests

#tinyid-client\target\tinyid-client-0.1.0-SNAPSHOT.jar就是可以使用的客户端

客户端配置文件

tinyid_client.properties

将tinyid_client.properties放在resouces下面

tinyid.server=localhost:9999
tinyid.token=0f673adf80504e2eaa552f5d791b644c

使用

public class ClientTest {@Testpublic void testNextId() {for (int i = 0; i < 100000; i++) {Long id = TinyId.nextId("test_odd");System.out.println("current id is: " + id);}}
}

注意:每次重启程序,id就会往前加一个step,不管你有没有用完,如果程序经常重启,step不宜设置过大。但是step不宜设置过小,否则与数据库交互过于频繁。

来源:

8种分布式ID生成方案汇总 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/22604.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MikTex+TexStudio踩坑记

首先&#xff0c;去这两个的官网&#xff0c;下载安装&#xff0c;都没问题。 第二&#xff0c;记得以管理员方式运行程序&#xff0c;可能会少很多麻烦 第三&#xff0c;编译的时候&#xff0c;命令行提示错误&#xff1a; So far, no MiKTeX administrator has checked fo…

AcWing 24:机器人的运动范围 ← BFS、DFS

【题目来源】https://www.acwing.com/problem/content/description/22/【题目描述】 地上有一个 m 行和 n 列的方格&#xff0c;横纵坐标范围分别是 0∼m−1 和 0∼n−1。 一个机器人从坐标 (0,0) 的格子开始移动&#xff0c;每一次只能向左&#xff0c;右&#xff0c;上&#…

【雕爷学编程】Arduino动手做(182)---DRV8833双路电机驱动模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

【LangChain】Prompts之Prompt templates

Prompts 编程模型的新方法是通过提示(prompts)。 prompts是指模型的输入。该输入通常由多个组件构成。 LangChain 提供了多个类和函数&#xff0c;使构建和使用prompts变得容易。 Prompt templates(提示模板): 参数化模型输入Example selectors(选择器示例): 动态选择要包含在…

EventBus 开源库学习(一)

一、概念 EventBus是一款在 Android 开发中使用的发布-订阅事件总线框架&#xff0c;基于观察者模式&#xff0c;将事件的接收者和发送者解耦&#xff0c;简化了组件之间的通信&#xff0c;使用简单、效率高、体积小。 一句话&#xff1a;用于Android组件间通信的。 二、原理…

TypeScript最新语法总结

注意注意&#xff01;&#xff01;&#xff01;本文介绍的是最新的TypeScript4的重要语法 第一部分&#xff1a;TypeScript的简介 TypeScript 是由微软开发的一款开源的编程语言&#xff0c;TypeScript 是 Javascript 的超集&#xff0c;遵循最新的 ES6、ES5 规范&#xff0c…

做好“关键基础设施提供商”角色,亚马逊云科技加快生成式AI落地

一场关于生产力的革命已在酝酿之中。全球管理咨询公司麦肯锡在最近的报告《生成式人工智能的经济潜力&#xff1a;下一波生产力浪潮》中指出&#xff0c;生成式AI每年可能为全球经济增加2.6万亿到4.4万亿美元的价值。在几天前的亚马逊云科技纽约峰会中&#xff0c;「生成式AI」…

动手学深度学习(二)线性神经网络

推荐课程&#xff1a;跟李沐学AI的个人空间-跟李沐学AI个人主页-哔哩哔哩视频 回归任务是指对连续变量进行预测的任务。 一、线性回归 线性回归模型是一种常用的统计学习方法&#xff0c;用于分析自变量与因变量之间的关系。它通过建立一个关于自变量和因变量的线性方程&…

分布式协议与算法——拜占庭将军问题

拜占庭将军问题 背景&#xff1a;以战国时期为背景 战国时期&#xff0c;齐、楚、燕、韩、赵、魏、秦七雄并立&#xff0c;后来秦国的势力不断强大起来&#xff0c;成了东方六国的共同威胁。于是&#xff0c;这六个国家决定联合&#xff0c;全力抗秦&#xff0c;免得被秦国各个…

JVM面试突击1

JVM面试突击 JDK&#xff0c;JRE以及JVM的关系 我们的编译器到底干了什么事&#xff1f; 仅仅是将我们的 .java 文件转换成了 .class 文件&#xff0c;实际上就是文件格式的转换&#xff0c;对等信息转换。 类加载机制是什么&#xff1f; 所谓类加载机制就是 虚拟机把Class文…

C语言阶段性测试题

大家好&#xff0c;我是深鱼~ 【前言】&#xff1a;本部分是C语言初阶学完阶段性测试题&#xff0c;最后一道编程题有一定的难度&#xff0c;需要多去揣摩&#xff0c;代码敲多了&#xff0c;自然就感觉不难了&#xff0c;加油&#xff0c;铁汁们&#xff01;&#xff01;&…

YOLO中Anchor生成介绍

Anchor生成机制 YOLOv1YOLOv2YOLOv4模型输出decode1.维度变换2.读取位置信息3.坐标变换4.构建网格5. 计算实际偏移量6.得到输出 YOLOv1 利用全连接层直接对边界框进行预测 YOLOv2 YOLOv2通过缩减网络&#xff0c;使用416x416的输入&#xff0c;模型下采样的总步长为32&#…

flutter开发实战-实现自定义按钮类似UIButton效果

flutter开发实战-实现自定义按钮类似UIButton效果 最近开发过程中需要实现一下UIButton效果的flutter按钮&#xff0c;这里使用的是监听手势点击事件。 一、GestureDetector GestureDetector属性定义 GestureDetector({super.key,this.child,this.onTapDown,this.onTapUp,t…

附件展示 点击下载

效果图 实现代码 <el-table-column prop"attachment" label"合同附件" width"250" show-overflow-tooltip><template slot-scope"scope"><div v-if"scope.row.cceedcAppendixInfoList &&scope.row.ccee…

路由的hash和history模式的区别

目录 ✅ 路由模式概述 一. 路由的hash和history模式的区别 1. hash模式 2. history模式 3. 两种模式对比 二. 如何获取页面的hash变化 ✅ 路由模式概述 单页应用是在移动互联时代诞生的&#xff0c;它的目标是不刷新整体页面&#xff0c;通过地址栏中的变化来决定内容区…

SQL 表别名 和 列别名

列表名 列表名之后 order by 可以用别名 也可以用原名&#xff0c; where 中不能用别名的 SQL语句执行顺序&#xff1a; from–>where–>group by -->having — >select --> order 第一步&#xff1a;from语句&#xff0c;选择要操作的表。 第二步&#xff1…

SpringBoot图片上传并对大小进行压缩(缩放比例)

前言 最近有个新需求&#xff0c;项目中对客户上传jpg图片的时候&#xff0c;每次都是校验大小必须≤30KB&#xff0c;但是客户实际使用的时候&#xff0c;总是会自己去进行压缩&#xff0c;压缩到30KB以内之后再上传&#xff0c;使用时间长了之后&#xff0c;客户总会觉得很麻…

react学习笔记——1. hello react

包含的包一共有4个&#xff0c;分别的作用如下&#xff1a; babel.min.js&#xff1a;可以进行ES6到ES5的语法转换&#xff1b;可以用于import&#xff1b;可以用于将jsx转换为js。注意&#xff0c;在开发的时候&#xff0c;这个转换&#xff08;jsx转换js&#xff09;不在线上…

Tcp的粘包和半包问题及解决方案

目录 粘包&#xff1a; 半包&#xff1a; 应用进程如何解读字节流&#xff1f;如何解决粘包和半包问题&#xff1f; ①&#xff1a;固定长度 ②&#xff1a;分隔符 ③&#xff1a;固定长度字段存储内容的长度信息 粘包&#xff1a; 一次接收到多个消息&#xff0c;粘包 应…

HBase概述

HBase 一 HBase简介与环境部署 1.1 HBase简介&在Hadoop生态中的地位 1.1.1 什么是HBase HBase是一个分布式的、面向列的开源数据库HBase是Google BigTable的开源实现HBase不同于一般的关系数据库, 适合非结构化数据存储 1.1.2 BigTable BigTable是Google设计的分布式…