做项目的时候经常会用id作为唯一标识。 但是当有这样一个需求出现的时候:工程分布式部署,要求抗住高并发。并且生成的id是根据时间自增的。解决这个问题有很多种方法,但是要选择一个性价比比较高的策略比较不容易,例如: 1.数据库自增id控制 小型的应用直接自增足以。稍微中型一点的可以做下分表,突破下数据库的瓶颈,那么稍微大型一点的用什么方法来突破性能的瓶颈那? 例如我们曾经一个业务用postgresql序列来产生自增id,1个月生成3000w个id,平均下来一秒10左右,高峰*5倍。还是很轻松的。 如果这种方法数据库有点吃不消、或者效率有点低,那么可以采用sql大步长+cache:意思就是一次在数据库中取100个id,缓存在cache中,生成id的时候先判断cache中有无id,如果有则取出来用,如果没有去mysql取。当然虽然这种方法减少了mysql的访问次数和锁的次数,但是带来的就是程序中的并发问题。 2.当前时间的毫秒或者纳秒 毫秒这个也有点low了,稍微明白的工程师一眼就看出来了,很容易被破解。就算破解无所谓,对于高并发来说1ms也还是有可能生成多个id的。 纳秒倒是解决了高并发的问题,应该没有应用在一纳秒生成多个id的。但是如果完全依赖于纳秒,那么就等于完全失去了可控性,出了问题的话也不是很好办。 但是对于这样一个需求用纳秒还是能轻松解决问题的,不失为一个好的选择。 3.UUID 这个有点太长了,虽然能保证性能,但是串太长,不自增。 下面进入这个技术分享的主题: 4.通过约束条件生成唯一id 据听说twitter用的也是此方法 什么是通过约束条件生成唯一id,简单说就是在很极限的条件下生成很多id,足以满足需求,类似是唯一id。 比如在同一台机器上20ms内生成4000个id甚至更多,比如有10台机器,那么就是20ms生成40000个id,这样足以应对任何需求了,那么具体的做法是什么? 首先确定id存储用的是64位,那么一个64位的二进制是这样的: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 1 1 1 0 0 0 0 0 1 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 看到这个就可以有很多事情可做了,约束条件生成id的方法就是切割这个64位,把某段的二进制表示成一个约束条件,可空性非常强,能抗住高并发,并且不易破解。 如上面的需求,如果要根据时间进行自增,那么就必须把当前的毫秒数放在高位了,比如前41位是当前时间。 41时间后面紧接9位是ip,ip之后的所有位数是自增数的二进制,记录着当前面位数相同的情况下这是第几个id。 所以如果现在有10台机器,那么这个id生成器生成id的极限是:同一台机器1ms内可以生成2的14次方个id。轻松满足需求。 最后切割成的效果可能是这样: 但是,这不是这个方法最大的好处,最大的好处是可以根据需求定制不同的约束条件,可以增加条件,继续分割这个64位数。 那么当条件比较多,64位不够分割的时候怎么办。有办法,进行移位操作,比如讲时间条件右移4位,那么1ms的约束条件就变成了16ms了,完全根据需求而定。 所以这个方法最大好处莫过于灵活,可控性强,根据需求可以轻易定制不同类型id。 最后我们把拼凑的这个64位二进制转成10进制存入数据库或者缓存中。 具体实现因需求而异,实现起来也相当简单,就不把实现贴出来了,只是做个分析,抛砖引玉。

如果想学习Java工程化、高性能及分布式、深入浅出。性能调优、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级架构进阶群:180705916,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家

在高并发分布式情况下生成唯一标识id相关推荐

  1. 在高并发的情况下,利用redis来处理库存超卖和遗留问题

    在高并发的情况下,利用redis来处理库存超卖和遗留问题 首先现在redis中放上商品的库存数量为100间商品,在初始化一个set集合用于放秒杀成功的用户id,本用例先放进去一个id=10000的用户 ...

  2. python namespace unique_Python使用uuid库生成唯一标识ID

    uuid是128位的全局唯一标识符(univeral unique identifier),通常用32位的一个字符串的形式来表现.有时也称guid(global unique identifier). ...

  3. js生成唯一标识ID

    js生成唯一标识ID 前言 方法一.利用时间戳+随机字母生成 方法二.利用时间戳加上机器码生成的唯一标识ID 总结 前言 有时候,表格数据的分页,增加,删除,编辑等功能都需要前端来完成,因为数据的全部 ...

  4. java异步处理_SpringBoot异步开发之异步请求,在高并发的情况下,提高性能

    何为异步请求 在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理.如果一个请求需要进行IO操作,比如 ...

  5. 怎样生成分布式情况下的唯一标示?必须包含网卡字段,以便不同机器生成的唯一标示肯定不一样...

    用到了以太网卡地址.纳秒级时间.芯片ID码和许多可能的数字 转载于:https://www.cnblogs.com/panxuejun/p/8526859.html

  6. 高并发分布式下生成全局ID的几种方法

    文章目录 利用全球唯一UUID生成订单号码 基于数据库实现全局ID 基于redis生成全局ID策略 号段模式 雪花算法 利用全球唯一UUID生成订单号码 **推荐理由: 简单方便,网上虽然说UUID出 ...

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

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

  8. 如何在分布式场景下生成全局唯一 ID ?

    作者 l 会点代码的大叔(CodeDaShu) 在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或 ...

  9. 在高并发、高负载的情况下,如何给表添加字段并设置DEFAULT值?

    在高并发.高负载的情况下,如何给表添加字段并设置DEFAULT值? 在高并发.高负载的情况下,如何给表添加字段并设置DEFAULT值? 在Oracle 12c之前,当Oracle表数据量上亿时,对表执 ...

最新文章

  1. ElasticSearch + xpack 使用
  2. 全排列函数next_permutation
  3. ospf实验及原理(ensp)
  4. (0.1)鸿蒙HarmonyOS开发工具DevEco Studio设置
  5. 前端学习(2883):实现事件处理函数批量绑定
  6. pytorch基础一:张量
  7. Dubbo的SPI实现
  8. 靠谱测试人员需具备沟通表达能力
  9. java零碎要点---用java实现生成二维码,与解析代码实现
  10. 命运(HDU 2571 简单动态规划)
  11. 自己来实现一套IOC注解框架
  12. 利用VisualVm和JMX远程监控K8S里的Java进程
  13. await原理 js_深入浅出node.js异步编程 及async await原理
  14. 容易遗忘的JS知识点整理
  15. 一道面试题引发的pythonic
  16. 18年韩师插本c语言的题答案,插本全能题库
  17. THUNLP发布《更多数据,更多关系,更多上下文与更多开放:关系抽取问题综述与前瞻》阅读笔记
  18. 一个程序员的成长之路(持续更新)
  19. 完整责任链模式——回旋链
  20. 使用Axure RP8 模拟遮罩层显隐

热门文章

  1. 12W人编程能力暴增!网友:服气!选择比天赋更重要!
  2. TOJ4537: n阶行列式
  3. 【Spring实战】—— 3 使用facotry-method创建单例Bean总结
  4. crontab 命令
  5. [ubuntu] 摆脱一直敲打‘Y'('yes')的困境
  6. 浏览器下载附件Content-Disposition
  7. 「APIO2018」选圆圈
  8. jQuery zTree几种常用的使用方式
  9. 构建dubbo分布式平台-maven构建根项目
  10. 使用openssl生成rsa公钥和私钥