分布式ID是什么,以美团Leaf为例改造融入自己项目【第十一期】

前言

  • 在日常开发中,主键id应用是非常广泛的,但是当涉及到分布式系统的时候,往往需要使用到分布式id,每一个服务里面一套生成规则的不易管理,容易引发冲突。
  • 我的IM聊天系统中使用分布式id来生成消息唯一键,为后面幂等做准备。后续做幂等可以采用数据库唯一主键来做,也可以使用Redis token 令牌来做,但是都是需要唯一的分布式id。以及涉及到分布分表等场景也是会使用到。
  • 这篇文章重点介绍美团Leaf 号段的使用。Leaf是美团推出的一个分布式ID生成服务,名字取自德国哲学家、数学家莱布尼茨的一句话:“There are no two identical leaves in the world.”(“世界上没有两片相同的树叶”),取个名字都这么有寓意,美团程序员牛掰啊!就是自己的IM项目中目前测试阶段用户量也不大,使用号段完全可以顶的住。

本期对应视频,可从b站查看
目前已经写的文章有。并且有对应视频版本。
git项目地址 【IM即时通信系统(企聊聊)】点击可跳转
sprinboot单体项目升级成springcloud项目 【第一期】
前端项目技术选型以及页面展示【第二期】
分布式权限 shiro + jwt + redis【第三期】
给为服务添加运维模块 统一管理【第四期】
微服务数据库模块【第五期】
netty与mq在项目中的使用(第六期)】
分布式websocket即时通信(IM)系统构建指南【第七期】
分布式websocket即时通信(IM)系统保证消息可靠性【第八期】
分布式websocket IM聊天系统相关问题问答【第九期】
什么?websocket也有权限!这个应该怎么做?【第十期】

1.分布式id是什么

生成ID的方式多种多样,可以使用Redis键自增,UUID,或者基于雪花算法实现的ID生成服务。最常见的基于数据库ID自增的方式,在业务数据量不大的时候,单库单表可以支撑,数据再大一点搞个MySQL主从同步、读写分离也能对付。但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求。
伴随着业务快速迭代,很多业务都需要生成ID,每个微服务各自为政会陷入"重复造轮子"的低效劳动中,同时造成服务治理上的混乱,此时一个能够生成全局唯一ID的服务是非常必要的。那么这个全局唯一ID就叫分布式ID生成服务。

2.常见的分布式id方案

  • UUID 当然 不建议(狗头) 它的存储以及查询对 MySQL 的性能消耗较大,
  • 号段模式
    号段模式是当下分布式ID生成器的主流实现方式之一,号段模式可以理解为从数据库批量的获取自增ID,每次从数据库取出一个号段范围,例如 (1,1000] 代表1000个ID,具体的业务服务将本号段,生成1~1000的自增ID并加载到内存。
  • Redis
    基于全局唯一ID的特性,我们可以通过Redis的INCR命令来生成全局唯一ID。
    同样使用Redis也有对应的缺点:ID 生成的持久化问题,如果Redis宕机了怎么进行恢复
  • 雪花算法 雪花算法是 Twitter 提出的一种分布式ID生成算法。雪花算法可以在多台机器上生成不重复的ID,支持高并发和大规模的分布式系统。

具体的涉及方案可以网上了解,本期主要讲解美团的开源项目Leaf的分布式id,有两种模式可以进行选择,一种是号段模式,一种是雪花算法。

3.美团分布式id 号段原理

需要插入的数据库

