范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

分布式微服务系统下,如何生成全局唯一ID?

  缘起
  在分布式微服务系统架构下,有非常多的情况我们需要生成一个全局唯一的 ID 来做标识,比如:需要分库分表的情况下,分库或分表会导致表本事的自增键不具备唯一性。较长的业务链路涉及到多个微服务之间的调用,需要一个唯一 ID 来标识比如订单 ID、消息 ID、优惠券 ID、分布式事务全局事务 ID。
  对于全局唯一 ID 来说,通常具备以下特点:全局唯一性:ID 不会重复,这个是全局唯一 ID 最基本的特性趋势递增:考虑到类似 MySQL 数据存储是基于 B+ 树的聚簇索引,非趋势递增会导致写入性能受到影响。单调递增:保证上一个 ID 的大小一定小于下一个 ID,对于某些有排序需求的场景有一定的必要性,比如 IM 消息触达到端,或者就是单纯的有需要基于 ID 进行排序的需求。信息安全:如果 ID 可以被简单的枚举出来,那么有潜在的数据安全问题。并且如果是订单号的场景,通过订单号的简单相减就预估出当天的订单量的话,会导致商业数据泄漏。
  可以发现 1 是我们必须去保证的,2 尽可能保证,3 和 4 一定程度上是互斥的,无法通过一个方案来实现。并且在这个基础上,全局唯一 ID 的生成需要做到高性能(TP999 的响应耗时要尽可能小)以及高稳定性(可用性 5 个 9)。常见方案
  通常来说全局唯一 ID 的生成方案也分几类:单机自行生成,不依赖其他服务,来保证全局唯一性。应用集群,应用服务的业务场景内保证全局唯一 ID。独立服务提供通用的生产全局唯一 ID 的能力。
  下面来具体介绍业界常见的一些方案:UUID
  UUID 是通用唯一识别码(Universally Unique Identifier)的缩写,开放软件基金会(OSF)规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素。利用这些元素来生成 UUID。
  UUID 一共有 5 个版本:版本1 - 基于时间的 UUID:主要依赖当前的时间戳及机器 mac 地址,因此可以保证全球唯一性。版本2 - 分布式安全的 UUID:将版本1的时间戳前四位换为 POSIX 的 UID 或 GID,很少使用。版本3 - 基于名字空间的 UUID(MD5 版):基于指定的名字空间/名字生成 MD5 散列值得到,标准不推荐。版本4 - 基于随机数的 UUID:基于伪随机数,生成 16byte 随机值填充 UUID。重复机率与随机数产生器的质量有关。版本5 - 基于名字空间的 UUID(SHA1版):将版本 3 的散列算法改为 SHA1。
  大家多数情况下使用的是 v4 版本,Node.js 的 uuid 包支持所有版本的 uuid 生成。Java 的 UUID.randomUUID() 是基于 v4 版本,UUID.nameUUIDFromBytes() 是基于 v3 版本。
  UUID 的优势:本地生成,不依赖外部服务,生成的性能也还不错。
  UUID 的劣势:v1 版本存在信息安全问题,直接将 mac 地址暴露出去,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。v3、v5 都是在命名空间 + 名称输入的情况下可以输出统一的 UUID,不适合用于唯一 ID 生成。v4 版本如果基于伪随机数,理论上会存在出现重复的概率。通常在数据库中存储为字符串,相比整型会花费更多存储空间。字符串无法保证有序,在 MySQL 基于 B+ 树的聚簇索引结构下,写入性能不佳。
  在一些简单场景下,对于性能的要求不严格,并且系统并发不高的情况下,使用 UUID 可能是最简单、最低成本的方案。数据库自增键
  数据库主键自增这个是大家都非常熟悉的功能,在分库分表的场景下,依赖单表主键自增显然没法保证唯一性。但也并不是完全不能利用,比如一个统一的 ID 生成服务,背后建若干张 sequence 表专门用于 ID 的生成,每台机器对应不同的 sequence 表,并且每个 sequence 表设置不同的自增初始值和统一的自增步长,比如 2 台机器的情况下,一台自增初始值为 1,一台自增初始值为 2,自增步长都为 2,就相当于每台机器返回的是一个等差数列,且每台机器返回的等差数列之间不会重复。
  这种方案满足的是趋势递增,但不是绝对的单调递增,同时也有明显的缺陷:扩展性较差,如果服务需要扩容,自增起始值和自增步长都需要整体重新设置。强依赖数据库,数据库挂了整个服务不可用,且数据库的 IO 性能会成为整个服务的瓶颈。
  但其实这些缺陷并非无法解决,有一个 "批量发号" 思想的解决方案:TDDL Sequence
  这里通过介绍我司 TDDL Sequence 的方案来解释 "批量发号" 的思想。其实依然是自增初始值结合自增步长的思路,但核心思路是通过应用层来代理 ID 的自增。只是在数据库中记录当前场景的 ID 最大值,通过在应用侧设置了自增步长,每次通过数据库拿到当前场景的 ID 起始值,就在本地得到了一个"号段",此时更新数据库记录当前最新的 ID 最大值,之后这个 "号段" 维护在内存中,ID 自增通过在内存中自增后直接返回,当这个 "号段" 消耗殆尽后,再重复之前的操作,得到一个新的号段。
  举个例子,当前场景下,应用配置的自增步长为 1000,且当前数据库中 ID 最大值为 1000,那么第一次请求数据库,会将当前场景的 ID 最大值更新到 2000,并得到号段 [1000, 2000),在这个区间内的自增 ID 全部通过内存生成,当生成到 2000 的时候,再次请求数据库,将当前场景的 ID 最大值更新为 3000,并在内存中维护号段 [2000, 3000)。CREATE TABLE `sequence` (   `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,   `name` VARCHAR(64) NOT NULL,   `value` BIGINT NOT NULL,   `gmt_create` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,   `gmt_modified` TIMESTAMP NOT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `uk_unique_name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 复制代码
  但如果自增是在内存中执行的,是否会存在多台机器申请到同一 "号段" 导致出现重复 ID 呢?这个部分是通过在请求数据库阶段的乐观锁实现的,因为当前机器确定使用这个号段前,会更新数据库当前最大 ID 值,通过乐观锁机制,如果拿老的最大 ID 值更新没有成功,意味着需要再去尝试取下一个 "号段",直到成功更新数据库记录为止。这个过程的时序如下:
  另外也不需要担心因为应用重启导致内存中维护号段丢失的问题,因为启动后一定会申请一个新号段,只是可能会存在一些 ID 的浪费,但这个问题通常可以忽略。Leaf-segment
  美团 Leaf-segment 的思路其实几乎和 TDDL Sequence 非常类似,不再额外说明。不过针对号段消耗殆尽后会同步请求数据库,对性能 TP999 指标有一定影响,故其设计了 "双 Buffer优化" 方案,本质上就是在监控号段已经消耗到比如 20% 的情况下,就会提前通过异步的方式拉取下一个号段,避免号段消耗殆尽后的数据库 IO 对性能 TP999 指标的影响。
  滴滴也曾开源了 tinyid,其生成 ID 的思想和上述方案几乎一致,就不再赘述。类雪花算法
  雪花算法是 Twitter 工程师提出的生成全局唯一 ID 的方案,它使用固定的 64 位二进制表示一个 ID,最后可以通过长整型的数据类型存储这个 ID。第一位为保留位,固定为 0,后面 41 位是 时间戳位,表示当前时间戳,那么算一下最多可以表示 (1L<<41)/(1000L*3600*24*365)=69 年的时间,再后面 10 位是 机器标识位,可以分别表示 1024 台机器。最后的 12 位为 序列号位,或者是自增序列位,可以表示 4096 个 ID,理论上 snowflake 方案的 QPS 约为 409.6w/s,这种分配方式可以保证在任何一个 IDC 的任何一台机器在任意毫秒内生成的 ID 都是不同的。
  之所以标题叫 "类雪花算法",原因是位数的分配,实际是可以自己调整的。比如单元化架构,多地分别有不同的机房,或者一个集群的机器数量超过了 1024 台,那么都可以根据实际情况去调整,比如需要单元化架构但一个应用的机器数量不可能超过 1024 台,那么可以将原来的 10 位机器位拿出两位来表示单元,8 位去标识机器。这个通常根据自己业务的实际情况可以灵活调整。
  类雪花算法由于依赖本地时间,会有一个知名的时间回拨问题:时间回拨问题
  所谓时间回拨,即当前得到的本地时间小于了之前获取的本地时间,感觉时针被"回拨"了。那么什么情况下可能出现时间回拨问题呢?人工设置NTP 网络时间同步
  人工设置的情况不多做解释,一般也很少发生。NTP 网络时间同步是一个时间同步协议,C/S 架构,服务器通过从权威设施(原子钟、GPS)获取到当前时间后,同时考虑传输时间差进行时间校准后得到当前的准确时间。首先我们日常家用的时钟,包括机器上的时钟通常是石英材质,石英材质的时钟精度虽然可以满足家用,但实际存在误差,也就意味着通过网络时间同步后的时间可能会出现回拨现象。
  这里不得不提到闰秒问题,什么是闰秒?
  为确定时间,世界上有两种常用的时间计量系统:基于地球自转的世界时(UT)和基于原子振荡周期的国际原子时(TAI)。由于两种测量方法不同,随着时间推移,两个计时系统结果会出现差异,因此有了协调世界时的概念。 协调世界时以国际原子时秒长为基础,在时刻上尽量接近世界时。1972年的国际计量大会决定,当国际原子时与世界时的时刻相差达到0.9秒时,协调世界时就增加或减少 1 秒,以尽量接近世界时,这个修正被称作闰秒。
  简单表达,就是地球自转速率本身不是一个稳定的值,为了磨平误差,世界时可能会出现减少 1 秒的情况,而网络时间同步又会去同步世界时,于是便发生了时间回拨问题。
  过去已经有几个知名的因为闰秒导致的故障:2012 年实施闰秒时,引发了 Reddit 的大规模故障,以及 Mozilla、LinkedIn、Yelp 和航空预订服务 Amadeus 的相关问题。2017 年,Cloudflare 的一个闰秒故障使这家网络基础设施公司的一部分客户的服务器离线。
  总之时间回拨问题无法避免,对于强依赖本地时间的计算,都需要考虑时间回拨问题的处理。
  闰秒将在 2035 年被取消,喜大普奔。Leaf-snowflake
  美团的 Leaf-snowflake 是基于雪花算法的 ID 生成方案,通过独立的集群服务对外提供能力,其机器标识位依赖 Zookeeper 生成,机器本地会备份一份结果用于 Zookeeper 的灾备。
  首先记录上一次生成 ID 的时间戳,如果本次的时间戳还小于上次的,那么说明发生时间回拨,如果时间偏差较小,则等待这个时间差过去,再进行生成,否则抛出异常拒绝服务,并且将当前机器剔除。//发生了回拨,此刻时间小于上次发号时间 if (timestamp < lastTimestamp) {     long offset = lastTimestamp - timestamp;     if (offset <= 5) {         try {             //时间偏差大小小于5ms,则等待两倍时间             wait(offset << 1);//wait             timestamp = timeGen();             if (timestamp < lastTimestamp) {                 //还是小于,抛异常并上报                 throwClockBackwardsEx(timestamp);             }             } catch (InterruptedException e) {               throw  e;         }     } else {         //throw         throwClockBackwardsEx(timestamp);     } } //分配ID        复制代码Seata UUID
  Seata 的 UUID 生成器是基于雪花算法改良的,针对上述的时间回拨问题进行了解决,同时也进一步突破了原来雪花算法的性能瓶颈。
  时间回拨问题本质是每次生成 ID 都会依赖本地时间,Seata UUID 生成器改良成了仅在应用启动是记录当前的时间戳,之后的生产就不再依赖,时间戳位的更新改成了依赖序列号位的溢出,每次当序列号位溢出(即已达到 4096)后将时间戳位进位。
  这样的改变相当于即解决了时钟回拨问题,也突破了 4096/ms 的生产性能瓶颈,相当于有 53 位参与递增。
  那么这样的改变是否有问题?因为在并发较高的情况下,会出现 超前消费,消费速率超过 4096/ms 的情况下,时间戳位的进位速度以及超过了当前时间戳的值,那么这个时候应用重启再拿当前的时间戳作为初始值,是否就会出现大量重复 ID 的情况呢?没错,理论可能,但这个问题实际被 Seata 忽略了,原因是如果真的持续是这样的 QPS,瓶颈不就不再 UUID 生成器了,Seata 服务本身就撑不住。
  当然由于每次生成的 ID 对本地时间不再是强依赖了,那么意味着这个 ID 在有限范围内是可被枚举的,不过由于是用在分布式事务的场景下,这个问题可以忽略。总结
  如果场景简单,直接使用 UUID 即可。如果仅是因为数据量比较大,需要分库分表,那么类似 TDDL Sequence 的方案也完全足够。除此之外,需要具体问题具体分析:如果唯一 ID 要落库,且可预见的会无限增长(比如是一个通用服务),需要一个定长 ID 来保证数据库字段长度的确定性,倾向于考虑类雪花算法的方案。如果判断服务需要承载的并发较高,则最好不要考虑 UUID 的方案。如果业务场景强依赖 ID 进行排序的,必须要求 ID 单调递增,则选择类雪花算法的方案。

如何选购一台全能的微单相机随着影像科技的不断进步,全画幅专微相机的性能越变越强,功能也逐渐全面起来。现在我们选购一台微单相机,不仅要看画质表现如何,还要关注视频性能,以及对焦系统连拍表现防抖功能等方方面面。(经济)陕西洛川土苹果变身时尚果新华社西安9月21日电题陕西洛川土苹果变身时尚果新华社记者陈钢陈晨张斌时近秋分,苹果种植大省陕西的数百万亩苹果正在陆续成熟。陕西最负盛名的果乡洛川县苹果种植面积达53万亩,当地农民五大纬度精准获客,未来移动联通电信三个巨头将会联合起来吗运营商大数据五大纬度精准获客,未来移动联通电信三个巨头将会联合起来吗?运营商大数据是宝藏,有待开发,其实运营商掌握了相当强大的综合数据资源,这个是没有任何争议的,无论是国内还是国外毛伟明以安全保稳定以稳定促发展持续巩固经济平稳健康向好势头毛伟明在宁乡调研时强调以安全保稳定以稳定促发展持续巩固经济平稳健康向好势头湖南日报9月27日讯(全媒体记者孙敏坚黄晗)27日下午,省委副书记省长毛伟明来到宁乡市开展两个统筹调研。他(经济)中银协报告2021年底我国消费金融公司贷款余额突破7000亿元新华社北京9月27日电(记者李延霞)中国银行业协会近日发布的数据显示,截至2021年底,我国消费金融公司数量增至30家,贷款余额突破7000亿元,达到7106亿元,同比增长44。2(经济)陕西洛川苹果之乡产量效益双丰收眼下正值苹果之乡陕西洛川县53万亩苹果收获季节。据当地农业部门介绍,今年洛川县苹果总产量预测为101。9万吨,已经成熟上市的中早熟品种,凭借良好的品质受到市场青睐,洛川苹果将迎来产优待证优惠政策来啦战友们,大家关心的还在陆续增加中战友们大家好!优待证能够享受哪些福利?优惠的项目是什么?有没有什么免费服务?快来一起看看吧!中国银联持证对象在云闪付APP优待证专区完成身份认证后,可享受专区内的各项服务。包括优待新来个技术总监,把限流实现的那叫一个优雅,佩服在电商高并发场景下,我们经常会使用一些常用方法,去应对流量高峰,比如限流熔断降级,今天我们聊聊限流。什么是限流呢?限流是限制到达系统的并发请求数量,保证系统能够正常响应部分用户请求Mybatis执行流程以及整合Spring源码分析一,简述mybatis的作用就是操作数据库,其实就是封装参数,生成sql,执行sql,封装结果,其实基本就是这几个大的步骤,mybatis和spring是怎么整合的呢,以及如何一步科沃斯,石头科技扫地机器人两大龙头发展历史20012009年的发展停滞时期渐进式的技术更新仅带来功能的边际改善,并未实质提升产品实用性。2001年Electrolux发布第一款量产扫地机器人Trilobite,使用我刚买了性价比天花板的智能手机还有不到几天的时间就要到国庆节了,我想换部性价比天花板的智能手机,个人觉得RedmiK50至尊版就相当的不错,手机性能拉满了。这款手机有6。67英寸的超大OLED柔性直屏,是追剧,立足餐饮供应市场,千味央厨拓展速冻米面新维度,市场潜力大(报告出品方分析师中原证券刘冉)1。行业餐饮供应市场的兴起餐饮业当前的发展阶段催生了餐饮供应市场的兴起,即要求食品制造业除服务零售端外,积极参与餐饮供应环节,为餐饮后厨提供标准化的我国进一步扩大社保费缓缴政策实施范围新华社北京9月24日电(记者姜琳王雨萧)人力资源社会保障部国家发展改革委财政部国家税务总局等四部门办公厅近日联合发布通知,明确自2022年9月起,各省自治区直辖市及新疆生产建设兵团特高压带电作业检修师邱中华刀尖行走12年7月17日,雨后的四川雅安市老林沟山区,水汽氤氲。一架直升机穿过薄雾,缓缓出现在这片森林上空。从远处就能看到,它的下方挂着一根吊索,直升机尽量压低飞行速度吊索下,有人坐在吊椅里,因开卖疯涨1万,华为这次比苹果更狠iPhone14开售,相关的黄牛事件估计很多人都有看到。黄牛们本以为能大赚一笔,结果反被买机的人倒宰一刀。这种骚操作,堪称善举。But,咱们主角不是苹果。是比iPhone14早1天全球连线中国影像节向古巴展示中国人的鲜活故事视频加载中新华社哈瓦那9月27日电为庆祝中国同古巴建交62周年和中华人民共和国成立73周年,中国影像节正在古巴举行,当地民众将通过多部纪录片了解真实的中国。中国影像节是中国文化和旅(外代二线)巴黎时装周Weinsanto品牌时装秀(外代二线)巴黎时装周Weinsanto品牌时装秀9月26日,模特在法国巴黎时装周上展示Weinsanto品牌的2023春夏新款服装。新华社西霸9月26日,模特在法国巴黎时装周上展省人大常委会向市人大常委会发来贺信热烈祝贺保定市人大设立常委会40周年贺信保定市人大常委会值此保定市人大常委会设立40周年之际,省人大常委会致以热烈的祝贺!40年来,保定市人大及其常委会始终坚持党的领导人民当家作主依法治国有机统一,认真履行法定职责,武汉至南昌特高压交流输变电工程正式开工新华社南昌9月22日电(记者姚子云)22日,落地江西的第三条特高压工程武汉至南昌特高压交流输变电工程,在江西省瑞昌市南义镇正式开工,计划2023年底实现全线贯通。工程建成后,华中地(体育)中国女篮主教练郑薇赢下比利时是一个提升18个前场篮板球是保障新华社悉尼9月27日电(记者岳东兴王琪)在世界杯上率队击败比利时以4胜1负结束小组赛赛程后,中国女篮主教练郑薇27日表示,这场球对全队来说是一个提升,锻炼价值也更大一些。当天,在悉博主浙江省体育局省足协金华市三方连夜开会处理省运会事件直播吧9月27日讯据博主浙江队情报小组报道,浙江省体育局浙江省足协金华市三方正连夜开会,准备对浙江省运会U15决赛中参与冲突的球员进行处罚。今天进行的浙江省运会U15决赛结束后,由(体育)NV夺得首届英雄联盟手游艾欧尼亚杯冠军新华社北京9月26日电首届英雄联盟手游艾欧尼亚杯总决赛的最终对决25日晚在莫干山上演,NV战队在比赛中率先抢得4积分,夺得首届英雄联盟手游艾欧尼亚杯总冠军。打野选手安旭龙(IDLo
硬盘的最新替换品爱国者P7000z推陈出新的电子产品,固态硬盘进入白菜价的时代,升级两年前的一堆硬盘,现在只用一根爱国者P7000z(2T)替换掉。P7000z采用联芸新一代MAP1602主控芯片长江存储旗下最新的欧洲市场iPhone15系列或取消SIM卡槽,国内仍双卡就在2022年iPhone14系列新品发布会上,苹果宣布美版全系iPhone都是eSIM,宣告SIM卡槽成为历史。如今,有消息称全新iPhone15系列在以法国为首的欧洲市场发布时一年前霸榜Steam的韩国网游,现在竟然还没凉去年,我写了这样一篇文章一款三年前的韩国网游在Steam霸榜了失落的方舟(LostArk),这款标准的韩国泡菜味网游,去年2月在Steam开放美服和欧服之后,在线人数一度超过100甲流来袭,应该怎么给孩子吃?今年3月5日,中国国家流感中心发布了2023年第9周第742期中国流感监测周报。监测数据显示,南北方省份流感病毒检测阳性率还在继续上升,以季节性甲型H1N1亚型流感病毒为主,季节性孕吐跟孩子的智商有关?有孕吐和没孕吐,生出的孩子有何不同?孕吐越严重孩子越聪明?这是一个让人感到神奇的说法。很多准妈妈都会担心孕吐对胎儿的健康有影响,但是有研究表明,孕吐并不会对胎儿的智力发育造成负面影响,反而可能会让宝宝更聪明。据加拿大如何为胎宝宝创造一个安全的环境胎儿在母亲的子宫内生长发育近10个月,生长环境的好坏决定了发育的优劣程度,因此孕妈妈在妊娠期间一定要注意自己身处的环境,避免外界的刺激因素影响宝宝发育。早睡早起胎儿喜欢早睡早起的规开学季叠加春季流行病高发期,如何降低孩子感染手足口病的风险?眼下,新学期已经拉开大幕,而随着春季的到来,一些春季流行疾病开始在校园抬头。开学季叠加春季流行病高发期,家长们难免会有些担心。而我们时常会听到的手足口病,就是一种春季流行病。关于手永安民俗展演引客来东南网3月28日讯(福建日报记者马丹凤通讯员邹雯摄影报道)他们在抛绣球,这是中国传统的婚俗。这是得胜回朝鼓,是我们永安的非物质文化遗产。26日一早,家住永安市区的杨文静带着两个女儿相约安徽向春而行帝王故里花鼓之乡,凤阳最美的六个旅游景点凤阳位于安徽省东北部,地处淮河中游南岸,长三角城市群,是安徽省滁州市下辖县。大自然的厚爱,馈赠给凤阳一方名山胜水,孕育了内涵厚重的淮河文化,哺育了一代农民皇帝朱元璋,造就了敢为天下世界上最重要的六大咽喉要道第六土耳其海峡位于土耳其西部,连接着黑海与地中海,是黑海通往地中海的唯一通道,被誉为天下咽喉。土耳其海峡包括博斯普鲁斯海峡(又叫伊斯坦布尔海峡)马尔马拉海和达达尼尔海峡(又叫恰纳卡做好水文章!专家为怒江体育旅游高质量发展把脉掌上春城讯3月24日,怒江体育旅游沙龙在云南旅游图书馆举办。沙龙由云南省旅游规划研究院主办,围绕如何做好水文章,相关领域专家业者畅谈怒江州体育旅游高质量发展的策略与路径。近年来,怒