专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

UUID的弊端以及雪花算法

  一、问题
  为什么需要分布式全局唯一ID以及分布式ID的业务需求
  在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识如在美团点评的金融、支付、餐饮、酒店;猫眼电影等产品的系统中数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息;特别一点的如订单、骑手、优惠券也都需要有唯一ID做标识。
  此时一个能够生成全局唯一ID的系统是非常必要的
  ID生成规则部分硬性要求
  全局唯一
  即不能出现重复ID号
  趋势递增
  在Mysql的InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用的是BTree的数据结构作为存储索引数据,在主键的选择上我们应该尽量使用有序的主键保证写入性能
  单调递增
  保证下一个ID一定大于上一个ID,如事务版本号、排序等特殊要求
  信息安全
  如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可:如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,需要ID无规则不规则,让竞争对手不好猜
  含时间戳
  在开发中能快速了解这个分布式id生成的时间
  ID号生成系统的可用性要求
  高可用
  发一个获取分布式ID的请求,服务器要保证99。999的情况下能给我返回一个分布式ID
  低延迟
  返回的速度要快
  高QPS(抵抗高访问)
  比如一秒内10万个,需要服务器能抵抗住并且生成10万个分布式ID
  二、一般通用方案
  (一)UUID
  jdk自带,生成36位字符,形式为844412,包含4个连号,对于单体式仅需满足唯一的话可以使用好处:性能高,本地生成,无网络消耗坏处:无序且字符串长,存入数据库会增大数据库压力,入数据库性能差。mysql官方推荐主键越短越好
  索引,B树索引的分裂
  既然分布式id是主键,然后主键是包含索引的,然后mysql的索引是通过b树来实现的,每一次新的UUID数据的插入,为了查询的优化,都会对索引底层的b树进行修改,因为UUID数据是无序的。
  所以每一次UUID数据的插入都会对主键地的b树进行很大的修改,这一点很不好。插入完全无序,不但会导致一些中间节点产生分裂,也会白白创造出很多不饱和的节点,这样大大降低了数据库插入的性能
  (二)数据库自增主键
  数据库自增主键实现原理:数据库自增id和replaceinto实现的
  REPLACEINTO的含义是插入一条记录,如果表中唯一索引的值遇到冲突,则替换老数据
  那数据库自增ID机制适合作分布式ID吗?答案是不太适合系统水平扩展比较困难,比如定义好了步长和机器台数之后,如果要添加机器该怎么做?假设现在只有一台机器发号是1,2。3。4。5(步长是1),这个时候需要扩容机器一台。可以这样做,把第二台机器的初始值设置得比第一台超过很多,貌似还好,现在想象一下如果我们线上有100台机器,这个时候要扩容该怎么做?简直是噩梦。所以系统水平扩展方案复杂难以实现。数据库压力还是很大,每次获取ID都得读写一次数据库,非常影响性能,不符合分布式ID里面的延迟低和要高QPS的规则(在高并发下,如果都去数据库里面获取id,那是非常影响性能的)
  (三)Redis生成全局id策略
  因为Redis是单线的天生保证原子性,可以使用原子操作INCR和INCRBY来实现
  注意:在Redis集群情况下,同样和MySQL一样需要设置不同的增长步长,同时key一定要设置有效期
  可以使用Redis集群来获取更高的吞吐量。
  假如一个集群中有5台Redis。可以初始化每台Redis的值分别是1,2,3,4,5,然后步长都是5。
  各个Redis生成的ID为:A:1,6,11,16,21B:2,7,12,17,22C:3,8,13,18,23D:4,9,14,19,24E:5,10,15,20,25
  三、snowflake
  (一)概述
  官网:
  https:github。comtwitterarchivesnowflake
  Twitter的分布式自增ID算法
  特点:
  能够按照时间有序生成
  Snowflake算法生成id的结果是一个64bit大小的整数,为一个Long型,转化为字符串最多19位
  分布式系统内不会产生ID碰撞(由datacenter和workerld作区分)并且效率较高。
  (二)结构
  bit表示,id一般为正,所以固定为0
  时间戳位范围为0241次方,大概是可以使用69年(从1970算起)
  工作进程位最多为210,即1024个节点,包括5位datacenter和5位workerld作区分
  12bit序列号,序列号,用来记录同毫秒内产生的不同id。12位(bit)可以表示的最大正整数是21214059
  (三)代码TwitterSnowflake
  SnowFlake的结构如下(每部分用分开):
  0000000000000000000000000000000000000000000000000000000000000000
  1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
  41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截开始时间截)得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T(1L41)(1000L606024365)69
  10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
  12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号
  加起来刚好64位,为一个Long型。
  SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。publicclassSnowflakeIdWorker{Fields开始时间截(20200828)privatefinallongtwepoch1598598185157L;机器id所占的位数privatefinallongworkerIdBits5L;数据标识id所占的位数privatefinallongdatacenterIdBits5L;支持的最大机器id,结果是31(这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)privatefinallongmaxWorkerId1L(1LworkerIdBits);支持的最大数据标识id,结果是31privatefinallongmaxDatacenterId1L(1LdatacenterIdBits);序列在id中占的位数privatefinallongsequenceBits12L;机器ID向左移12位privatefinallongworkerIdShiftsequenceBits;数据标识id向左移17位(125)privatefinallongdatacenterIdShiftsequenceBitsworkerIdBits;时间截向左移22位(5512)privatefinallongtimestampLeftShiftsequenceBitsworkerIdBitsdatacenterIdBits;生成序列的掩码,这里为4095(0b1111111111110xfff4095)privatefinallongsequenceMask1L(1LsequenceBits);工作机器ID(031)privatelongworkerId;数据中心ID(031)privatelongdatacenterId;毫秒内序列(04095)privatelongsequence0L;上次生成ID的时间截privatelonglastTimestamp1L;Constructors构造函数paramworkerId工作ID(031)paramdatacenterId数据中心ID(031)此方法是判断传入的机房号和机器号是否超过了最大值,即31,或者小于0publicSnowflakeIdWorker(longworkerId,longdatacenterId){if(workerIdmaxWorkerIdworkerId0){thrownewIllegalArgumentException(String。format(workerIdcantbegreaterthandorlessthan0,maxWorkerId));}if(datacenterIdmaxDatacenterIddatacenterId0){thrownewIllegalArgumentException(String。format(datacenterIdcantbegreaterthandorlessthan0,maxDatacenterId));}this。workerIdworkerId;this。datacenterIddatacenterId;}Methods核心方法获得下一个ID(该方法是线程安全的)returnSnowflakeIdpublicsynchronizedlongnextId(){1。获取当前的系统时间longtimestamptimeGen();如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常if(timestamplastTimestamp){thrownewRuntimeException(String。format(Clockmovedbackwards。Refusingtogenerateidfordmilliseconds,lastTimestamptimestamp));}如果是同一时间生成的,则进行毫秒内序列if(lastTimestamptimestamp){sequence要增1,但要预防sequence超过最大值4095,所以要与SEQUENCEMASK按位求与即如果此时sequence等于4095,加1后为4096,再和4095按位与后,结果为0sequence(sequence1)sequenceMask;毫秒内序列溢出if(sequence0){阻塞到下一个毫秒,获得新的时间戳timestamptilNextMillis(lastTimestamp);}}时间戳改变,毫秒内序列重置else{sequence0L;}上次生成ID的时间截把当前时间赋值给lastTime,以便下一次判断是否处在同一个毫秒内lastTimestamptimestamp;移位并通过或运算拼到一起组成64位的IDlongid((timestamptwepoch)timestampLeftShift)时间戳减去默认时间再左移22位与运算(datacenterIddatacenterIdShift)机房号左移17位与运算(workerIdworkerIdShift)机器号左移12位与运算sequence;序列号无需左移直接进行与运算returnid;}阻塞到下一个毫秒,直到获得新的时间戳paramlastTimestamp上次生成ID的时间截return当前时间戳protectedlongtilNextMillis(longlastTimestamp){longtimestamptimeGen();while(timestamplastTimestamp){timestamptimeGen();}returntimestamp;}返回以毫秒为单位的当前时间return当前时间(毫秒)protectedlongtimeGen(){returnSystem。currentTimeMillis();}Test测试publicstaticvoidmain(String〔〕args){SnowflakeIdWorkeridWorkernewSnowflakeIdWorker(0,0);for(inti0;i1000;i){longididWorker。nextId();System。out。println(id);}}}
  (四)优缺点
  优点:
  毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。可以根据自身业务特性分配bit位,非常灵活。
  缺点:
  依赖机器时钟,如果机器时钟回拨,会导致重复ID生成在单机上是递增的,但是由于设计到分布式环境,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况(此缺点可以认为无所谓,一般分布式ID只要求趋势递增,并不会亚格要求递增,90的需求都只要求趋势递增)
  缺点的解决方案
  可以参照以下两个来进行机器时钟的同步百度开源的分布式唯一ID生成器UidGeneratorLeaf美团点评分布式ID生成系统

