做网站应该拿多少提成,微信小程序开发文档下载,遵义建站平台哪家好,百度账号怎么改名字一、Leaf
在当今日益数字化的世界里#xff0c;软件系统的开发已经成为了几乎所有行业的核心。然而#xff0c;随着应用程序的规模不断扩大#xff0c;以及对性能和可扩展性的需求不断增加#xff0c;传统的软件架构和设计模式也在不断地面临挑战。其中一个主要挑战就是如…一、Leaf
在当今日益数字化的世界里软件系统的开发已经成为了几乎所有行业的核心。然而随着应用程序的规模不断扩大以及对性能和可扩展性的需求不断增加传统的软件架构和设计模式也在不断地面临挑战。其中一个主要挑战就是如何有效地处理分布式环境中的唯一标识问题。这正是分布式ID 的重要性所在。
分布式ID的实现方式有多种多样常见的包括 UUID、Snowflake 算法、Twitter 的 Snowflake 算法、基于数据库的自增长ID 等。每种方式都有其适用的场景和优缺点。
比如常见的 UUID , 标准型式包含32个16进制数字以连字号分为五段形式为8-4-4-4-12的36个字符优点是性能非常高本地生成没有网络消耗但缺点也显而易见首先不易于存储UUID太长16字节128位通常以36长度的字符串表示很多场景不适用。其次信息不安全基于MAC地址生成UUID的算法可能会造成MAC地址泄露这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。也不适合作为DB的主键。MySQL官方有明确的建议主键要尽量越短越好。
基于数据库的自增长ID 的方式实现起来非常简单并且ID是单向自增顺序的但缺点也很明显过度依赖于 DB 数据库在并发量高的情况下数据库成为了性能瓶颈。
基于Snowflake 算法的方式可以解决上述提到的问题并且稳定性和灵活性都非常高但强依赖于机器时钟如果机器上时钟回拨会导致发号重复或者服务会处于不可用状态。
既然如此那下面我们来认识更强大的分布式ID生成器 Leaf 它是美团开源的分布式 ID 生成器旨在解决分布式系统中的唯一标识生成问题确保在分布式环境下生成的 ID 具有全局唯一性、顺序性和高性能。
Leaf 实现了Leaf-segment和Leaf-snowflake两种方案。
Leaf-segment是一种基于数据库的分布式 ID 生成方案原始基于数据库的自增长ID 方案每次获取ID都得读写一次数据库造成数据库压力大该方案利用proxy server批量获取每次获取一个segment(step决定大小)号段的值。用完之后再去数据库获取新的号段可以大大的减轻数据库的压力。各个业务不同的发号需求用biz_tag字段来区分每个biz-tag的ID获取相互隔离互不影响。如果以后有性能需求需要对数据库扩容不需要上述描述的复杂的扩容操作只需要对biz_tag分库分表就行。
Leaf-snowflake方案完全沿用snowflake方案的bit位设计对于workerID的分配使用Zookeeper持久顺序节点的特性自动对snowflake节点配置wokerID对于时钟回拨问题解决方案如下 更多介绍可以参考官方信息 官方介绍地址https://tech.meituan.com/2017/04/21/mt-leaf.html githubhttps://github.com/Meituan-Dianping/Leaf.git 下面一起来实践下Leaf的使用。
首先拉取 Leaf SpringBoot 封装依赖源码
git clone -b feature/spring-boot-starter https://github.com/Meituan-Dianping/Leaf.gitcd leaf使用 Maven 将 Leaf 打到本地仓库中
mvn clean install -Dmaven.test.skiptrue 打包成功后可以创建一个 SpringBoot 项目在 pom 中加入下面依赖
dependencyartifactIdleaf-boot-starter/artifactIdgroupIdcom.sankuai.inf.leaf/groupIdversion1.0.1-RELEASE/versionexclusionsexclusiongroupIdcom.alibaba/groupIdartifactIddruid/artifactId/exclusionexclusiongroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/exclusion/exclusions/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.1.6/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-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)
) ENGINEInnoDB;写入两个 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?useUnicodetruecharacterEncodingutf8serverTimezoneGMTusername: 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 秒的时间为两个业务场景生成了 1000个ID。
三、Leaf-snowflake 方式使用
这种模式依赖于 Zookeeper 所以在实验前你需要有一个运行中的 Zookeeper 服务。
这种模式操作ZK使用 curator因此需要引入 curator 的依赖
dependencygroupIdorg.apache.curator/groupIdartifactIdcurator-recipes/artifactIdversion2.12.0/version
/dependency在配置文件中开启Leaf-snowflake 模式
leaf:name: test1segment:enable: trueurl: jdbc:mysql://localhost:3306/leaf?useUnicodetruecharacterEncodingutf8serverTimezoneGMTusername: 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式增长。