分布式发号器(2)

目录

 

数据结构

最大峰值型

最小粒度值型

并发

机器ID的分配

时间同步

设计验证

性能需求

调整时间是否会影响ID产生功能?

每4年一次同步润秒会不会影响ID产生功能?

 


数据结构

1. 最大峰值型:采用秒级有序,秒级时间占用30位,序列号占用20位

字段:|`版本`|`类型`|`生成方式`|`秒级时间`|`序列号`|`机器ID`|

位数:|*63*|*62*|*60-61*|*40-59*|*10-39*|*0-9*|


2. 最小粒度型:采用毫秒级有序,毫秒级时间占用40位,序列号占用10位

字段:|`版本`|`类型`|`生成方式`|`毫秒级时间`|`序列号`|`机器ID`|

位数:|*63*|*62*|*60-61*|*20-59*|*10-19*|*0-9*|
最大峰值型能够承受更大的峰值压力,但是粗略有序的粒度有点大。
最小粒度型有较细致的粒度,但是每个毫秒能承受的理论峰值有限,为1k,同一个毫秒如果有更多的请求产生,必须等到下一个毫秒再响应。
ID类型在配置时指定,需要重启服务才能互相切换。

最大峰值型

  • 序列号:20位,理论上每秒内平均可产生2^20= 1048576个ID,百万级别,如果系统的网络IO和CPU足够强大,可承受的峰值达到每毫秒百万级别。
    
    秒级时间:30位,表示秒级时间,2^30/60/60/24/365=34,也就是可使用30+年。
  • 机器ID:10位, 2^10=1024, 也就是最多支持1000+个服务器。中心发布模式和REST发布模式一般不会有太多数量的机器,按照设计每台机器TPS 1万/s,10台服务器就可以有10万/s的TPS,基本可以满足大部分的业务需求。
    但是考虑到在业务服务可以使用内嵌发布方式,对机器ID的需求量变得更大,这里最多支持1024个服务器。
  • 生成方式:2位,用来区分三种发布模式:嵌入发布模式,中心服务器发布模式,REST发布模式。
    00:嵌入发布模式
    01:中心服务器发布模式
    02:REST发布模式
    03:保留未用
  • ID类型:1位,用来区分两种ID类型:最大峰值型和最小粒度型。
    0:最大峰值型
    1:最小粒度型
  • 版本:1位,用来做扩展位或者扩容时候的临时方案。作为30年后扩展使用,或者在30年后ID将近用光之时,扩展为秒级时间或者毫秒级时间来挣得系统的移植时间窗口,其实只要扩展一位,完全可以再使用30年。
    0:默认值,以免转化为整型再转化回字符串被截断 
    1:表示扩展或者扩容中 

最小粒度值型

序列号:10位,每毫秒内序列号总计2^10=1024个, 也就是每个毫秒最多产生1000+个ID,理论上承受的峰值完全不如最大峰值方案。

毫秒级时间:40位,表示毫秒级时间,2^40/1000/60/60/24/365=34,同样可以使用30+年。

并发

对于中心服务器和REST发布方式,ID生成的过程涉及到网络IO和CPU操作,ID的生成基本都是内存到高速缓存的操作,没有IO操作,网络IO是系统的瓶颈。
相对于CPU计算速度来说网络IO是瓶颈,因此,ID产生的服务使用多线程的方式,对于ID生成过程中的竞争点time和sequence,这里使用了多种实现方式

使用concurrent包的ReentrantLock进行互斥,这是缺省的实现方式,也是追求性能和稳定两个目标的妥协方案。
使用传统的synchronized进行互斥,这种方式的性能稍微逊色一些,通过传入JVM参数-Dvesta.sync.lock.impl.key=true来开启。
使用concurrent包的ReentrantLock进行互斥,这种实现方式的性能非常高,但是在高并发环境下CPU负载会很高,通过传入JVM参数-Dvesta.atomic.impl.key=true来开启。

机器ID的分配

将机器ID分为两个区段,一个区段服务于中心服务器发布模式和REST发布模式,另外一个区段服务于嵌入发布模式。

0-923:嵌入发布模式,预先配置,(或者由Zookeeper产生,第二版中实现),最多支持924台内嵌服务器
924 – 1023:中心服务器发布模式和REST发布模式,最多支持300台,最大支持300*1万=300万/s的TPS

如果嵌入式发布模式和中心服务器发布模式以及REST发布模式的使用量不符合这个比例,我们可以动态调整两个区间的值来适应。

另外,各个垂直业务之间具有天生的隔离性,每个业务都可以使用最多1024台服务器。

时间同步

使用Linux的定时任务crontab,定时通过授时服务器虚拟集群(全球有3000多台服务器)来核准服务器的时间。

设计验证

1. 我们根据不同的信息分段构建一个ID,使ID具有全局唯一,可反解和可制造。

2. 我们使用秒级别时间或者毫秒级别时间以及时间单元内部序列递增的方法保证ID粗略有序。

3. 对于中心服务器发布模式和REST发布模式,我们使用多线程处理,为了减少多线程间竞争,我们对竞争点time和sequence使用   ReentrantLock来进行互斥,由于ReentrantLock内部使用CAS,这比JVM的Synchronized关键字性能更好,在千兆网卡的前提下,至少可达到1万/s以上的TPS。

4. 由于我们支持中心服务器发布模式,嵌入式发布模式和REST发布模式,如果某种模式不可用,可以回退到其他发布模式,如果Zookeeper不可用,可以会退到使用本地预配的机器ID。从而达到服务的最大可用。

5. 由于ID的设计,我们最大支持1024台服务器,我们将服务器机器号分为两个区段,一个从0开始向上,一个从128开始向下,并且能够动态调整分界线,满足了可伸缩性。

性能需求

最终的性能验证要保证每台服务器的TPS达到1万/s以上。

调整时间是否会影响ID产生功能?

  • 未重启机器调慢时间,Vesta抛出异常,拒绝产生ID。重启机器调快时间,调整后正常产生ID,调整时段内没有ID产生。
  • 重启机器调慢时间,Vesta将可能产生重复的时间,系统管理员需要保证不会发生这种情况。重启机器调快时间,调整后正常产生ID,调整时段内没有ID产生。

每4年一次同步润秒会不会影响ID产生功能?

  • 原子时钟和电子时钟每四年误差为1秒,也就是说电子时钟每4年会比原子时钟慢1秒,所以,每隔四年,网络时钟都会同步一次时间,但是本地机器Windows,Linux等不会自动同步时间,需要手工同步,或者使用ntpupdate向网络时钟同步。
    
    
  • 由于时钟是调快1秒,调整后不影响ID产生,调整的1s内没有ID产生。

 

 

 

 

 

你可能感兴趣的:(分布式发号器)