赵志浩
Published on 2022-07-27 / 13 Visits
0
0

cantor基于redis的发号器

cantor的主要玩法是基于redis,

主要是基于redis的Hincrby命令:Redis Hincrby 命令 (runoob.com)

以业务方发送业务ID为主,后端服务器,根据当前的秒级时间,来创建对应的key,

HINCRBY KEY_NAME FIELD_NAME INCR_BY_NUMBER

HINCRBY 秒级时间戳 业务ID 100000

直接上述的命令,秒级时间戳是key,对用的业务id是该 秒级时间戳的key,value是 10w,

该命令执行成功后,得到对应的10w结果,此时会把该10的数据,存储到对应的buffer中,

当然,实际存储的是,当前的rage 1000,最终的位数是10w,每次递增这个rage,1000-2000-3000

直到用到10w为结束。

采取这种方式,也就是每次,在同一秒中:请求过来了10个应用ID,那么该一秒的时间戳,对应的就是有10个应用的key。

-----

可能存在的问题点是什么:

1、一个应用id,有100个容器,同一秒把100个请求,同时发送到了cantor的一个节点上,那么此时第一个请求过来,已经创建了10w的buffer的时候,

此时后续的99个请求,都会从buffer中获取数值,一次返回1000个,1000 * 100 刚好10w个请求用完。如果是这样的话,就是针对一个应用,1秒内最多支持100个并发请求。如果是50w,则一秒内支持500。

一个请求过来后,本地会缓存1000个range,所以,几乎不存在1个服务,1秒内,同时发送100个请求。如果是有100个容器,则可能存在这种情况。

--------------

同时则引出第二个问题,发号器本身也是容器化的,所以请求发号器的流量本身也是被打散的,2个发号器容器的情况下。

1秒内,同时来100个请求,第一个请求给容器A,第二个请求给容器B,两边的秒级时间戳一致,业务ID一致,只需要递增对应的value值即可。

所以100个请求,同时给到两个容器上,则其中50个请求,用A容器内的10W的buffer,另外50个请求,用B容器的50W buffer,所以整体还是趋势递增的,

-----------------

趋势有序是这样的:趋势有序:1、100、101、2、3、4、102、5、103、104、6

----------

关于时间戳不准的问题,可以采用这种方式来解决:

全局ID服务设计 - [技术工程部] 基础设施中心 - Confluence (amh-group.com)

不同实例间时间不同步问题

引入基准时钟。基准时钟是存储在存储中间件里的所有实例中最大的时钟。

  • ID Generator服务每隔一段时间做一次同步时钟的操作。

  • 同步操作首先将自己的机器时钟保存(覆盖)至存储,接着取回所有实例的时钟,最后使用最大的时钟作为基准时钟。

现在也是基于这种方式来做的:

com.wlqq.infra.clients.TimeWatcher

currentAvailableTimestamp() 方法

原创声明:作者:赵志浩、个人博客地址:https://zhaozhihao.com

原创声明:笔名:陈咬金、 博客园地址:https://www.cnblogs.com/zh94/


Comment