zoukankan      html  css  js  c++  java
  • 分布式唯一ID方案

    背景

      在复杂的分布式系统中,往往需要对大量的数据和消息进行唯一标识。

      如对大量的订单做分库分表后,需要有一个唯一的ID来标识一条数据或消息,数据库的自增ID显然不能满足需求。

      

      业务系统对分布式唯一ID的要求:

        ①:全局唯一性,不能重复

        ②:趋势递增,在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDMS使用B-tree的数据结构来存储索引数据,在主键的选择上面应该尽量使用有序的主键保证写入性能

        ③:单调递增,保证下一个ID一定大于上一个ID

        ④:信息安全,如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要ID无规则、不规则

    常用方案

     1、UUID

      优点:生成简单,本地生成,没有网络消耗,性能非常高

      缺点:

        1)每次生成的ID是无序的,无法保证趋势递增,不能作为数据库主键,否则会引起索引数据位置频繁变动,严重影响性能

        2)UUID的字符串存储,查询效率慢

        3)存储空间大

        4)ID本事无业务含义,不可读
        

     2、Redis 

      利用redis的原子性自增,具体实现为:

      年份 + 当天距当年第多少天 + 天数 + 小时 + redis自增

      

      优点:

        有序递增,可读性强
      缺点:

        占用带宽,每次要向redis进行请求

     3、雪花snowflake算法

      snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。

      其核心思想是:使用41bit作为毫秒数,10bit作为work ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。

      snowflake算法生成64位的二进制正整数,然后转换成10进制的数。

      64位二进制数组成部分如下:

         

      优点:

        1)此方案每秒能够产生409.6万个ID,性能快

        2)时间戳在高位,自增序列在低位,整个ID是趋势递增的,按照时间有序递增

        3)灵活度高,可以根据业务需求,调整bit位的划分,满足不同的需求

      缺点:

        只能保证work id相同的情况下生成的id是递增的

        依赖机器的时钟,如果服务器时钟回拨,会导致重复ID生成  

      时钟回拨问题的解决方案:

        1)回拨之后更换work id

        2)等时间追上来再去生成id

     4、美团Leaf

     https://tech.meituan.com/2017/04/21/mt-leaf.html

    参考:https://juejin.cn/post/6844903562007314440

    END.

  • 相关阅读:
    【leetcode】Sum Root to Leaf Numbers(hard)
    【leetcode】First Missing Positive(hard) ☆
    【leetcode】Next Permutation(middle)
    【好玩的应用】QQ连连看辅助工具
    【leetcode】Binary Tree Preorder Traversal (middle)★
    【leetcode】Reverse Words in a String(hard)☆
    【leetcode】Same Tree(easy)
    【leetcode】Factorial Trailing Zeroes(easy)
    【leetcode】Maximum Gap(hard)★
    Behavioral模式之Chain of Responsibility模式
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/14200747.html
Copyright © 2011-2022 走看看