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

分布式微服务系统下,如何生成全局唯一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 单调递增,则选择类雪花算法的方案。

如何让cpu跑出最大睿频?如何看cpu体质?处理器的体质和他能不能达到标称的睿频没关系,11500本身不能超频无需关注体质,只能说如果体质好的i511500能手动给他设置更低的电压来稳定运行以达到更低的发热和功耗。至于楼主说国家反诈app到底有多厉害?国家反诈app一夜爆红,下载量一直在前几名。我也下载安装了,功能确实很强大,确实能起到反诈作用,特别是对于老人来说,最大限度避免被诈骗!不知道你说的是宣传角度还是说功能角度。若从宣11400和5600g后期装显卡怎么选5600g不支持pc4?Inteli511400采用Intel的14nm工艺,CypressCove架构,6核心12线程,基础频率2。6GHz,加速频率4。4GHz,L3缓存12MB,UHD730核显,I胖好一点还是瘦好?为什么?人胖点好,还是瘦点好?当然是哪种都不好!但是如果在合理的范围内,两种都没有问题,但是如果特别胖或者特别瘦,对于身体健康来说,都有很大的影响,根据mbi来看我们每个人根据身高不同,都退休工龄三十九年与四十年退休后有什么不同?谢邀应答!个人看法,一,例如,39年的是在2O14年1O月1日之前退休的是按老人老办法计发工资。而4O年的是在2O15年退休的是按新人新方法计算退休金。老人退休金高按老办法计算。新怀孕变胖后你有哪些搞笑体验?怀孕后,随着孕期的慢慢增加肚子一天天变大,之前的衣服都不能穿啦。为了节省不必要的开支,冬天穿起了老公的羽绒服,内搭衣。我姐怀孕以后,鼻子变得又大又宽,我妈说,就是个大蛤蟆趴脸上,笑你玩过最真实的战争网游是什么?当然是来自2002年的古董游戏大海战2了,画面党和手残党别来玩,steam里搜索大海战2就能找到游戏,游戏早已复活,现在是复兴街阶段,现在收益高单线路一周满级,任务福利多,熟练不用帝国时代二都有什么花式玩法?帝国时代2真的是好玩又经典,1999年发行的游戏已经是网吧必玩游戏之一。当时网络还不是那么好用,所以很多人都选择去网吧玩这款百玩不厌的多人即时战略游戏。那么有什么玩法让人百玩不厌呢在哪里可以查询化妆品成分?一般去美丽修行看。但是美修上有些产品没有,我就看httpwww。cosdna。com这里面蛮多产品成分信息的。另外,推荐几个讲成分的公众号言安堂美容大王和化学家kenjijoel(我是实习生,最近主管发现我在boss上更新简历,让别人问我最近可不可以上班,我该怎么办?确实比较尴尬,我去年的时候也遇到过类似的情况。有一次闲来无事,我就用手机查看了某招聘app,其实本身并没有想着找工作,只是看看目前市场什么行情,有哪些公司在招人,尤其是我们这一个行支付宝花呗突然被关闭什么情况?你是说支付宝关闭了花呗应用,还是你自己的花呗帐号被关闭了?说实话我不喜欢花呗的操作有次我在淘宝买东西在支付环节上没有注意不知道什么时候点花呗支付了帐单整个交易过程都以为是在用,自己
为什么卢卡库想回到国米库卡库出生于1993年,拥有比利时与刚果的双国籍,职业生涯效力过6支球队,目前身价7000万,总交易金额到达了3亿2406万。2006年加盟安德莱赫特青年队2008赛季2011赛季跨过蒸汽弹射的福建舰强在哪里?世界第一的中国技术有多强?随着003号航母下水,电磁弹射有关话题再度成为讨论的热度,那么电磁弹射到底有哪些优势呢?电磁弹射技术是一种新兴的直线推进技术,目前世界上只有中美两国拥有电磁弹射研制并加以运用的,而孕妇餐后五不宜,有些至少要等两个小时,别让坏习惯影响胎儿孕妇作为特殊人群在日常生活当中必须要被特殊照顾,只有这样才能够保证孕妇的身体变得更好一些。这也就意味着孕妇在日常生活当中生活习惯也是需要注意一下的,尤其是吃完饭之后这5件事情最好不五爪金龙现身云南景洪!消失10多年,如今突然出现预示着什么2022年6月中旬,云南省景洪市森林警察大队接到群众报警称在家中院子里发现了一只五爪金龙,不知该如何处理,故报警求助。很多人看到五爪金龙可能会一头雾水这是什么动物?其实五爪金龙是一卫报曼联准备7000万欧浮动报价德容,滕哈赫希望季前赛前敲定直播吧6月21日讯卫报消息,曼联准备7000万欧浮动报价德容,滕哈赫希望季前赛之前敲定德容转会。转会记者斯基拉跟进确认,曼联报价7000万欧签德容。卫报表示,理想结果是曼联在7月8佩杜拉巴黎将给什克的报价提高到6500万欧,但不会提到8000万欧直播吧6月21日讯据佩杜拉官网报道称,巴黎已经将给什克里尼亚尔的报价提高到了6500万欧。什克里尼亚尔可能会在夏窗离开国米,但这与他只剩下一年的合同无关,因为据意大利记者佩杜拉报道川普的三位娇妻,个个都是狠角色,现任是特朗普最害怕的一个文科普研究集1你知道川普有多怕老婆吗?当众让他难堪,甚至还给他戴绿帽。一直以来,特朗普都以狂妄自大的形象在展示在公众面前,无论是形容某些国家像粪坑,还是让某位国家领导人坐小板凳,都你的存款无法提现,由河南新财富集团控股的银行案件引发的热议6月19日最新热搜在今年34月份其实就有相关媒体报道,河南部分的村镇银行储户取钱受阻,以及总部位于安徽省的新淮河村镇银行均因无法正常提现,引起一些储户恐慌。并且相关的四家村镇银行的背靠祖国,优势凸显活力无限随着近期一系列试飞演练等准备工作完成,经过6年建设的香港国际机场第三跑道预计在今年投入使用。这座于24年前搬至大屿山赤鱲角的新机场,见证了香港回归祖国后一次次腾飞,又将与香港一起实怀念乔羽,怀念他对时代的态度街谈一条大河波浪宽,风吹稻花香两岸让我们荡起双桨,小船儿推开波浪这些耳熟能详的歌曲,陪伴了一代又一代中国人的成长,它们有一个共同的词作者,这就是著名词作家乔羽。6月20日凌晨,乔羽被婆婆逼到失语,亚洲戴安娜晚年坦言我与明仁天皇没有爱情当大多数女性都开始站于独立自由的角度来看待婆媳关系的时候,王室女性却似乎一直停留在传统的观念里无法自拔。而日本王室又是世界为数不多的王室中,婆媳关系最难相处的地方,传统规矩,甚至是