美团分布式 ID 框架 Leaf 介绍和使用

一、Leaf

在当今日益数字化的世界里,软件系统的开发已经成为了几乎所有行业的核心。然而,随着应用程序的规模不断扩大,以及对性能和可扩展性的需求不断增加,传统的软件架构和设计模式也在不断地面临挑战。其中一个主要挑战就是如何有效地处理分布式环境中的唯一标识问题。这正是分布式ID 的重要性所在。

分布式ID的实现方式有多种多样,常见的包括 UUIDSnowflake 算法、TwitterSnowflake 算法、基于数据库的自增长ID 等。每种方式都有其适用的场景和优缺点。

比如常见的 UUID , 标准型式包含3216进制数字,以连字号分为五段,形式为8-4-4-4-1236个字符,优点是性能非常高,本地生成,没有网络消耗,但缺点也显而易见,首先不易于存储,UUID太长,16字节128位,通常以36长度的字符串表示,很多场景不适用。其次信息不安全,基于MAC地址生成UUID的算法可能会造成MAC地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。也不适合作为DB的主键。MySQL官方有明确的建议主键要尽量越短越好。

基于数据库的自增长ID 的方式,实现起来非常简单,并且ID是单向自增顺序的,但缺点也很明显,过度依赖于 DB 数据库,在并发量高的情况下数据库成为了性能瓶颈。

基于Snowflake 算法的方式,可以解决上述提到的问题,并且稳定性和灵活性都非常高,但强依赖于机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。

既然如此,那下面我们来认识更强大的分布式ID生成器 Leaf ,它是美团开源的分布式 ID 生成器,旨在解决分布式系统中的唯一标识生成问题,确保在分布式环境下生成的 ID 具有全局唯一性、顺序性和高性能。

Leaf 实现了Leaf-segmentLeaf-snowflake两种方案。

Leaf-segment是一种基于数据库的分布式 ID 生成方案,原始基于数据库的自增长ID 方案,每次获取ID都得读写一次数据库,造成数据库压力大,该方案利用proxy server批量获取,每次获取一个segment(step决定大小)号段的值。用完之后再去数据库获取新的号段,可以大大的减轻数据库的压力。各个业务不同的发号需求用biz_tag字段来区分,每个biz-tagID获取相互隔离,互不影响。如果以后有性能需求需要对数据库扩容,不需要上述描述的复杂的扩容操作,只需要对biz_tag分库分表就行。

Leaf-snowflake方案完全沿用snowflake方案的bit位设计,对于workerID的分配,使用Zookeeper持久顺序节点的特性自动对snowflake节点配置wokerID,对于时钟回拨问题,解决方案如下:

在这里插入图片描述

更多介绍可以参考官方信息:

官方介绍地址:https://tech.meituan.com/2017/04/21/mt-leaf.html

github:https://github.com/Meituan-Dianping/Leaf.git

下面一起来实践下Leaf的使用。

首先拉取 Leaf SpringBoot 封装依赖源码:

git clone -b feature/spring-boot-starter https://github.com/Meituan-Dianping/Leaf.git
cd leaf

使用 MavenLeaf 打到本地仓库中

mvn clean install -Dmaven.test.skip=true 

在这里插入图片描述

打包成功后,可以创建一个 SpringBoot 项目,在 pom 中加入下面依赖:

<dependency><artifactId>leaf-boot-starter</artifactId><groupId>com.sankuai.inf.leaf</groupId><version>1.0.1-RELEASE</version><exclusions><exclusion><groupId>com.alibaba</groupId><artifactId>druid</artifactId></exclusion><exclusion><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.6</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>

二、Leaf-segment 方式使用

首先创建leaf使用的数据库:

CREATE DATABASE leaf

创建ID规则表:

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;

写入两个 biz_tag

insert into leaf_alloc(biz_tag, max_id, step, description) values('test1', 1, 2000, '测试1');
insert into leaf_alloc(biz_tag, max_id, step, description) values('test2', 1, 2000, '测试2');

项目中加入leaf 和数据库配置:

leaf:name: test1segment:enable: trueurl: jdbc:mysql://localhost:3306/leaf?useUnicode=true&characterEncoding=utf8&serverTimezone=GMTusername: rootpassword: root

生成ID测试:

