浩鲸科技:为什么要用雪花ID替代数据库自增ID?(转载)

2024-01-04

浩鲸科技的面试题如下:

image.png

其他面试题相对来说比较简单,大部人题目都可以在我的网站上( www.javacn.site)找到答案,这里就不再赘述,咱们今天只聊“为什么要使用雪花 ID 替代数据库自增 ID?”这个问题。

1.什么是雪花 ID?

雪花 ID(Snowflake ID)是一个用于分布式系统中生成唯一 ID 的算法,由 Twitter 公司提出。它的设计目标是在分布式环境下高效地生成全局唯一的 ID,具有一定的有序性。

雪花 ID 的结构如下所示:

image.png

这四部分代表的含义

  1. 符号位 :最高位是符号位,始终为 0,1 表示负数,0 表示正数,ID 都是正整数,所以固定为 0。
  2. 时间戳部分 :由 41 位组成,精确到毫秒级。可以使用该 41 位表示的时间戳来表示的时间可以使用 69 年。
  3. 节点 ID 部分 :由 10 位组成,用于表示机器节点的唯一标识符。在同一毫秒内,不同的节点生成的 ID 会有所不同。
  4. 序列号部分 :由 12 位组成,用于标识同一毫秒内生成的不同 ID 序列。在同一毫秒内,可以生成 4096 个不同的 ID。

2.Java 版雪花算法实现

接下来,我们来实现一个 Java 版的雪花算法:


  

java

public class SnowflakeIdGenerator {
  
  // 定义雪花 ID 的各部分位数
  private static final long TIMESTAMP_BITS = 41L;
  private static final long NODE_ID_BITS = 10L;
  private static final long SEQUENCE_BITS = 12L;

  // 定义起始时间戳(可根据实际情况调整)
  private static final long EPOCH = 1609459200000L;

  // 定义最大取值范围
  private static final long MAX_NODE_ID = (1L << NODE_ID_BITS) - 1;
  private static final long MAX_SEQUENCE = (1L << SEQUENCE_BITS) - 1;

  // 定义偏移量
  private static final long TIMESTAMP_SHIFT = NODE_ID_BITS + SEQUENCE_BITS;
  private static final long NODE_ID_SHIFT = SEQUENCE_BITS;

  private final long nodeId;
  private long lastTimestamp = -1L;
  private long sequence = 0L;

  public SnowflakeIdGenerator(long nodeId) {
    if (nodeId < 0 || nodeId > MAX_NODE_ID) {
      throw new IllegalArgumentException("Invalid node ID");
    }
    this.nodeId = nodeId;
  }

  public synchronized long generateId() {
    long currentTimestamp = timestamp();
    if (currentTimestamp < lastTimestamp) {
        throw new IllegalStateException("Clock moved backwards");
    }
    if (currentTimestamp == lastTimestamp) {
      sequence = (sequence + 1) & MAX_SEQUENCE;
      if (sequence == 0) {
        currentTimestamp = untilNextMillis(lastTimestamp);
      }
    } else {
      sequence = 0L;
    }
    lastTimestamp = currentTimestamp;
    return ((currentTimestamp - EPOCH) << TIMESTAMP_SHIFT) |
           (nodeId << NODE_ID_SHIFT) |
           sequence;
  }

  private long timestamp() {
    return System.currentTimeMillis();
  }

  private long untilNextMillis(long lastTimestamp) {
    long currentTimestamp = timestamp();
    while (currentTimestamp <= lastTimestamp) {
      currentTimestamp = timestamp();
    }
    return currentTimestamp;
  }
}

调用代码如下:


  

java

public class Main {
  public static void main(String[] args) {
    // 创建一个雪花 ID 生成器实例,传入节点 ID
    SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1);
    // 生成 ID
    long id = idGenerator.generateId();
    System.out.println(id);
  }
}

其中,nodeId 表示当前节点的唯一标识,可以根据实际情况进行设置。generateId 方法用于生成雪花 ID,采用同步方式确保线程安全。具体的生成逻辑遵循雪花 ID 的位运算规则,结合当前时间戳、节点 ID 和序列号生成唯一的 ID。

需要注意的是,示例中的时间戳获取方法使用了 System.currentTimeMillis(),根据实际需要可以替换为其他更精确的时间戳获取方式。同时,需要确保节点 ID 的唯一性,避免不同节点生成的 ID 重复。

3.雪花算法问题

虽然雪花算法是一种被广泛采用的分布式唯一 ID 生成算法,但它也存在以下几个问题:

  1. 时间回拨问题 :雪花算法生成的 ID 依赖于系统的时间戳,要求系统的时钟必须是单调递增的。如果系统的时钟发生回拨,可能导致生成的 ID 重复。时间回拨是指系统的时钟在某个时间点之后突然往回走(人为设置),即出现了时间上的逆流情况。
  2. 时钟回拨带来的可用性和性能问题 :由于时间依赖性,当系统时钟发生回拨时,雪花算法需要进行额外的处理,如等待系统时钟追上上一次生成 ID 的时间戳或抛出异常。这种处理会对算法的可用性和性能产生一定影响。
  3. 节点 ID 依赖问题 :雪花算法需要为每个节点分配唯一的节点 ID 来保证生成的 ID 的全局唯一性。节点 ID 的分配需要有一定的管理和调度,特别是在动态扩容或缩容时,节点 ID 的管理可能较为复杂。

