分布式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.DruidDataSourcedruid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/yan?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: rootpassword: rootinitial-size: 10max-active: 100min-idle: 10max-wait: 60000pool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 20time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000#Oracle需要打开注释#validation-query: SELECT 1 FROM DUALtest-while-idle: truetest-on-borrow: falsetest-on-return: falsestat-view-servlet:enabled: trueurl-pattern: /druid/*#login-username: admin#login-password: adminfilter:stat:log-slow-sql: trueslow-sql-millis: 1000merge-sql: falsewall: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.rhkb.cn/news/247874.html

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

相关文章

Flink CEP实现10秒内连续登录失败用户分析

1、什么是CEP&#xff1f; Flink CEP即 Flink Complex Event Processing&#xff0c;是基于DataStream流式数据提供的一套复杂事件处理编程模型。你可以把他理解为基于无界流的一套正则匹配模型&#xff0c;即对于无界流中的各种数据(称为事件)&#xff0c;提供一种组合匹配的…

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

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

单片机介绍

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

electron-builder vue 打包后element-ui字体图标不显示问题

当使用electron打包完成的时候&#xff0c;启动项目发现使用的element-ui字体图标没显示都变成了小方块&#xff0c;并出现报错&#xff0c;请看下图&#xff1a; 解决方法&#xff1a; 在vue.config.js中设置 customFileProtocol字段&#xff1a;pluginOptions: {electronBui…

两个近期的计算机领域国际学术会议(软件工程、计算机安全):欢迎投稿

近期&#xff0c;受邀担任两个国际学术会议的Special session共同主席及程序委员会成员&#xff08;TPC member&#xff09;&#xff0c;欢迎广大学界同行踊跃投稿&#xff0c;分享最新研究成果。期待这个夏天能够在夏威夷檀香山或者加利福尼亚圣荷西与各位学者深入交流。 SERA…

防御保护常用知识

防火墙的主要职责在于&#xff1a;控制和防护 --- 安全策略 --- 防火墙可以根据安全策略来抓取流量之 后做出对应的动作 防火墙分类主要有四类&#xff1a; 防火墙吞吐量 --- 防火墙同一时间能处理的数据量多少 防火墙的发展主要经过以下阶段&#xff1b; 传统防火墙&#xf…

格子表单GRID-FORM | 嵌套子表单与自定义脚本交互

格子表单/GRID-FORM已在Github 开源&#xff0c;如能帮到您麻烦给个星&#x1f91d; GRID-FORM 系列文章 基于 VUE3 可视化低代码表单设计器嵌套表单与自定义脚本交互 新版本功能 &#x1f389; 不觉间&#xff0c;GRID-FORM 已经开源一年&#xff08;2023年1月29日首次提交…

大数据StarRocks(八):资源隔离实战

前言 自 2.2 版本起&#xff0c;StarRocks 支持资源组管理&#xff0c;集群可以通过设置资源组&#xff08;Resource Group&#xff09;的方式限制查询对资源的消耗&#xff0c;实现多租户之间的资源隔离与合理利用。在 2.3 版本中&#xff0c;StarRocks 支持限制大查询&#…

HAL STM32+EC11编码器实现增减调节及单击、双击、长按功能

HAL STM32EC11编码器实现增减调节及单击、双击、长按功能 &#x1f4fa;实现效果演示&#xff1a; &#x1f4d8;内容提要 &#x1f4dd;本文主要实现&#xff0c;通过STM32 HAL库开发&#xff0c;实现的EC11编码器功能&#xff0c;按键结合状态机思想实现的拓展单击、双击、…

Linux之快速入门(CentOS 7)

文章目录 一、Linux目录结构二、常用命令2.1 切换用户2.2查看ip地址2.3 cd2.4 目录查看2.5 查看文件内容2.6 创建目录及文件2.7 复制和移动2.8 其他2.9 tar3.0 which3.1 whereis3.2 find&#xff08;这个命令尽量在少量用户使用此软件时运行&#xff0c;因为此命令是真的读磁盘…

计数排序(六)——计数排序及排序总结