CREATE TABLE `segment_id` (
  `biz_tag` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '业务类型',
  `max_id` BIGINT(20) NOT NULL DEFAULT '1' COMMENT '当前最大id',
  `step` INT(11) NOT NULL COMMENT '号段步长',
  `version` INT(20) NOT NULL COMMENT '版本号',
  `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`biz_tag`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

比如使用下面的SQL,当需要ID时,先发起查询,然后更新max_id,更新成功则表示获取到新号段[max_id, max_id+step)。

UPDATE segment_id SET max_id=max_id+step, VERSION = VERSION + 1 WHERE VERSION = #{version} and biz_tag = #{biz_tag};

在这里插入图片描述
可以从这张图上面看出不同的服务去请求分布式id发号器,然后去数据库中去取一个号段,然后存储起来起始值以及步长在缓存中进行分发,并且美团LeafLeaf还采用了双Buffer异步更新的策略,保证无论何时,都能有一个Buffer的号段可以正常对外提供服务。有兴趣的消小伙伴可以去了解下。

4.改造分布式id

美团的分布式id是基于mysql5.7的,然后就是数据库的版本比较老了,我们项目使用的数据库是Mysql8,需要改一下pom依赖,以及数据库连接池也不一样,也是需要改造一下 。
首先拿出core模块;

在这里插入图片描述
美团源码的这个部分直接拿了进去没有做一些更改,然后
在loginuser模块

4.1首先需要数据库建好,然后进行Mysql8的改造。

1.更改pom文件

  <mysql-connector-java.version>8.0.14</mysql-connector-java.version>

2.leaf.properties做下面修改

leaf.name=com.sankuai.leaf.opensource.test
# 开启号段模式
leaf.segment.enable=true
leaf.jdbc.url=jdbc:mysql://192.168.1.200:3307/leaf?characterEncoding=utf8&serverTimezone=Asia/Shanghai
leaf.jdbc.username=root
leaf.jdbc.driver-class-name=com.mysql.cj.jdbc.Driver
leaf.jdbc.password=123456
# 开启snowflake模式
leaf.snowflake.enable=false
leaf.snowflake.zk.address=localhost
leaf.snowflake.port=2181

springboot是2.2.5版本,durid是1.1.13 配置如下.

 datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/yan?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
      username: root
      password: root
      initial-size: 10
      max-active: 100
      min-idle: 10
      max-wait: 60000
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      #Oracle需要打开注释
      #validation-query: SELECT 1 FROM DUAL
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        #login-username: admin
        #login-password: admin
      filter:
        stat:
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: false
        wall:
          config:
            multi-statement-allow: true

dao层的实际应用.


@Mapper
public interface IDAllocMapper extends BaseMapper<LeafAlloc> {

    @Select("SELECT `key`, max_id, step, update_time FROM leaf_alloc")
    @Results(value = {
            @Result(column = "key", property = "key"),
            @Result(column = "max_id", property = "maxId"),
            @Result(column = "step", property = "step"),
            @Result(column = "update_time", property = "updateTime")
    })
    List<LeafAlloc> getAllLeafAllocs();

    @Select("SELECT `key`, max_id, step FROM leaf_alloc WHERE `key` = #{tag}")
    @Results(value = {
            @Result(column = "key", property = "key"),
            @Result(column = "max_id", property = "maxId"),
            @Result(column = "step", property = "step")
    })
    LeafAlloc getLeafAlloc(@Param("tag") String tag);

    @Update("UPDATE leaf_alloc SET max_id = max_id + step WHERE `key` = #{tag}")
    void updateMaxId(@Param("tag") String tag);

    @Update("UPDATE leaf_alloc SET max_id = max_id + #{step} WHERE `key` = #{key}")
    void updateMaxIdByCustomStep(@Param("leafAlloc") LeafAlloc leafAlloc);

    @Select("SELECT `key` FROM leaf_alloc")
    List<String> getAllTags();
}

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

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

相关文章

OpenHarmony RK3568 启动流程优化

目前rk3568的开机时间有21s&#xff0c;统计的是关机后从按下 power 按键到显示锁屏的时间&#xff0c;当对openharmony的系统进行了裁剪子系统&#xff0c;系统app&#xff0c;禁用部分服务后发现开机时间仅仅提高到了20.94s 优化微乎其微。在对init进程的log进行分析并解决其…

12V-80V车灯芯片都有哪些?-H5028L

电动车车灯芯片的工作原理可以简要概括为以下几点&#xff1a; 光源&#xff1a;电动车车灯通常使用LED&#xff08;Light Emitting Diode&#xff09;作为光源。LED是一种半导体器件&#xff0c;当电流通过LED时&#xff0c;它会发光。 驱动电路&#xff1a;车灯芯片中包含驱…

百度智能小程序开发平台:SEO关键词推广优化 带完整的搭建教程

移动互联网的普及&#xff0c;小程序成为了众多企业和开发者关注的焦点。百度智能小程序开发平台为开发者提供了一站式的解决方案&#xff0c;帮助企业快速搭建并推广自己的小程序。本文将重点介绍百度智能小程序开发平台的SEO关键词推广优化功能&#xff0c;并带完整的搭建教程…

保护医疗数据不受威胁:MPLS专线在医疗网络安全中的角色

随着数字技术的快速发展&#xff0c;医疗行业正在经历一场革命。从电子健康记录到远程医疗服务&#xff0c;数字化不仅提高了效率&#xff0c;也带来了前所未有的挑战--尤其是关于数据安全和隐私保护的挑战。在这样的背景下&#xff0c;如何确保敏感的医疗数据安全传输&#xf…

github添加 SSH 密钥

1 打开终端 输入 ssh-keygen -t rsa -b 4096 -C "github邮箱地址"如果不需要密码可以一路回车 出现这个页面就是生存成功了 open ~/.ssh // 打开.ssh 找到id_rsa.pub复制出内容新建ssh密钥输入内容,保存即可

本地部署Tale博客网站并结合内网穿透实现公网访问本地站点

文章目录 前言1. Tale网站搭建1.1 检查本地环境1.2 部署Tale个人博客系统1.3 启动Tale服务1.4 访问博客地址 2. Linux安装Cpolar内网穿透3. 创建Tale博客公网地址4. 使用公网地址访问Tale 前言 今天给大家带来一款基于 Java 语言的轻量级博客开源项目——Tale&#xff0c;Tale…

数字人解决方案VividTalk——音频驱动单张照片实现人物头像说话的效果

前言 VividTalk是一项由南京大学、阿里巴巴、字节跳动和南开大学共同开发的创新项目。该项目通过结合单张人物静态照片和一段语音录音&#xff0c;能够制作出一个看起来仿佛实际说话的人物视频。项目的特点包括自然的面部表情和头部动作&#xff0c;口型能够同步&#xff0c;同…

C++ 数论相关题目:卡特兰数应用、快速幂求组合数。满足条件的01序列

给定 n 个 0 和 n 个 1 &#xff0c;它们将按照某种顺序排成长度为 2n 的序列&#xff0c;求它们能排列成的所有序列中&#xff0c;能够满足任意前缀序列中 0 的个数都不少于 1 的个数的序列有多少个。 输出的答案对 1097 取模。 输入格式 共一行&#xff0c;包含整数 n 。 …

“全”实力认可 | 美创科技领跑CCSIP 2023全景图数据安全领域

近日&#xff0c;FreeBuf咨询正式发布《CCSIP&#xff08;China Cyber Security Industry Panorama&#xff09;2023中国网络安全行业全景册&#xff08;第六版&#xff09;》。本次全景册面向广大国内安全厂商&#xff0c;由厂商自主申报并填写信息征集表&#xff0c;经FreeBu…

Android 中的动态应用程序图标

Android 中的动态应用程序图标 一、需求二、解决方案三、方案实现四、结论 一、需求 您可能遇到过那些可以实现巧妙技巧的应用程序 - 更改应用程序图标&#xff08;也许是在您的生日那天&#xff09;&#xff0c;然后无缝切换回常规图标。这种功能会激起你的好奇心&#xff0c…

网络防御安全:2-6天笔记

第二章&#xff1a;防火墙 一、什么是防火墙 防火墙的主要职责在于&#xff1a;控制和防护。 防火墙可以根据安全策略来抓取流量之后做出对应的动作。 二、防火墙的发展 区域&#xff1a; Trust 区域&#xff0c;该区域内网络的受信任程度高&#xff0c;通常用来定义内部…

TensorFlow2实战-系列教程9:RNN文本分类1

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、文本分类任务 1.1 文本分类 数据集构建&#xff1a;影评数据集进行情感分析&…

Leetcode 206 反转链表

反转链表 准备工作1&#xff09;ListNode基本结构2&#xff09;初始化ListNode集合 解法一&#xff1a;遍历创建新节点解法二&#xff1a;两组List&#xff0c;面向对象操作解法三&#xff1a;递归调用解法四&#xff1a;直接移动解法五&#xff1a;解法二的面向过程 Leetcode …

spring cloud activiti 审批流的用法

demo的搭建及使用 1、创建activiti审批流需要安装bpmn插件&#xff0c;新的idea版本支持的这个bpmn插件只有下图这个&#xff0c;并不好用&#xff0c;所以我这里使用eclipse来创建bpmn流程 eclipse的连接如下&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1mSoKprN-…

基于Java SSM框架实现药品销售系统项目【项目源码+论文说明】

基于java的SSM框架实现药品销售系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个药品销售系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述药品销…

原生table样式

HTML <div><table style"width: 100%;"><thead><tr><th style"width:25%;">董事会</th><th style"width:25%;">监事会</th><th style"width:25%;">股东</th><th sty…

【Vue】前端项目引入阿里图标

【Vue&React】前端项目引入阿里图标 1、登录自己的iconfont-阿里巴巴矢量图标库&#xff0c;把需要的图标加入到自己的项目中去&#xff1b;2、加入并进入到项目中去选择Font class 并下载到本地3、得到的文件夹如下4. 把红框中的部分粘贴到自己的项目中&#xff08; stati…

CRG设计之复位

1. 前言 CRG(Clock and Reset Generation&#xff0c;时钟复位生成模块) 模块扮演着关键角色。这个模块负责为整个系统提供稳定可靠的时钟信号&#xff0c;同时在系统上电或出现故障时生成复位信号&#xff0c;确保各个模块按预期运行。简而言之&#xff0c;CRG模块就像是SoC系…

nginx无法启动,win10占用80端口 (注册表方式解决)

参考&#xff1a;https://blog.csdn.net/qq_39523111/article/details/128853509 改为4 重启后 不再占用 pid 不是4了 已经变为nginx了 改为0 没起作用

蓝桥杯2024/1/26笔记-----基于PCF8591的电压采集装置

功能实现要求&#xff1a; 每次建好工程文件夹&#xff0c;里边包含User&#xff08;放工程文件&#xff0c;mian.c&#xff0c;可以在这里写如同我这个文章的文本文档&#xff09;、Driver&#xff08;存放底层文件如Led.c&#xff0c;Led.h等&#xff09; 新建的工程先搭建框…
最新文章