UUID——全局唯一ID——universally unique identifie。

一般来说常用的基于时间进行排序,因为时间是自然递增的。但是全局唯一ID的两个核心要求是:

  1. 全局唯一
  2. 粗略有序

在分布式环境下,很有可能多台机器同时产生了同一个ID,这样就无法唯一的标识某项业务。

引入单点ID生成器

我们可以独立部署一个服务,专门用于生成ID。其他需要ID的服务,都调用这一个接口,这样在一台机器上我们就可以利用本地的时钟或者计数器来分发ID。

问题一:时钟回拨
计算机底层的时钟,主要依靠石英钟,本身是有一定的误差的,计算机定期请求NTP服务,来同步当前时间,这期间其实可能会产生时钟跳跃。

问题二:计数器消失
我们将计数器保存在内存中,一旦这台机器发生断电或者故障,我们就无法知道之前的ID生成到多少了
即使我们引入Raft协议和Mapreduce的相关备份服务,提高了计数器的可用性,但是这样又会出现主服务和备用服务如何同步的问题。
即使解决了上述问题,单点服务的最大限制在于性能不佳,每个请求都要持久化连接,并发量很容易到瓶颈

基于数据库实现ID生成器

我们知道数据库中主键是绝对唯一的,如果设置主键为auto_increment,数据库可以帮助我们生成唯一的全局ID。
但是单点的数据库仍然和上述问题一样,有性能瓶颈。

水平扩展
我们想用多个数据库同时分配ID,那么怎么保证ID不冲突呢。

比如两个数据库,一个持有所有偶数 ID,一个持有所有奇数 ID。其他业务系统只需要轮询两个数据库,就可以得到粗略有序的全局唯一 ID 了。

为什么是粗略有序,因为没办法保证需求的业务会不断的规律的轮询两个数据库,但是能保证的是随着时间的推移,只要负载均衡算法比较合理,他得到的ID绝对是递增的。

数据库写入瓶颈问题
利用单点思路,把生成ID的响应服务,和存储ID的服务拆开,单点对外提供ID,但是将ID状态记录在数据里

具体来说,每次单点服务向数据库批量申请N个ID,在本地用内存维护这一段ID,并把数据库中已经用过的ID+N,直到这N个被服务申请完,再重复。
这样即使单点服务挂了,我们重启之后直接向数据库申请,也能保证获得的ID是自然递增的,无非就是中间少了存在单点服务的那一小段而已。
这样设计,可以大大减少数据库写入次数,把每次申请变成了每次压力只有1/N,往往可以承受10w级的QPS。

UUID

UUID实现不同于远程调用单点服务,而是直接在业务本地产生,被封装成一个库用以调用。
UUID 一共包含 32 位 16 进制数,也就是相当于 128 位二进制数,显示的时候被分为 8-4-4-4-12 几个部分,看一个例子:


0725f9ac-8cc1-11ec-a8a3-0242ac120002

实现版本一:
用name(一段二进制)计算,保证不同空间不同name得到唯一UUID,而相同空间相同名字UUID相同。
对其做MD5+位运算,最终得到ID。

实现版本二:
基于随机性进行计算,因为 UUID 非常长,所以其重复概率可以忽略不计。
但 UUID 过于冗长,且主流版本完全无序,对数据库存储非常不利,这点我们之后介绍 B+ 树的时候也会展开讨论。