4.如何解决时间回拨问题?

百度 UidGenerator 框架中解决了时间回拨的问题,并且解决方案比较经典,所以咱们这里就来给大家分享一下百度 UidGenerator 是怎么解决时间回拨问题的?

UidGenerator 介绍 :UidGenerator 是百度开源的一个分布式唯一 ID 生成器,它是基于 Snowflake 算法的改进版本。与传统的 Snowflake 算法相比,UidGenerator 在高并发场景下具有更好的性能和可用性。它的实现源码在: github.com/baidu/uid-g…

UidGenerator 是这样解决时间回拨问题的:UidGenerator 的每个实例中,都维护一个本地时钟缓存,用于记录当前时间戳。这个本地时钟会定期与系统时钟进行同步,如果检测到系统时钟往前走了(出现了时钟回拨),则将本地时钟调整为系统时钟。

4.为什么要使用雪花 ID 替代数据库自增 ID?

数据库自增 ID 只适用于单机环境,但如果是分布式环境,是将数据库进行分库、分表或数据库分片等操作时,那么数据库自增 ID 就有问题了。

例如,数据库分片之后,会在同一张业务表的分片数据库中产生相同 ID(数据库自增 ID 是由每个数据库单独记录和增加的),这样就会导致,同一个业务表的竟然有相同的 ID,而且相同 ID 背后存储的数据又完全不同,这样业务查询的时候就出问题了。

所以为了解决这个问题,就必须使用分布式中能保证唯一性的雪花 ID 来替代数据库的自增 ID。

5.扩展:使用 UUID 替代雪花 ID 行不行?

如果单从唯一性来考虑的话,那么 UUID 和雪花 ID 的效果是一致的,二者都能保证分布式系统下的数据唯一性,但是即使这样,也 不建议使用 UUID 替代雪花 ID ,因为这样做的问题有以下两个:

  1. 可读性问题 :UUID 内容很长,但没有业务含义,就是一堆看不懂的“字母”。
  2. 性能问题 :UUID 是字符串类型,而字符串类型在数据库的查询中效率很低。

所以,基于以上两个原因,不建议使用 UUID 来替代雪花 ID。

小结