西卡荣登十大榜首,PYL练铁也是榜首,双榜都有UZI当前,S13赛季已正式开始,许多玩家正在关注最近的比赛。随着LPL赛区的常规赛接近尾声,各大战队也进入了最后的抢分阶段。粉丝们的关注度不断攀升,最近的十大选手投票引发了热议。然而,原版最终幻想7成功要归功于CG动画更符合西方玩家口味最终幻想7的创作者坂口博信最近参加了2023年摩纳哥动漫游戏国际会议的一个小组讨论会,在会议上坂口博信探讨了最终幻想7在西方大受欢迎的原因,他认为这要归功于游戏引入了CG动画,这更女子在AD钙奶中喝出小虫,娃哈哈回应再来一瓶?近日,在山西运城,高女士称在给孩子配奶粉时,在娃哈哈AD钙奶中发现异物。高女士表示平常给孩子喂奶时,都会配一些娃哈哈,早上给孩子冲奶时发现了虫子。就有个虫子,平时没有。对此,娃哈哈2岁男童反复高烧,奶奶只在诊所开了一点药,结果造成一辈子遗憾孙子5个月大时,他的妈妈就抛下这个家走了。军军从小就是我由我在照顾,可是我怎么想不到一次高烧会让孙子患上这样的重症。是我的无知耽误了他的一辈子,也害了这个家啊。奶奶陈应珍看着曾经白干细胞移植4周后早孕!杨女士二胎再当妈!最近,公司有几个还没结婚的小姑娘,体检的时候查出来卵巢囊肿,大家都紧张得不行。小姑娘的担心是有道理的,卵巢对女性健康的重要性不言而喻,但因为焦虑,病急乱投医,就不好了。还有一些女性这五分钟他经历了什么小朋友们,遇到坏人我们要怎么做?近日,云龙派出所民警走进辖区幼儿园,联合园方开展防暴恐演练。为让此次演练取得生动真实的效果,几天前,派出所民警同园方进行了仔细协商,并在演练开始前,世界级女优苍井空!AV生涯16年,35岁结婚,19年宣布怀上双胞胎朋友们!还记的12年因钓鱼岛引发的热议吗?从那以后让更多人了解了她的职业生涯历程,所谓五味杂陈很多人不理解和苍井空有什么关系。记得当时有句口号钓鱼岛是中国的,苍井空是世界的这句话的让动人音乐与经典电影并蒂开花深圳交响乐团演奏电影上甘岭主题歌我的祖国资料图片资料图片电影流浪地球2的主题曲人是直抵人心感人至深电影深海配乐将真挚情感娓娓道来,令观众印象深刻。音乐与电影都是贴近大众的艺术,二者人工智能(AI)的发展前景人工智能将会与大数据云计算物联网工业互联网无人驾驶等新一代信息技术深度融合,形成一个全球化智慧化网络化的新型社会结构。在这个结构中,人类将可以享受更高效更便捷更安全更环保的生活和工小白入门必知必会PHP安装一PHP基础1。1服务器配置4核CPU8G内存100G磁盘空间,操作系统CentOS7。81。2下载地址httpswww。php。netdownloads。php二PHP安装2。1TopAIGC共识进入21世纪以来,科学技术革命呈现前所未有的集群化规模化迭代加速化趋势。跨界的大科学体系构成百年未有之大变局的新变量。其中,人工智能将成为大科学体系的核心力量,AIGC则代表了人工
国有经济运行呈稳定恢复态势前7月国企营业总收入同比增长9。5经济日报北京8月29日讯(记者曾金华)财政部29日发布统计数据显示,前7月,全国国有及国有控股企业营业总收入同比保持增长,国有经济运行呈稳定恢复态势。统计显示,前7月,国有企业营业从冷门到火爆,临期食品行业经历了什么不知从何时起,临期食品也成为当代消费者最追捧的商品之一。特别是快消品,如饮料酒水,牛奶,食品等等。如今,迫在眉睫的食品消费热潮背后,似乎隐含着当代消费者生活习惯的转变和反消费意识的实况足球重磅新增传奇最强新版兽腰2023新引擎战斗力如何?国际服新传奇维埃拉,国服将高光卡形式登场,高光卡维埃拉的爆发力比较强,控球能力更好,还有不错的双传。缺点就是身体控制手感要差些,在就是远射和制空方面也不是特别出色。当前版本维埃拉有小卤蛋喜提加强!桑启惨遭大砍,关羽达摩这波赢麻了本文原创首发于公众号电竞怪客hello大家好我是怪客君又是一天周末,怪客不小心睡过头了,这里先跟大家说声抱歉昨天怪客给大家梳理了王者今年下半年大概率会上线的一些皮肤归属,想了解皮肤知道结局的我一点不慌今天冒泡赛最后一场,RNG对阵LNG,但是朋友聚餐,没怎么看手机,吃饭前打开比分20,觉得没悬念,安心吃饭。吃到一半,上个厕所,一看直播22了,莫非今年是让二追三的年份?回去酒过三V5和猛龙队,常规赛虎季后赛虫在昨天的2022LPL全球总决赛资格赛的低位赛中,LNG是31战胜了V5挺进下一轮。V5从前两个赛季摆烂的状态一跃到今年的常规赛战神,但是他们却如同NBA的猛龙队一样,常规赛猛如虎单机塔防手游迷宫探险家即将上线迷宫探险家是一款充满荒诞风格的逆向塔防游戏,在这里有各式各样荒诞的建筑物,有各种怪异荒诞的生物,还有奇葩荒诞的玩儿法。游戏中,玩家都跌入魔王创造出来的无尽迷宫,在迷宫中不断重复着循俗话人到七十古来稀,70岁后如何养生延寿?6个细节要重视古时有句话叫作人到七十古来稀,那时人们的生活条件和医疗水平都很低,活到七十岁的人很少见,能活到的人都是人们眼中的长寿老人了。可是到现在人们的平均寿命都到了83。6岁,七十岁的老人比这个公认的养肺高手,最适合秋天多吃过了处暑,就意味着离秋天越来越近了。秋的气候特点是燥,而我们的肺喜润恶燥,若燥邪侵体,可导致肺的阴津不足,引发许多不适甚至疾病。所以今天,要给大家推荐一个养肺润燥的佳品百合,现在抓熬夜危害早知道熬夜对于大多数人来说很正常,有些时候确实因为工作的原因,还有的时候只是单纯的追剧或是不想睡觉。不过,你知道这熬夜会有哪些危害和后果?首先,是的免疫功能会下降,特别是一些与免疫系统相含寄生虫最多的4种鱼,老板自己都不吃,没营养价格贵鱼肉高钙高蛋白,营养价值高,但是市场上的鱼肉,种类可是非常丰富的,在面对这些鱼肉的时候,不是所有鱼都适合食用。因为有些鱼肉是含有寄生虫的,处理不当的话,很容易就会让我们人体,受到寄
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网