何为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机器id | 12bit 序列号 |
0 | 0000000000000000…0000 | 0000000000 | 000000000000 |
隐患
snowflake并不完美,因为有一种情况,snowflake产生的id是有可能会出现重复的
产生的id的组成:(符号位)+时间戳+机器id+序列号;
这三部分,机器id可以不重复,序列号也可以做到不重复,那唯一可能重复的就是时间戳了。
- 时间怎么会重复?
时间明明是一直向前的,除非时间倒退,退回到之前的某个时间点,再次产生的id才可能是重复的。你说对了,人类感受的时间是不会倒退的,但是,机器上的时间都是时钟,时钟可能会因为种种原因变慢了或者变快了。
比如有一天你(或者机器上的时间同步器)发现有一台机器的时钟变快了,于是往回拨1秒,然后就可能会出现重复的id
- 消除
时钟的问题
某些对时间及其敏感的程序,甚至会考虑使用GPS上的原子钟来做时钟同步;
或者,干脆有土豪(某歌)直接在数据中心自己搞原子钟,然并卵,时间同步时的网络传输延迟、抖动,依然无解。永远都是只能
减小
,无法消灭
。
示例源码,下载即可使用。欢迎下载~~~
下载源码链接
如果对你有帮助,记得点赞/评论/收藏~ 谢谢
何为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机器id | 12bit 序列号 |
0 | 0000000000000000…0000 | 0000000000 | 000000000000 |
隐患
snowflake并不完美,因为有一种情况,snowflake产生的id是有可能会出现重复的
产生的id的组成:(符号位)+时间戳+机器id+序列号;
这三部分,机器id可以不重复,序列号也可以做到不重复,那唯一可能重复的就是时间戳了。
- 时间怎么会重复?
时间明明是一直向前的,除非时间倒退,退回到之前的某个时间点,再次产生的id才可能是重复的。你说对了,人类感受的时间是不会倒退的,但是,机器上的时间都是时钟,时钟可能会因为种种原因变慢了或者变快了。
比如有一天你(或者机器上的时间同步器)发现有一台机器的时钟变快了,于是往回拨1秒,然后就可能会出现重复的id
- 消除
时钟的问题
某些对时间及其敏感的程序,甚至会考虑使用GPS上的原子钟来做时钟同步;
或者,干脆有土豪(某歌)直接在数据中心自己搞原子钟,然并卵,时间同步时的网络传输延迟、抖动,依然无解。永远都是只能
减小
,无法消灭
。
示例源码,下载即可使用。欢迎下载~~~
下载源码链接
如果对你有帮助,记得点赞/评论/收藏~ 谢谢