数据库自增 ID 只适用于单机数据库环境,而对于分库、分表、数据分片来说,自增 ID 不具备唯一性,所以要要使用雪花 ID 来替代数据库自增 ID。但雪花算法依然存在一些问题,例如时间回拨问题、节点过度依赖问题等,所以此时,可以使用雪花算法的改进框架,如百度的 UidGenerator 来作为数据库的 ID 生成方案会比较好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浩鲸科技:为什么要用雪花ID替代数据库自增ID?(转载) 的相关文章

  • 跨境电商三大趋势已经涌现

    在过去的几年里 跨境电商在推动外贸增长中发挥了至关重要的作用 成为了引领行业发展的强大引擎 然而 随着2024年的到来 跨境电商行业又站在了崭新的起点 准备攀登新的发展高峰 数据显示 得益于经济的逐步复苏 未来三年跨境电商行业预计将以16
  • mysql+关掉密码过期

    mysql 关掉密码过期 要在MySQL中关闭密码过期功能 可以按照以下步骤进行操作 登录到MySQL服务器 使用管理员账户 如root 连接到数据库 mysql uroot ppassword 运行以下命令来查看当前的密码过期设置 SHO
  • 【计算机开题报告】智能社区管理系统

    一 设计目的及意义 随着经济的发展 人们生活水平的提高 工作和日常事务繁忙 人们对服务就有了更深入 更精细的要求 而计算机技术的迅猛发展 使得这种需求变为可能 传统的社区服务业也与互联网技术结合更加密切 这是社会发展的必然趋势 为解决社区中
  • sql临时表、创建虚拟表、select临时表、多行数据、自定义数据、插入数据

    SELECT FROM VALUES John 25 Jane 30 Mike 35 AS table name name age 方法2 select 1 2 union all select 3 4
  • 【计算机开题报告】 医药信息管理系统

    一 选题依据 简述国内外研究现状 生产需求状况 说明选题目的 意义 列出主要参考文献 1 研究背景 随着医药事业的不断壮大 相关单位对于医药信息的管理变得越来越重要 传统的手工管理效率低 易出错 费时费力 不能及时精确的收集 传递 存储 加
  • 天猫数据分析工具推荐(天猫第三方数据平台)

    在电商迅速发展的大背景下 做好天猫数据分析能够在多方面帮助品牌商家更好地运营店铺 塑造品牌 如通过数据分析了解消费者的需求 购买偏好 这有利于品牌商家及时调整商品结构 产品推广 商品宣传等等 灵活制定品牌的销售策略 那么 天猫平台行业 品牌
  • 2024年最热门的15个科技工作岗位

    1 系统安全管理员 系统安全管理员的任务是确保公司的网络 数据和系统免受网络安全威胁 方法是确保有适当的安全战略并保持最新的合规性和策略 要求 应聘者应具有网络安全职位的工作经验 并对合规性和安全协议的最佳实践有坚实的基础 这个职位通常需要
  • 【计算机毕业设计】个人日常事务管理系统

    进入21世纪网络和计算机得到了飞速发展 并和生活进行了紧密的结合 目前 网络的运行速度以达到了千兆 覆盖范围更是深入到生活中的角角落落 这就促使 管理系统的发展 管理系统可以实现远程处理事务 远程工作信息和随时追踪工作的状态 网上管理系统给
  • 【计算机毕业设计】航空信息管理系统

    传统信息的管理大部分依赖于管理人员的手工登记与管理 然而 随着近些年信息技术的迅猛发展 让许多比较老套的信息管理模式进行了更新迭代 飞机票信息因为其管理内容繁杂 管理数量繁多导致手工进行处理不能满足广大用户的需求 因此就应运而生出相应的航空
  • 【计算机毕业设计】基于web的山东红色旅游信息管理系统

    有效的处理想要的相关信息和如何传播有效的信息 一直是人类不断探索的动力 人类文明火种的传承都是通过了多种媒介作为载体 也是随着社会生产力的发展不断的更新 随着互联网的到来 信息传播与管理都上升了一个新的台阶 并且方便应用的同时也要考虑信息传
  • 【计算机毕业设计】校园体育赛事管理系统

    身处网络时代 随着网络系统体系发展的不断成熟和完善 人们的生活也随之发生了很大的变化 人们在追求较高物质生活的同时 也在想着如何使自身的精神内涵得到提升 而读书就是人们获得精神享受非常重要的途径 为了满足人们随时随地只要有网络就可以看书的要
  • 【计算机毕业设计】学生就业管理系统

    如今社会上各行各业 都喜欢用自己行业的专属软件工作 互联网发展到这个时候 人们已经发现离不开了互联网 新技术的产生 往往能解决一些老技术的弊端问题 因为传统学生就业信息管理难度大 容错率低 管理人员处理数据费工费时 所以专门为解决这个难题开
  • 【计算机毕业设计】网上拍卖系统

    现代经济快节奏发展以及不断完善升级的信息化技术 让传统数据信息的管理升级为软件存储 归纳 集中处理数据信息的管理方式 本网上拍卖系统就是在这样的大环境下诞生 其可以帮助使用者在短时间内处理完毕庞大的数据信息 使用这种软件工具可以帮助管理人员
  • 图解python | 字符串及操作

    1 Python元组 Python的元组与列表类似 不同之处在于元组的元素不能修改 元组使用小括号 列表使用方括号 元组创建很简单 只需要在括号中添加元素 并使用逗号隔开即可 tup1 ByteDance ShowMeAI 1997 202
  • 【计算机毕业设计】电商个性化推荐系统

    伴随着我国社会的发展 人民生活质量日益提高 于是对电商个性化推荐进行规范而严格是十分有必要的 所以许许多多的信息管理系统应运而生 此时单靠人力应对这些事务就显得有些力不从心了 所以本论文将设计一套电商个性化推荐系统 帮助商家进行商品信息 在
  • 【计算机毕业设计】二手家电管理平台

    时代在飞速进步 每个行业都在努力发展现在先进技术 通过这些先进的技术来提高自己的水平和优势 二手家电管理平台当然不能排除在外 二手家电管理平台是在实际应用和软件工程的开发原理之上 运用java语言以及前台VUE框架 后台SpringBoot
  • 【计算机毕业设计】springbootstone音乐播放器的设计与实现

    随着我国经济的高速发展与人们生活水平的日益提高 人们对生活质量的追求也多种多样 尤其在人们生活节奏不断加快的当下 人们更趋向于足不出户解决生活上的问题 stone音乐播放器展现了其蓬勃生命力和广阔的前景 与此同时 为解决用户需求 stone
  • 做测试不会 SQL?超详细的 SQL 查询语法教程来啦!

    前言 作为一名测试工程师 工作中在对测试结果进行数据比对的时候 或多或少要和数据库打交道的 要和数据库打交道 那么一些常用的sql查询语法必须要掌握 最近有部分做测试小伙伴表示sql查询不太会 问我有没有sql查询语法这一块的文档可以学习
  • 毕业设计:基于python人脸识别系统 LBPH算法 sqlite数据库 (源码)✅

    博主介绍 全网粉丝10W 前互联网大厂软件研发 集结硕博英豪成立工作室 专注于计算机相关专业 毕业设计 项目实战6年之久 选择我们就是选择放心 选择安心毕业 感兴趣的可以先收藏起来 点赞 关注不迷路 毕业设计 2023 2024年计算机毕业
  • 温室气体排放更敏感的模型(即更高的平衡气候敏感性(ECS))在数年到数十年时间尺度上也具有更高的温度变化(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码 数据

随机推荐