美团分布式 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: test1
  segment:
    enable: true
    url: jdbc:mysql://localhost:3306/leaf?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
    username: root
    password: root

生成ID测试:

@Slf4j
@SpringBootTest
class LeafIdApplicationTests {

    @Resource
    private SegmentService segmentService;

    @Test
    void contextLoads() {
        // 生成 1000 个ID
        StopWatch 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: test1
  segment:
    enable: true
    url: jdbc:mysql://localhost:3306/leaf?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
    username: root
    password: root
  snowflake:
    enable: true
    address: 127.0.0.1
    port: 2181

生成ID测试:

@Slf4j
@SpringBootTest
class LeafIdApplicationTests {

    @Resource
    private SegmentService segmentService;

    @Resource
    private SnowflakeService snowflakeService;

    @Test
    void contextLoads() {
        // 生成 1000 个ID
        StopWatch 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.mfbz.cn/a/424217.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

凌特杯,第二届,数字音频传输。simulink matlab

终于比赛进入了尾声&#xff0c;最为指导老师也是非常的激动。接下来进入了论文写作阶段和视频拍摄阶段。 第二届凌特杯规定的硬件是ADI的Pluto&#xff0c;成本在2k以内&#xff0c;能支持MATLAB&#xff0c;它能够流畅的实时播放接收到的音乐数据&#xff0c;并把数据保存成…

图论例题解析

1.图论基础概念 概念 &#xff08;注意连通非连通情况&#xff0c;1节点&#xff09; 无向图&#xff1a; 度是边的两倍&#xff08;没有入度和出度的概念&#xff09; 1.完全图&#xff1a; 假设一个图有n个节点&#xff0c;那么任意两个节点都有边则为完全图 2.连通图&…

Mysql列子查询

目录 列子查询数据准备 列子查询 子查询返回的结果是一列(可以是多行)&#xff0c;这种子查询称为列子查询。 常用的操作符&#xff1a; 操作符描述IN在指定的集合范围之内&#xff0c;多选一NOT IN不在指定的集合范围之内 案例&#xff1a;查询"教研部"和"…

【UE 材质】冰冻效果

效果 步骤 1. 打开“Quixel Bridge” 下载冰的纹理 2. 新建一个材质&#xff0c;这里命名为“M_Frozen” 打开“M_Frozen”&#xff0c;添加如下节点&#xff0c;此时我们可以通过控制参数“偏移”来改变边界的偏移 此时预览效果如下 如果增加参数“偏移”的默认值效果如下 3.…

Transformer中的自注意力机制计算过程分析

目录 1 什么是自注意力机制 2 自注意力的计算过程 1 什么是自注意力机制 自注意力机制&#xff08;Self-Attention&#xff09;顾名思义就是关注单个序列内部元素之间的相关性&#xff0c;不仅可以用于 seq2seq 的机器翻译模型&#xff0c;还能用于情感分析、内容提取等场景…

Doris实战——美联物业数仓

目录 一、背景 1.1 企业背景 1.2 面临的问题 二、早期架构 三、新数仓架构 3.1 技术选型 3.2 运行架构 3.2.1 数据模型 纵向分域 横向分层 数据同步策略 3.2.2 数据同步策略 增量策略 全量策略 四、应用实践 4.1 业务模型 4.2 具体应用 五、实践经验 5.1 数据…

Spring Boot项目中不使用@RequestMapping相关注解,如何动态发布自定义URL路径

一、前言 在Spring Boot项目开发过程中&#xff0c;对于接口API发布URL访问路径&#xff0c;一般都是在类上标识RestController或者Controller注解&#xff0c;然后在方法上标识RequestMapping相关注解&#xff0c;比如&#xff1a;PostMapping、GetMapping注解&#xff0c;通…

Java项目:30 基于SpringBoot自习室座位预定系统

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 功能设计 管理员 1、用户管理 管理员可以新增、删除管理员 管理员可以删除学生 2、自习室管理 管理员可以新增自习室、设置自习室的座位…

关于福彩历史数据采集器和体彩历史数据采集器的下载安装说明

前段时间因为研究基于人工神经网络&#xff08;深度学习&#xff0c;所谓的“AI”算法&#xff09;对3D开奖数据进行预测&#xff0c;开发了两款浏览器插件----“福彩历史数据采集器”和“体彩历史数据采集器”。之所以开发这两款插件&#xff0c;是因为不管是基于什么样的方式…

机器学习:集成学习(Python)

一、Adaboost算法 1.1 Adaboost分类算法 adaboost_discrete_c.py import numpy as np import copy from ch4.decision_tree_C import DecisionTreeClassifierclass AdaBoostClassifier:"""adaboost分类算法&#xff1a;既可以做二分类、也可以做多分类&#…

缓存相关问题:雪崩、穿透、预热、更新、降级的深度解析

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 1. 缓存雪崩 1.1 问题描述 1.2 解决方案 1.2.1 加锁防止并发重建缓存 2. 缓存穿透 2.1 问题描述 2.2 解决方案 2.2.1 …

Ubuntu下安装Scala

前言 弄了一下终于成功装上了&#xff0c;这里对此进行一下总结 安装虚拟机 VMware虚拟机安装Ubuntu&#xff08;超详细图文教程&#xff09;_vmware安装ubuntu-CSDN博客https://blog.csdn.net/qq_43374681/article/details/129248167Download Ubuntu Desktop | Download | …

FinalShell连接Linux

远程连接linux 我们使用VMware可以得到Linux虚拟机&#xff0c;但是在/Mware中操作Linux的命令行页面不太方便&#xff0c;主要是: 内容的复制、粘贴跨越VMware不方便 文件的上传、下载跨越VMware不方便 不方便也就是和Linux系统的各类交互&#xff0c;跨越VMwar 到Linux操作系…

win11 更多网络适配器选项

win11更多网络适配器选项查找路径&#xff1a;控制面板→网络和共享中心→更改适配器设置

计算机二级Python刷题笔记------基本操作题23、33、35、37(考察字符串)

文章目录 第二十三题&#xff08;字符串替换&#xff1a;replace(old,new)&#xff09;第三十三题&#xff08;字符串遍历&#xff09;第三十五题&#xff08;字符串与列表&#xff09;第三十七题&#xff08;拼接字符串&#xff09; 第二十三题&#xff08;字符串替换&#xf…

Ubuntu进入python时报错:找不到命令 “python”,“python3” 命令来自 Debian 软件包 python3

一、错误描述 二、解决办法 进入”/usr/bin”目录下&#xff0c;查看/usr/bin目录中所有与python相关的文件和链接&#xff1a; cd /usr/bin ls -l | grep python 可以看到Python3指向的是Python3.10&#xff0c;而并无指向python3的软连接 只需要在python与python3之间手动…

2024.03.02蓝桥云课笔记

1.scanf与printf取消分隔符的限制方法 示例代码&#xff1a; int main() { char s[10];scanf("%d[^\n]",s);printf("%s",s);return 0; } 运行&#xff1a; 输入&#xff1a;Hello World 输出&#xff1a;Hello World 注&#xff1a;其中[]中是一个正则…

YTM32的同步串行通信外设SPI外设详解(Master Part)

YTM32的同步串行通信外设SPI外设详解&#xff08;Master Part&#xff09; 文章目录 YTM32的同步串行通信外设SPI外设详解&#xff08;Master Part&#xff09;IntroductionFeatures引脚信号时钟源其它不常用功能 Pricinple & Mechinism基于FIFO的命令和数据管理机制锁定配…

19. 学习人工智能如何从阅读论文中获取一手信息,并推荐一些技术论文

本文为 「茶桁的 AI 秘籍 - BI 篇 第 19 篇」 文章目录 Hi&#xff0c;你好。我是茶桁。 上节课给大家预告了&#xff0c;今天这节课咱们来看一篇论文。我们之前几节课中讲解的内容其实是在一些论文里面有使用到的。 我们先看一下论文的内容&#xff0c;讲讲 ALS。 就像我上节…

unsubscribe:Angular 项目中常见场景以及是否需要 unsubscribe

本文由庄汇晔同学编写~ 在 Angular 项目中&#xff0c;经常会使用到 observable subscribe&#xff0c;但是 subscribe 读取了数据之后&#xff0c;真的就是万事大吉了吗&#xff1f;这个问题的答案或许是&#xff0c;或许不是。有些 observable 需要 unsubscribe&#xff0c;…
最新文章