玄靖
刘兵,花名玄靖,目前供职于阿里巴巴,开源技术爱好者,高性能Redis中间件NRedis-Proxy作者,目前研究方向为java中间件,微服务等技术。
(一)什么是分布式发号器
说起分布式发号器的前生今世,咱们应该感恩这个时代;随着互联网在中国越来越普及化,单机系统或者一个小系统已经无法满足需要,随着用户逐渐增多,数据量越来越大,单个应用或者单个数据库已经无法满足需求,在应用以至于微服务来临,在数据库存储方面分库分表来临,可以解决问题;但是新的问题产生,怎么样做到多个应用可以有唯一主键或者序号,防止数据重复呢?分布式发号器正好为解决这个问题,可以让大家无须为这个问题烦恼了,这是本人写这篇文章初衷
(二)分布式发号器优势
1)解决分库分表中唯一序号的问题
2)解决分布式应用或者微服务框架中唯一序号的问题
3)提供可定制化生成规则,根据业务需求可自定义扩展
4)性能高效且系统简单稳定
5)系统可任意扩展
(三)分布式发号器架构图
(四)分布式发号器流程图
1)分布式发号器重要字段
2)concurrentValue不存在的流程图
3)concurrentValue存在的流程图
(五)目前存在分布式发号器解决方案
1)UUID
Universally Unique IDentifier(UUID),有着正儿八经的RFC规范,是一个128bit的数字,也可以表现为32个16进制的字符(每个字符0-F的字符代表4bit),中间用"-"分割。
?时间戳+UUID版本号: 分三段占16个字符(60bit+4bit)
?Clock Sequence号与保留字段:占4个字符(13bit+3bit)
?节点标识:占12个字符(48bit)
2)Hibernate
Hibernate的CustomVersionOneStrategy.java,解决了之前version 1的两个问题
?时间戳(6bytes, 48bit):毫秒级别的,从1970年算起,能撑8925年....
?顺序号(2bytes, 16bit, 最大值65535): 没有时间戳过了一毫秒要归零的事,各搞各的,short溢出到了负数就归0。
?机器标识(4bytes 32bit): 拿localHost的IP地址,IPV4呢正好4个byte,但如果是IPV6要16个bytes,就只拿前4个byte。
?进程标识(4bytes 32bit): 用当前时间戳右移8位再取整数应付,不信两条线程会同时启动。
3)MongoDB
MongoDB的ObjectId.java
?时间戳(4 bytes 32bit):是秒级别的,从1970年算起,能撑136年。
?自增序列(3bytes 24bit, 最大值一千六百万): 是一个从随机数开始(机智)的Int不断加一,也没有时间戳过了一秒要归零的事,各搞各的。因为只有3bytes,所以一个4bytes的Int还要截一下后3bytes。
?机器标识(3bytes 24bit): 将所有网卡的Mac地址拼在一起做个HashCode,同样一个int还要截一下后3bytes。搞不到网卡就用随机数混过去。
?进程标识(2bytes 16bits):从JMX里搞回来到进程号,搞不到就用进程名的hash或者随机数混过去。
可见,MongoDB的每一个字段设计都比Hibernate的更合理一点,时间戳是秒级别的,自增序列变长了,进程标识变短了。总长度也降到了12 bytes 96bit。
4)Twitter的snowflake派号器
snowflake也是一个派号器,基于Thrift的服务,不过不是用redis简单自增,而是类似UUID version1,
只有一个Long 64bit的长度,所以IdWorker紧巴巴的分配成:
?时间戳(42bit) :自从2012年以来(比那些从1970年算起的会过日子)的毫秒数,能撑139年。
?自增序列(12bit,最大值4096):毫秒之内的自增,过了一毫秒会重新置0。
?DataCenter ID (5 bit, 最大值32):配置值,支持多机房。
?Worker ID ( 5 bit, 最大值32),配置值,因为是派号器的id,一个机房里最多32个派号器就够了,还会在ZK里做下注册。
可见,因为是中央派号器,把至少40bit的节点标识都省出来了,换成10bit的派号器标识。所以整个UID能够只用一个Long表达。
另外,这种派号器,client每次只能一个ID,不能批量取,所以额外增加的延时是问题,而且只能1024台机器范围之内。
以上几种方案同一个问题,不可自定义,位数过长
(六)推荐大神开涛书籍(京东有卖,绝对干货满满,买书送知识)
扩展阅读
纪实篇:
用技术点亮成都 | 中生代技术嘉年华成都站纪实
用技术点亮魔都 | 中生代技术嘉年华上海站纪实
用技术点亮帝都 | 中生代技术嘉年华北京站纪实
分享篇:
中生代技术嘉年华成都 | O2O数据应用探索 | 新美大技术总监樊聪
中生代技术嘉年华成都 | 融数数据基于DevOps的微服务架构演进之路 | 融数CTO王东
中生代技术嘉年华成都 | OKR管理 | 23魔方联合创始人王勉
中生代技术嘉年华成都 | 智能营销与未来独角兽 | 骆驼码创始人宋春雨
中生代技术嘉年华成都 | 大卫张33|研发管理在互联网时代|文末有视频
中生代技术嘉年华成都 | 大胡子 姜志辉 | 跨界 认知 疯人院 | 有视频
中生代技术嘉年华成都 | AWS蒙维 | 无服务器计算架构
活动预告:
AWSome Day
AWSome Day是AWS在全球各大城市巡回举办的重要活动,进入中国已有四年时间。
它是一场为时一天、结合教育与技术新知的云计算免费研讨会,适合开发人员、 IT 技术人员、或技术/业务领域决策者。
它将引领您从入门到精通,由浅至深地打好扎实的云计算基础;同时,您可以在现场与培训讲师探讨问题、与AWS专家面对面沟通、与同行伙伴共同探讨趋势和未来。
标签: redis客户端SLave
评论列表
es, 16bit, 最大值65535): 没有时间戳过了一毫秒要归零的事,各搞各的,short溢出到了负数就归0。 ?机器标识(4bytes 32bit): 拿localHost的IP地址,IPV4呢正好4个byte,但如果是IPV6要16个bytes,就只拿前4个byte。 ?进程标识(
最大值一千六百万): 是一个从随机数开始(机智)的Int不断加一,也没有时间戳过了一秒要归零的事,各搞各的。因为只有3bytes,所以一个4bytes的Int还要截一下后3bytes。 ?机器标识(3bytes 24bit): 将所有
搞不到就用进程名的hash或者随机数混过去。 可见,MongoDB的每一个字段设计都比Hibernate的更合理一点,时间戳是秒级别的,自增序列变长了,进程标识变短了。总长度也降到了12 bytes 96bit。