@Slf4j
@SpringBootTest
class LeafIdApplicationTests {@Resourceprivate SegmentService segmentService;@Testvoid contextLoads() {// 生成 1000 个IDStopWatch sw = new StopWatch();sw.start();for (int i = 0; i < 1000; i++) {long id1 = segmentService.getId("test1").getId();long id2 = segmentService.getId("test2").getId();log.info("id1: {}, id2: {}", id1, id2);}sw.stop();log.info(sw.prettyPrint());}}

在这里插入图片描述
可以看到在约 0.178 秒的时间,为两个业务场景生成了 1000ID

三、Leaf-snowflake 方式使用

这种模式依赖于 Zookeeper ,所以在实验前你需要有一个运行中的 Zookeeper 服务。

这种模式操作ZK使用 curator,因此需要引入 curator 的依赖:

<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>2.12.0</version>
</dependency>

在配置文件中开启Leaf-snowflake 模式:

leaf:name: test1segment:enable: trueurl: jdbc:mysql://localhost:3306/leaf?useUnicode=true&characterEncoding=utf8&serverTimezone=GMTusername: rootpassword: rootsnowflake:enable: trueaddress: 127.0.0.1port: 2181

生成ID测试:

@Slf4j
@SpringBootTest
class LeafIdApplicationTests {@Resourceprivate SegmentService segmentService;@Resourceprivate SnowflakeService snowflakeService;@Testvoid contextLoads() {// 生成 1000 个IDStopWatch sw = new StopWatch();sw.start();for (int i = 0; i < 1000; i++) {long id1 = snowflakeService.getId("test1").getId();long id2 = snowflakeService.getId("test2").getId();log.info("id1: {}, id2: {}", id1, id2);}sw.stop();log.info(sw.prettyPrint());}}

在这里插入图片描述

可以看到相比于上面数据库模式,仅需要约 0.0234105 秒,性能更高,而且做到ID不是顺序+1式增长。

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

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

相关文章

学生云服务器_学生云主机_学生云数据库_云+校园特惠套餐

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…

自注意力机制(Self-Attention)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站&#xff08;【http://www.aideeplearning.cn】&#xff09; Transformer模型中最关键部分就是自注意力&#xff08;Self-Attention&#xff09;机制&#xff0c;正如 Transformer 的论文的标题是“…

【Vue3】函数式编程(h 函数)

h 函数的原理就是 createVNode。可以使用 h 函数封装一些小组件。 <template><table border><tr><th>name</th><th>age</th><th>操作</th></tr><tr v-for"item in list" :key"item.age"&…

零拷贝技术深入分析

一、零拷贝 在前面的文章“深浅拷贝、COW及零拷贝”中对零拷贝进行过分析&#xff0c;但没有举例子&#xff0c;也没有深入进行展开分析。本文将结合实际的例程对零拷贝进行更深入的分析和说明。 在传统的IO操作中&#xff0c;以文件通过网络传输为例 &#xff0c;一般会经历以…

K8s控制器

控制器: Deployment: Deployment概述: replicaset:自动创建pod的控制器 Delpoyment控制器: pod的名字需要唯一,在这不写名字,利用标签进行创建 replicas:表示你想要克隆的数量,selector:通过标签.识别哪个pod是我创建出来的.这里的标签和后面元数据里的标签要一致. Cluster…

NCDA设计大赛获奖作品剖析:UI设计如何脱颖而出?

第十二届大赛简介 - 未来设计师全国高校数字艺术设计大赛&#xff08;NCDA&#xff09;开始啦&#xff01;视觉传达设计命题之一: ui 设计&#xff0c;你想知道的都在这里。为了让大家更好的参加这次比赛&#xff0c;本文特别为大家整理了以往NCDA大赛 UI 设计的优秀获奖作品&a…

2024年腾讯云优惠券_代金券_云服务器折扣券免费领取链接

腾讯云优惠代金券领取入口共三个渠道&#xff0c;腾讯云新用户和老用户均可领取8888元代金券&#xff0c;可用于云服务器等产品购买、续费和升级使用&#xff0c;阿腾云atengyun.com整理腾讯云优惠券&#xff08;代金券&#xff09;领取入口、代金券查询、优惠券兑换码使用方法…

【SpringBean】bean的作用域和bean的生命周期

目录 前言 一 bean的作用域 1. singleton——唯一 bean 实例 2. prototype——每次请求都会创建一个新的 bean 实例 3. request——每一次HTTP请求都会产生一个新的bean&#xff0c;该bean仅在当前HTTP request内有效 4. session——每一次HTTP请求都会产生一个新的 bean&…

程序员的金三银四求职宝典!

目录 ​编辑 程序员的金三银四求职宝典 一、为什么金三银四是程序员求职的黄金时期&#xff1f; 二、如何准备金三银四求职&#xff1f; 1. 完善简历 2. 增强技术能力 3. 提前考虑目标公司 4. 提前准备面试 三、程序员求职的常见面试题 1. 数据结构和算法 2. 数据库 …

一次电脑感染Synaptics Pointing Device Driver病毒的经历,分享下经验

没想到作为使用电脑多年的老司机也会电脑中病毒&#xff0c;周末玩电脑的时候突然电脑很卡&#xff0c;然后自动重启&#xff0c;奇怪&#xff0c;之前没出现这个情况。 重启后电脑开机等了几十秒&#xff0c;打开任务管理器查看开机进程&#xff0c;果然发现有个Synaptics Po…

LeetCode 刷题 [C++] 第121题.买卖股票的最佳时机

题目描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的…

php儿童服装销售管理系统计算机毕业设计项目包运行调试

php mysql儿童服装销售网 功能&#xff1a;前台后台 前台&#xff1a; 1.服装资讯 文章标题列表 详情 2.服装选购中心 分页查看图文列表 详情 3.用户注册 登陆 退出 4.服装加入收藏 5.加入购物车 6.对服装进行评论 会员中心&#xff1a; 1.我的账户 查看 修改 2.我的收藏 查看 …

STM32 中断流程介绍

STM32可以产生中断的事件多种多样&#xff0c;比如&#xff1a;定时器时间结束、串口接收到数据、某个GPIO检测到电平变化等等等等。 1、STM32 gpio 中断处理流程介绍 1、从引脚进入的高低电平首先由输入驱动器处理&#xff0c;如下图 2、经过输入驱动器处理后的信号会进…

c++基础知识补充4

单独使用词汇 using std::cout; 隐式类型转换型初始化&#xff1a;如A a1,,此时可以形象地理解为int i1;double ji;&#xff0c;此时1可以认为创建了一个值为1的临时对象&#xff0c;然后对目标对象进行赋值&#xff0c;当对象为多参数时&#xff0c;使用&#xff08;1&#xf…

c1-周考2

c1-第二周 9月-技能1.一个岛上有两种神奇动物&#xff0c;其中神奇鸟类2个头3只脚&#xff0c;神奇兽类3个头8只脚。游客在浓雾中看到一群动物&#xff0c;共看到35个头和110只脚&#xff0c;求可能的鸟类和兽类的只数2.构建一个长度为5的数组&#xff0c;并且实现下列要求3.构…

鬼屋游戏c++

c #include <iostream> #include <string> #include <vector> #include <cstdlib> // 用于随机数生成 #include <ctime> // 用于随机数种子using namespace std;// 定义房间结构体 struct Room {string description;bool hasKey;bool hasClue…

babylonjs入门-自由相机 FreeCamera

基于babylonjs封装的一些功能和插件 &#xff0c;希望有更多的小伙伴一起玩babylonjs&#xff1b; 欢迎加群&#xff08;点击群号传送&#xff09;&#xff1a;464146715 官方文档 中文文档 案例传送门 懒得打字 粘贴复制 一气呵成 ​

计算机网络——22TCP拥塞

TCP拥塞 TCP拥塞控制机制 端到端的拥塞控制机制 路由器不向主机有关拥塞的反馈信息 路由器的负担较轻符合网络核心简单的TCP/IP架构原则 端系统根据自身得到的信息&#xff0c;判断是否发生拥塞&#xff0c;从而采取动作 拥塞控制的几个问题 如何检测拥塞 轻微拥塞拥塞 控…

Http基础之http协议、无状态协议、状态码、http报文、跨域-cors

Http基础 HTTP基础HTTP协议请求方法持久连接管线化 无状态协议使用Cookie状态管理 状态码1XX2XX OK200 OK204 NO Content206 Content-Range 3XX 重定向301302304307 4XX400401403404 5XX500503 HTTP报文请求报文响应报文通用首部字段Cache-ControlConnectionDate请求首部字段Ac…

JVM 第四部分—垃圾回收相关概念 2

System.gc() 在默认情况下&#xff0c;通过System.gc()或者Runtime.getRuntime().gc()的调用&#xff0c;会显式触发Full GC&#xff0c;同时对老年代和新生代进行回收&#xff0c;尝试释放被丢弃对象占用的内存 然而System.gc()调用附带一个免责声明&#xff0c;无法保证对垃…