zoukankan      html  css  js  c++  java
  • 分布式id

    是什么

    分布式id是分布式系统中地一个全局唯一id。

    为什么

    以前业务量小的时候,进行系统开发一个mysql实例就可以提供服务,再大点的时候进行读写分离也可以应付过来,此时数据库主键自增就可以满足。但随着业务的不断扩展,读写分离扛不住后就需要进行分库分表,但在进行分库分表后就需要一个唯一的ID来标识一条记录

    分布式id的条件

    • 全局唯一性:基本要求就是保证id的全局唯一性
    • 高性能:高性能低延时,ID生成响应快
    • 趋势递增:在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用B-tree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。
    • 信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要ID无规则、不规则。

    UUID

    UUID(通用唯一编码),它是全球唯一的编码 可以使用,但不推荐

    @Test
    public void testUUID(){
        //利用hutool生成uuid
        String uuid = IdUtil.randomUUID();
        System.out.println(uuid);
    }
    

    UUID的生成非常简单,输出结果为 aad66041-58e2-4fc3-a728-29295086e343(可以去掉中间的 -),但是UUID并不适用于实际的业务开发中。

    • 优点

    生成简单,本地生成没有网络消耗,具有唯一性

    • 缺点

    无序的字符串,不具备趋势递增的特性
    没有具体的业务含义
    不仅长度过长,而且还是字符串,会导致mysql插入删除是数据位置变动频繁,而且字符串作为索引查询慢。

    基于数据库自增ID

    单数据库模式下使用数据库自增充当分布式ID是一个很好的选择。但是在高并发场景下,就不推荐使用了。

    • 优点

    实现简单,ID自增,数值类型查询速度快

    • 缺点

    DB单点存在宕机风险,无法抗住高并发场景

    基于数据库集群模式

    单点数据库方式扛不住高并发,存在宕机风险,那么就做成多主库模式集群,也就是多个mysql实例都能单独长生自增ID。那么这又会出现一个问题,多个mysql都是从1开始自增,会造成重复的ID。解决方案,设置起始值和自增步长。
    假设是两个主库
    主库1:

    set @@auto_increment_offset = 1;     -- 起始值
    set @@auto_increment_increment = 2;  -- 步长
    

    主库2:

    set @@auto_increment_offset = 2;     -- 起始值
    set @@auto_increment_increment = 2;  -- 步长
    

    这样两个库的主键自增分别为:

    1 3 5 7 9
    2 4 6 8 10

    这种方法看似解决了自增和id唯一性的问题,但是随着业务量的增加,两个主库扛不住压力了,就需要进行mysql实例的扩展,此时就麻烦了,如果需要增加第三台主库,那么就需要从新设置三个主库的起始值和步长。

    • 优点:

    解决了DB单点问题

    • 缺点:

    不利于后续扩容

    基于redis模式

    Redis是单线程的并且reids中的incr命令是原子自增的。
    redis是第三方的组件,如果本身系统中就没有使用redis,这时使用redis就会增加系统的负担,因为一旦使用就是集群,而且至少得三个哨兵集群。
    redis如果使用RBD作为持久化,那在一个快照时间内宕机了,此时还未进行吃就会,恢复后会出现ID重复
    使用AOF进行持久化,恢复较慢。(至少丢失1s得数据)

    雪花算法

    雪花算法时twitter开源得分布式id生成方案。其核心思想就是:使用一个64bit得long型数字作为全局唯一id

    第一部分1个bit:0,二进制的最高位为符号位。0表示整数,1表示负数。
    第二部分是41bit的时间戳。单位是毫秒。41bit可以表示的数字多达241-1,也就是可以标识241-1毫秒,约等于69年(从1970年开始)。
    第三部分5个bit:表示机房id,最多表示2^5个机房
    第四部分为5个bit:表示的是机器id。每个房间里可以有2^5个机器。
    第五部分12个bit:表示序号,就是某个机房某台机器上一毫秒内同时生成的id的序号。12bit可以代表的最大正整数是2^12-1,一共4096个数,也就是说一毫秒内可以生成4096个唯一id。

    • 优点:
      高性能高可用,生成时不依赖于数据库,完全在内存中生成。
      容量大:每秒能生成百万的自增id
      id自增:时间时自增的,所以生成的id也是自增的。

    • 缺点:
      依赖与系统时间的一致性,如果系统时间被回调,或者改变,可能造成重复的id。

  • 相关阅读:
    riot.js教程【三】访问DOM元素、使用jquery、mount输入参数、riotjs标签的生命周期
    博客园文章编辑器5.0版本发布(markdown版)
    【开源】博客园文章编辑器4.0版发布
    博客园文章编辑器【客户端应用程序】V3.0.0发布
    博客园文章编辑器【客户端应用程序】V2.0.0发布,命名为51cnblogs
    在VSCode中编辑HTML文档时,在Dom标签上写style属性时智能提示的问题
    产品经理做什么?
    riot.js教程【二】组件撰写准则、预处理器、标签样式和装配方法
    riot.js教程【一】简介
    程序员的时间管理哲学——打造自己的分时管理系统
  • 原文地址:https://www.cnblogs.com/liuzhidao/p/14848569.html
Copyright © 2011-2022 走看看