Laravel 分布式唯一 ID 生成器使用
发布时间 - 2020-06-17 00:00:00 点击率:次在应用程序中,经常需要全局唯一的id作为数据库主键。如何生*局唯一id?
首先,需要确定全局唯一ID是整型还是字符串?如果是字符串,那么现有的UUID就完全满足需求,不需要额外的工作。缺点是字符串作为ID占用空间大,索引效率比整型低。
如果采用整型作为ID,那么首先排除掉32位int类型,因为范围太小,必须使用64位long型。
采用整型作为ID时,如何生成自增、全局唯一且不重复的ID?
方案一:利用数据库的自增ID,从1开始,基本可以做到连续递增。Oracle可以用SEQUENCE,MySQL可以用主键的AUTO_INCREMENT,虽然不能保证全局唯一,但每个表唯一,也基本满足需求。
数据库自增ID的缺点是数据在插入前,无法获得ID。数据在插入后,获取的ID虽然是唯一的,但一定要等到事务提交后,ID才算是有效的。有些双向引用的数据,不得不插入后再做一次更新,比较麻烦。
第二种方式是采用一个集中式ID生成器,它可以是Redis,也可以是ZooKeeper,也可以利用数据库的表记录最后分配的ID。
这种方式最大的缺点是复杂性太高,需要严重依赖第三方服务,而且代码配置繁琐。一般来说,越是复杂的方案,越不可靠,并且测试越痛苦。
第三种方式是类似Twitter的Snowflake算法,它给每台机器分配一个唯一标识,然后通过时间戳+标识+自增实现全局唯一ID。这种方式好处在于ID生成算法完全是一个无状态机,无网络调用,高效可靠。缺点是如果唯一标识有重复,会造成ID冲突。
Snowflake算法采用41bit毫秒时间戳,加上10bit机器ID,加上12bit序列号,理论上最多支持1024台机器每秒生成4096000个序列号,对于Twitter的规模来说够用了。
但是对于绝大部分普通应用程序来说,根本不需要每秒超过400万的ID,机器数量也达不到1024台,所以,我们可以改进一下,使用更短的ID生成方式:
53bitID由32bit秒级时间戳+16bit自增+5bit机器标识组成,累积32台机器,每秒可以生成6.5万个序列号,核心代码:
private static synchronized long nextId(long epochSecond) {
if (epochSecond < lastEpoch) {
// warning: clock is turn back:
logger.warn("clock is back: " + epochSecond + " from previous:" + lastEpoch);
epochS
econd = lastEpoch;
}
if (lastEpoch != epochSecond) {
lastEpoch = epochSecond;
reset();
}
offset++;
long next = offset & MAX_NEXT;
if (next == 0) {
logger.warn("maximum id reached in 1 second in epoch: " + epochSecond);
return nextId(epochSecond + 1);
}
return generateId(epochSecond, next, SHARD_ID);}时间戳减去一个固定值,此方案最高可支持到2106年。
如果每秒6.5万个序列号不够怎么办?没关系,可以继续递增时间戳,向前“借”下一秒的6.5万个序列号。
同时还解决了时间回拨的问题。
机器标识采用简单的主机名方案,只要主机名符合host-1,host-2就可以自动提取机器标识,无需配置。
最后,为什么采用最多53位整型,而不是64位整型?这是因为考虑到大部分应用程序是Web应用,如果要和JavaScript打交道,由于JavaScript支持的最大整型就是53位,超过这个位数,JavaScript将丢失精度。因此,使用53位整数可以直接由JavaScript读取,而超过53位时,就必须转换成字符串才能保证JavaScript处理正确,这会给API接口带来额外的复杂度。这也是为什么新浪微博的API接口会同时返回id和idstr的原因。
推荐教程:《PHP》《Laravel教程》
# laravel
# 整型
# 万个
# 应用程序
# 最多
# 不需要
# 可以用
# 主键
# 是一个
# 我们可以
# 用了
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
Linux安全能力提升路径_长期防护思维说明【指导】
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知
专业商城网站制作公司有哪些,pi商城官网是哪个?
Laravel如何配置和使用缓存?(Redis代码示例)
如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤
北京网站制作公司哪家好一点,北京租房网站有哪些?
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境
如何用PHP快速搭建CMS系统?
Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率
如何用AI帮你把自己的生活经历写成一个有趣的故事?
网站图片在线制作软件,怎么在图片上做链接?
Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
,南京靠谱的征婚网站?
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
Laravel如何处理和验证JSON类型的数据库字段
Laravel怎么在Blade中安全地输出原始HTML内容
微信小程序 五星评分(包括半颗星评分)实例代码
佛山企业网站制作公司有哪些,沟通100网上服务官网?
青岛网站建设如何选择本地服务器?
如何在宝塔面板中创建新站点?
如何快速重置建站主机并恢复默认配置?
如何在万网开始建站?分步指南解析
JavaScript中如何操作剪贴板_ClipboardAPI怎么用
如何在阿里云香港服务器快速搭建网站?
香港网站服务器数量如何影响SEO优化效果?
如何自定义建站之星模板颜色并下载新样式?
,交易猫的商品怎么发布到网站上去?
如何用PHP工具快速搭建高效网站?
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
javascript事件捕获机制【深入分析IE和DOM中的事件模型】
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
Laravel如何使用查询构建器?(Query Builder高级用法)
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
android nfc常用标签读取总结
Laravel如何记录自定义日志?(Log频道配置)
Laravel模型关联查询教程_Laravel Eloquent一对多关联写法
文字头像制作网站推荐软件,醒图能自动配文字吗?
详解阿里云nginx服务器多站点的配置
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
Laravel如何与Docker(Sail)协同开发?(环境搭建教程)


econd = lastEpoch;
}
if (lastEpoch != epochSecond) {
lastEpoch = epochSecond;
reset();
}
offset++;
long next = offset & MAX_NEXT;
if (next == 0) {
logger.warn("maximum id reached in 1 second in epoch: " + epochSecond);
return nextId(epochSecond + 1);
}
return generateId(epochSecond, next, SHARD_ID);}