何为SnowflakeID雪花id构造器

一个适合大量数据的主键生成器

  • 可以尽可能的让数据靠拢
  • 可以赋予主键更多的区分信息这个是一个附加的也是一个短板
  • 支持数据库的扩容/分片(该id是 全球唯一、轻量的)

比较


  • 自增主键

利用数据库产生自增id,保证唯一性,单独使用一张(或固定几张)数据库表专门用来产生自增id,与业务无关,后续不再重新分表,数据量大时 可以删除早一些时候产生的数据

  • 好处: 实现简单,容易理解
  • 劣势:严重依赖数据库,id产生速率受数据库性能以及连接数据库的网络影响

  • 时间戳

时间戳做唯一id

  • 优势: 简单/简单/简单
  • 劣势: 并发高或者分布式环境中基本不可行,同一时间生成的id是重复的,不满足全局唯一

  • 借助Redis实现主键

利用Redis原子操作incrBy

  • 好处:实现简单,容易理解
  • 坏处:依赖Redis,且Redis需要持久化

  • UUID/GUID

  • 好处:使用非常简单,不需要依赖其他设施
  • 坏处:太长,128bit,不适合做数据库主键

UUID/GUID 不适合 做主键的原因 太长

UUID/GUID 的特点

  • 唯一,随机
  • 适合分布式 / 高并发

UUID/GUID 的缺点

就日常使用最多的mysql 来说,主键常常伴随索引。索引中的值就是主键的值。
若数据量超级大/海海量 的时候,索引的操作 将变得非常损耗性能。为什么损耗性能呢?因为太长导致读取 计算都是消耗资源的。
若对上述损耗不存在压力/用户也能接受,可以不用理会

为何追求递增?

因为递增最大的优势就是对磁盘IO是友好的。
熟悉磁盘结构的同学们都知道,随机写的效率是很慢的,因为磁头需要转动到指定的位置,这个磁头转动的过程比起cpu或者内存来,完全不是一个数量级的,太慢太慢了,所以如果能尽可能的使数据靠近在一一起(递增就能靠在一起),那么就不需要频繁的抬起磁头,转动磁盘,写数据了,一路写到底会快很多。
一些大型分布式数据库,比如HBase,ElasticSearch等,也都是利用顺序写这个特点提高数据的写入性能的

说到这里雪花算法ID生成器,便应运而生了!

核心原理

符号位 + 时间戳 + 机器id + 序列号

符号位(不使用,保证为是正数)41bit时间戳位10bit机器id12bit 序列号
00000000000000000…00000000000000000000000000

隐患

snowflake并不完美,因为有一种情况,snowflake产生的id是有可能会出现重复的

产生的id的组成:(符号位)+时间戳+机器id+序列号;
这三部分,机器id可以不重复,序列号也可以做到不重复,那唯一可能重复的就是时间戳了。

  • 时间怎么会重复?

时间明明是一直向前的,除非时间倒退,退回到之前的某个时间点,再次产生的id才可能是重复的。你说对了,人类感受的时间是不会倒退的,但是,机器上的时间都是时钟,时钟可能会因为种种原因变慢了或者变快了。

比如有一天你(或者机器上的时间同步器)发现有一台机器的时钟变快了,于是往回拨1秒,然后就可能会出现重复的id

  • 消除时钟的问题

某些对时间及其敏感的程序,甚至会考虑使用GPS上的原子钟来做时钟同步;

或者,干脆有土豪(某歌)直接在数据中心自己搞原子钟,然并卵,时间同步时的网络传输延迟、抖动,依然无解。永远都是只能减小无法消灭

示例源码,下载即可使用。欢迎下载~~~

下载源码链接

如果对你有帮助,记得点赞/评论/收藏~ 谢谢

https://blog.csdn.net/zyj0070/article/details/108776246
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