共计 2227 个字符,预计需要花费 6 分钟才能阅读完成。
本篇内容介绍了“关于主键的知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让丸趣 TV 小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
1. UUID 模式
通用唯一识别码 (Universally Unique Identifier),根据标准方法生成,不依赖中央机构的注册和分配,UUID 具有唯一性重复 UUID 码概率接近零,可以忽略不计。UUID 具有多个版本:基于时间的 UUID、DCE 安全的 UUID、基于名字的 UUID(MD5)(UUID.nameUUIDFromBytes())、随机 UUID(UUID.randomUUID().toString())、基于名字的 UUID(SHA1),Version 1/ 2 适合应用于分布式计算环境下,具有高度的唯一性;Version 3/ 5 适合于需要相同内容生成相同 UUID 的业务场景下;Version 4 建议不要使用 (随机数有可能出现重复,但是重复的概率极低,在设计时需要考虑到这一点)。
UUID 虽然解决了依赖于数据库生成主键的策略,但是也存在一些不足:占用存储空间大; 随机生成,不具有连续性,作为主键时性能较差; 无法根据主键进行排序,确定记录插入的先后顺序; 对于开发人员不友好; 如果生成过程中使用了机器 MAC 地址,存在一定安全隐患。
2. 步长模式
即 Flickr 的 sharding 主键生成方案。使用多台数据库服务器,通过设置不同的起始值、一致自增步长,让每个数据库中各表主键保持唯一。如图所示:
步长方式在一定程度上解决了高并发的问题,但是也存在一些问题如:扩展困难,设置好步长后,再进行扩展将会比较困难;ID 并不是按顺序严格单调递增的特性,只是趋势递增; 每次获取 ID 仍然需要读写一次数据库,仍然存在瓶颈。
3. 号段模式
即每次从数据库获取 id 时,从数据库取到当前 id 最大值,然后返回 max+step,当应用程序用完这个号段后,再从数据库获取下一个长度为 step 的号段。为此需要专门设计一张用以记录 id 的表,在应用服务为集群,而主键服务器为单点时,多个应用服务节点同时获取 id 时,会产生冲突,可以增加 version 字段从而使用乐观锁进行并发访问控制。
号段模式将主键缓存在应用服务端,从而减少对数据库的访问频率; 在数据库数据库不可用时,应用服务仍然可以持续运行一段时间直到当前号段用完; 但是在应用服务重启时有可能丢失部分 id,导致 id 增长不连续。
基于号段模式有一些成熟方案,且经过实践验证:美团的 Leaf-segment 对号段发放方式进行了双 buffer 缓存及高可用容灾优化。采用双 buffer 模式,在当前号段消费到某个点时就异步的把下一个号段加载到内存中。而不需要等到号段用尽的时候才去更新号段,不会在应用服务器向数据库请求 id 时,因为 id 号段没有取回来,导致线程阻塞。
滴滴的 TinyId 参照了美团 Leaf 的实现方式,并对其做了扩展,增加了多 db 支持和 tinyid-client。
4. snowflake 模式 (雪花算法)
Twitter 实现的分布式 ID 生成算法。结构如下:0-00000000000000000000000000000000000000000-00000-00000-000000000000
1 bit:保留位,为符号位,全部为 0,表示生成的 id 都是正数。
41bit:时间戳,单位为毫秒,41 位可以表示 69 年的时间。
10bit:机器 id,10bit 里面 5 位代表机房 id,5 位代表机器 id,可以表示 32 个机房,每个机房里面可以用 32 台机器。
12bit:12 位序列号,按顺序递增,记录每个节点 1 毫秒内产生的 id,每毫秒可以产生 4096 个 id。
snowflake 的优点:
主键在单个节点上是按序列递增的,能够按照时间趋势进行递增。
主键的生成不依赖于数据库,可以由应用程序生成。
在分布式集群内不会产生重复 id。
可以根据业务需求对 bit 位进行调整。
snowflake 的缺点:
对于时间依赖较高,如果时间回拨,则会产生主键重复情况。
当集群规模较大时,workid 配置会增加一定成本。
美团的 Leaf-snowflake,使用 zk 解决了 snowflake 依赖于时钟,时间回拨产生重复主键问题; 百度的 UidGenerator,支持自定义时间戳、workerId、序列号等。
5. Redis 模式
利用 Redis 原子操作 INCR 和 INCRBY 来实现,使用 Redis 集群提高并发量,与步长模式类似,只不过将 id 生成器由传统数据库换成效率更高的 Redis 数据库。但是当 Redis 重启或者宕机,记录主键值会丢失,所以利用 Redis 进行主键生成时需要对当前主键值进行持久化。Redis 支持 RDB 和 AOF 两种持久化机制。RDB 模式下,可能会丢失部分未打镜像的数据,根据快照恢复后会产生部分重复 ID,故 RDB 不适合实施持久化 Redis 数据场景。AOF 以独立日志记录每次写命令,重启时执行日志中的命令进行数据恢复,不会出现 ID 重复现象,但是会由于备份命令过多,导致 Redis 恢复数据时间较长。
以上介绍了五种数据库主键的生成策略,大家可以根据具体业务场景和系统实际情况选择一款最适合自己的主键策略,提升数据库性能,保证在高并发情况下系统运行稳定性。
“关于主键的知识点有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注丸趣 TV 网站,丸趣 TV 小编将为大家输出更多高质量的实用文章!