10.算法进阶之分布式篇——分布式环境下如何生成唯一ID——UUID相关推荐

  1. 生成唯一字符串算法_面试官问:在分布式场景,生成唯一ID,你有几种方案?...

    来源:http://t.cn/RG0AW0a 说明:本文代码采用C#,重要的是理解解决方案,代码实现都是次要的. 系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结.生成I ...

  2. mysql并发获取唯一数值_高并发分布式环境中获取全局唯一ID[分布式数据库全局唯一主键生成]...

    需求说明 在过去单机系统中,生成唯一ID比较简单,可以使用MySQL的自增主键或者Oracle中的sequence, 在现在的大型高并发分布式系统中,以上策略就会有问题了,因为不同的数据库会部署到不同 ...

  3. 分布式集群环境下,如何实现session共享三(环境搭建)

    这是分布式集群环境下,如何实现session共享系列的第三篇.在上一篇:分布式集群环境下,如何实现session共享二(项目开发)中,准备好了一个通过原生态的servlet操作session的案例.本 ...

  4. 根据twitter的snowflake算法生成唯一ID

    C#版本 /// <summary>/// 根据twitter的snowflake算法生成唯一ID/// snowflake算法 64 位/// 0---0000000000 000000 ...

  5. dotNET Core实现分布式环境下的流水号唯一

    业务背景 在管理系统中,很多功能模块都会涉及到各种类型的编号,例如:流程编号.订单号.合同编号等等.编号各有各自的规则,但通常有一个流水号来确定编号的唯一性,保证流水号的唯一,在不同的环境中实现方式有 ...

  6. java 安卓客户端开发_《安卓网络编程》之第一篇 java环境下模拟客户端、服务器端...

    1.Socket简介 在网络上的两个程序通过一个双向的通信连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket是TCP/IP协议的一个 ...

  7. 第十八篇 Linux环境下常用软件安装和使用指南

    提醒:如果之后要安装virtualenvwrapper的话,可以直接跳到安装virtualenvwrapper的方法,而不需要先安装好virtualenv 安装virtualenv和生成虚拟环境 安装 ...

  8. python版雪花算法生成唯一ID

    一.雪花算法图解 理论一大堆,总结如下图: 下方为源码,返回的结果为19位,为10进制表示,使用二进制表示就是64位,所以不必有所疑惑. 二.源码 1.异常捕获块 文件名:exceptions.py ...

  9. java redis 生成唯一id_Redis在集群环境中生成唯一ID

    概述 设计目标:每秒最大生成10万个ID,ID单调递增且唯一.Reidis可以不需要持久化ID. 要求:集群时钟不能倒退. 总体思路:集群中每个节点预生成生成ID:然后与redis的已经存在的ID做比 ...

最新文章

  1. boost::python::detail::result相关的测试程序
  2. java mybatis 返回map_mybatis返回map集合的格式是什么?mybatis返回map集合实例
  3. spring中配置quartz定时器
  4. java 如何让程序一直运行的程序_java – 如何在程序结束前让方法在后台持续运行?...
  5. centos7正确关机重启
  6. 网络流之最小点权覆盖和最大点权独立集学习
  7. 【渝粤教育】国家开放大学2018年春季 0266-22T设计构成 参考试题
  8. Elasticsearch安装之安装Java环境
  9. visual foxpro c语言教程,VFP简单初级入门教程超好.pdf
  10. 李宏毅机器学习笔记——深度学习
  11. C#.Net网络程序开发-Socket篇(转)
  12. python中def fun()是什么意思_python def 定义函数,调用函数方式
  13. 大地高、正高和正常高的区别
  14. 蒟蒻的SCAU第一周个人排位赛赛后感想
  15. nsis升级包_NSIS office补丁
  16. 骁龙8gen2和骁龙8gen1差距大吗 骁龙8gen2比8gen1性能强多少
  17. PC端安装android模拟器
  18. Flink【优质】面试
  19. 技术人员如何创业《四》—— 打造超强执行力团队
  20. [js] 得到本月、上月、下月的起始、结束日期; 得到今年、去年、明年的开始、结束日期 day.js

热门文章

  1. 研究B站视频编号含义 - av | ep | md ...
  2. mybatis(二)xml配置文件详细说明
  3. 数据库横向扩展和纵向扩展
  4. hrbust 哈理工oj 1633 word!word!【欧拉路、欧拉回路的有向图判断】
  5. 了解世界杯赔率,让您运气更‘好‘(个人分享)
  6. CnOpenData地方留言文本数据简介
  7. Jumpserver部署+Ldap认证
  8. 主板怎么安装在计算机主机箱,计算机主板、主机、机箱和计算机的制作方法
  9. RocketMQ:The producer group has been created before, specify another name please.
  10. html 自动 生成 日期,自己生成Select列表日期时间