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

这篇具有很好参考价值的文章主要介绍了美团分布式 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,对于时钟回拨问题,解决方案如下:

美团leaf,微服务,分布式

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

官方介绍地址: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 

美团leaf,微服务,分布式

打包成功后,可以创建一个 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());
    }

}

美团leaf,微服务,分布式
可以看到在约 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());
    }

}

美团leaf,微服务,分布式

可以看到相比于上面数据库模式,仅需要约 0.0234105 秒,性能更高,而且做到ID不是顺序+1式增长。文章来源地址https://www.toymoban.com/news/detail-861666.html

到了这里,关于美团分布式 ID 框架 Leaf 介绍和使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【项目实战】分布式计算和通信框架(AKKA)入门介绍

    Akka是一个用于构建高并发、分布式、可容错、事件驱动的应用程序的工具包和运行时。它基于Actor模型,提供了一种高效的并发编程模型,可以轻松地编写出高并发、分布式、可容错的应用程序。Akka还提供了一些常用的组件,如路由、集群、持久化等,可以帮助开发人员更加

    2024年02月08日
    浏览(11)
  • 【分布式】分布式ID

    分布式场景下,一张表可能分散到多个数据结点上。因此需要一些分布式ID的解决方案。 分布式ID需要有几个特点: 全局唯一(必要) :在多个库的主键放在一起也不会重复 有序(必要) :避免频繁触发索引重建 信息安全 :ID连续,可以根据订单编号计算一天的单量,造成

    2024年02月07日
    浏览(16)
  • 【分布式技术专题】「分布式ID系列」百度开源的分布式高性能的唯一ID生成器UidGenerator

    UidGenerator是什么 UidGenerator是百度开源的一款分布式高性能的唯一ID生成器,更详细的情况可以查看官网集成文档 uid-generator是基于Twitter开源的snowflake算法实现的一款唯一主键生成器(数据库表的主键要求全局唯一是相当重要的)。要求java8及以上版本。 snowflake算法 Snowflake算法描

    2024年02月04日
    浏览(23)
  • 分布式id实战

    目录 常用方式 特征 潜在问题 信息安全 高性能 UUID 雪花算法 数据库生成 美团Leaf方案 Leaf-segment 数据库方案 Leaf-snowflake 方案 uuid 雪花算法 数据库主键 全局唯一 趋势递增 信息安全 如果id连续递增, 容易被爬虫, 批量下载数据 如果订单id是连续递增, 容易被竞争对手推算出日交

    2024年02月21日
    浏览(10)
  • 分布式ID(2):雪花算法生成ID

    1 雪花算法简介 这种方案大致来说是一种以划分命名空间(UUID也算,由于比较常见,所以单独分析)来生成ID的一种算法,这种方案把64-bit分别划分成多段,分开来标示机器、时间等,比如在snowflake中的64-bit分别表示如下图(图片来自网络)所示: 41-bit的时间可以表示(1L

    2024年01月20日
    浏览(16)
  • 分布式唯一ID实战

    UUID的标准形式包含32个16进制数字,以 “ - ” 进行分割,形式为 8-4-4-4-12的32个字符,实例 550e8400-e29b-41d4-a716-446655440000。 优点: - 性能高,本地生成,没有网络消耗 缺点: - 不易存储,长度太长,32个16进制数字,128位 - 不安全,会暴露MAC地址 - UUID作为MySQL主键,会导致索引

    2024年02月12日
    浏览(10)
  • 架构设计-分布式ID

    1.不要用主键ID作为业务单号的唯一标识,因为一是数据同步麻烦,第二一旦业务数据扩张涉及到分库分表则数据维护麻烦,因为此时主键ID容易造成重复 。 2.对于有相似属性的业务ID如直播或者录播ID存储在业务表中的一个字段,一旦程序员哪天状态不好忘记区分类型,就很

    2024年02月03日
    浏览(46)
  • 算法、语言混编、分布式锁与分布式ID、IO模型

    数据结构和算法是程序的基石。我们使用的所有数据类型就是一种数据结构(数据的组织形式),写的程序逻辑就是算法。 算法是指用来操作数据、解决程序问题的一组方法。 对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源(空间

    2024年02月08日
    浏览(12)
  • 分布式ID系统设计(3)

    第二集说了id-service-Segment-DB可以生成趋势递增的ID,但是ID号是可以计算的。不太适用于一些订单ID生成的场景。因为存在数据暴露的风险 比如我可以对比两天的订单ID号来大致计算出公司一天的订单量。这个有点危险。 所以我们需要id-serviceSnowFlake方案。 id-service-snowFlake完全沿

    2024年02月06日
    浏览(17)
  • 分布式ID系统设计(1)

    我们姑且把它叫做id-server 。那么这么个id-server的设计和考虑需要什么 全局唯一:不能出现重复的id号 最基本要求。 趋势递增: 在innodb中使用的是聚集索引。B+Tree的pk最好是有序的 单调递增:保证下一个id一定要大于上一个id 安全:如果ID是连续的 被爬虫的可能性能就很大。有一些

    2024年02月08日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包