目录 一.前言 二.归并小补充 三.计数排序 操作步骤&#xff1a; 代码部分&#xff1a; 四.稳定性的概念&#xff1a; 五.排序大总结&#xff1a; ​六.结语 一.前言 我们已经进入排序的尾篇了&#xff0c;本篇主要讲述计数排序以及汇总各类排序的特点。码字不易&#x…

【JavaScript 漫游】【002】JS 的数据类型总览

文章简介 本文为【JavaScript 漫游】专栏的第 002 篇文章&#xff0c;主要记录了笔者学习 JS 数据类型中所了解的基本知识点。 ES5 的数据类型有哪些如何区分 ES5 的数据类型null 和 undefined 的相同点和不同点布尔值的转换规则parseInt 和 parseFloat 的基本用法 作为 JS …

使用plotly dash 画3d圆柱(Python)

plotly3D &#xff08;3d charts in Python&#xff09;可以画3维图形 在做圆柱的3D装箱项目&#xff0c;需要装箱的可视化&#xff0c;但是Mesh &#xff08;3d mesh plots in Python&#xff09;只能画三角形&#xff0c;所以需要用多个三角形拼成一个圆柱&#xff08;想做立…

网站小程序分类目录网源码系统+会员注册登录功能 附带完整的搭建教程

随着互联网的发展&#xff0c;小程序分类目录网站已经成为了人们获取各类信息的重要渠道。而在这个领域中&#xff0c;罗峰给大家分享一款网站小程序分类目录网源码系统以其强大的功能和易用性&#xff0c;脱颖而出。本系统集成了会员注册登录功能&#xff0c;让用户能够更加便…

【git】git update-index --assume-unchanged(不改动.gitignore实现忽略文件)

文章目录 原因分析&#xff1a;添加忽略文件(取消跟踪)的命令&#xff1a;取消忽略文件(恢复跟踪)的命令&#xff1a;查看已经添加了忽略文件(取消跟踪)的命令&#xff1a; 原因分析&#xff1a; 已经维护的项目&#xff0c;文件已经被追踪&#xff0c;gitignore文件不方便修…

Layui + Echarts 5.0

Layui 怎么整合最新版本的 Echarts 5.0&#xff0c;Echarts 4 升级到 5后&#xff0c;有了很大改变&#xff0c;新的配置项4是无法兼容的&#xff0c;所以想要使用新的功能&#xff0c;都需要升级&#xff01; 新建一个echarts.js文件 layui.define(function (exports) {// 这…

Optional lab: Linear Regression using Scikit-LearnⅠ

scikit-learn是一个开源的、可用于商业的机器学习工具包&#xff0c;此工具包包含本课程中需要使用的许多算法的实现 Goals In this lab you will utilize scikit-learn to implement linear regression using Gradient Descent Tools You will utilize functions from sci…

微服务技术总结

微服务&#xff01; SrpingClound 微服务主要解决项目拆分后所产生的一系列问题。SpringClound主要解决服务的治理问题 单体VS分布式 单体&#xff1a;部署简单、成本低 缺点&#xff1a;服务耦合度高 2兼容1 服务拆分注意事项 远程调用分析 提供者&#xff1a;服务的提供方…

QT 使用XML保存操作记录

文章目录 1 实现程序保存操作记录的思路2 XML文档基本结构3 QDomDocument实现XML读写3.1 QDomDocument实现生成XML文件3.2 QDomDocument实现读取XML文件 4 QXmlStreamWriter实现读写4.1 QXmlStreamWriter实现生成XML4.2 QXmlStreamWriter实现读取XML 1 实现程序保存操作记录的思…

【大数据】Flink 架构(三):事件时间处理

《Flink 架构》系列&#xff08;已完结&#xff09;&#xff0c;共包含以下 6 篇文章&#xff1a; Flink 架构&#xff08;一&#xff09;&#xff1a;系统架构Flink 架构&#xff08;二&#xff09;&#xff1a;数据传输Flink 架构&#xff08;三&#xff09;&#xff1a;事件…