6行代码实现一个 id 发号器

标签: JAVA 技术资料 | 发表时间:2015-07-27 11:15 | 作者:唐福林
出处:http://blog.fulin.org

id 发号器的问题, @一乐 的这篇文章说的很透彻了: http://weibo.com/p/1001603800404851831206 但参考实现就显得有些复杂。最近在雪球工作中正好需要用到发号器,于是用 Lua 在 Redis 上实现了一个最简单的:


-- usage: redis-cli -h 10.10.201.100 -p 10401 EVAL "$(cat getID.lua)" 1 XID:01:02
local arg = KEYS[1]
-- project id must has 2 digits, 01 - 15
local pid = tonumber(string.sub(arg, 5, 6))
-- instance id must has 2 digits, 01 - 15
local iid = tonumber(string.sub(arg, 8, 9))
local idnum = redis.call("INCR", "ID_IDX") % 65536
local sec = redis.call("TIME")[1] - 1420041600
return sec*16777216 + pid*1048576 + iid*65536 + idnum

解释:

  • id 总长度 52bit,为了兼容 js,php,flex 等语言 long 类型最长只能 52 bit
  • 最高 28 bit 为秒级时间戳,因为位数限制,不能从 1970.1.1 开始,-1420041600 表示从 2015.1.1 开始,大约可以使用10年(3106天)
  • 接下来4个bit为 project id,客户端传入,区分业务
  • 再接下来4个bit为 instance id,HA 用的,支持最多16个instance。如果业务只需要“秒级粗略有序”,比如发微博或发评论,则可以多个 instance 同时使用,不需要做任何特殊处理;如果业务需要“因果有序”,比如某个user短期内快速做的多个操作必须有因果顺序(程序化交易,必须先卖再买,几个毫秒内完成),那么就需要做一些特殊处理,要么用 uid 做一致性hash,或者像我们这样偷懒:一段时间内固定使用一个 instance
  • 最低16个bit是 sequence id,每个 instance 支持每秒 65535 个 id。bit数再大,redis 该成为瓶颈了。
  • twitter和微博都是把 instance id 写死到 server 端,这样 server端就变成有状态的了:16个instance,每个 instance 都与其它的配置不一样。在雪球我们不希望 server 端有状态,于是设计成 instance id 由客户端传入,server 端退化成一个普通的 redis cache server (不需要 rdb,不需要 aof,宕机重启即可)
  • 几个注意点:宕机不能自动立即重启,必须间隔1秒以上,避免 sequence id 重复导致 id 重复;迁移时必须先 kill 老的 instance,再启动新的,也是为了避免 sequence id 重复。

id 发号器说简单也确实挺简单。任何一个技术点,只要理解了本质,大约都是这么简单罢。

相关 [代码 id] 推荐:

6行代码实现一个 id 发号器

- - 唐福林-博客雨
id 发号器的问题, @一乐 的这篇文章说的很透彻了: http://weibo.com/p/1001603800404851831206 但参考实现就显得有些复杂. 最近在雪球工作中正好需要用到发号器,于是用 Lua 在 Redis 上实现了一个最简单的:. id 总长度 52bit,为了兼容 js,php,flex 等语言 long 类型最长只能 52 bit.

id Software入驻GitHub,发布旗下所有开源游戏代码

- - ITeye资讯频道
id Software是一家知名电子游戏开发公司,该公司开发的知名游戏包括《德军总部》系列(Wolfenstein)、《毁灭战士》(Doom)系列、《雷神之锤》系列(Quake)等. 知名的FPS大作《半条命》(Half-LIfe)和《反恐精英》(Counter-Strike,简称CS)就是利用Quake的引擎制作的.

产生Id

- - 研发管理 - ITeye博客
// worker编号最大值,决定支持的部署节点数量. // 毫秒内自增位数,每毫秒最大序号支持65535. // worker编号偏移量. // 毫秒基线:2015-01-01 00:00:00. * 从环境变量中获取worker编号,每个部署环境编号不能重复. * 每个部署环境编号不能重复. * @param workerId Worker编号.

id Software发布《狂怒(Rage)》

- ArmadilloCommander - Solidot
id Software发布了容量为21GB的第一人称射击游戏《狂怒(Rage)》. 游戏基于id Tech 5引擎,背景是世界末日后的未来. 目前对它的评价好坏参半,媒体综合评分80左右,玩家评分相似或更低. 在游戏中,玩家将扮演一位小行星Apophis撞击地球后的幸存者. 在灾难发生前,全世界展开合作将包括科学家在内的精英冰冻在地下,以在灾难后重建地球.

小米手机ID简介

- miyizs - Billwang 工业设计
      小米手机是小米公司(全称北京小米科技有限责任公司)专为发烧友级手机控打造的 一款高品质智能手机. 下面我们将对其做一个简单的介绍.       小米手机的外观设计走的是简约内敛路线,直板加圆润的边角让其显得简单清爽. 小米手机配置了,1.5GHz双核处理器、1G RAM、4英寸夏普屏、800万像素摄像头以及大容量电池.

标签?ID?还是CLASS?

- - 前端观察
想谈一下几个基本的HTML问题,都是围绕着应该怎样使用HTML. 多用有语义的标签,少用div和span,避免使用没有class的div和span. 设想一下HTML的世界最初只有div和span这两个标签,其实网页依然可以写得出来. 更多标签的出现,其实是为了替代利用率高但不好书写的 
 和  来的.

设备id那些事

- - 算法之道
随着用户隐私关注度越来越高,搜广推以imei收集用户数据的方式开始被要求整改,首先是客户端不会上传imei,那么追踪用户的唯一标识没有了,那后续该怎么做. 其实除了这个唯一标识符问题,还有一些应用设置项:出现了允许关闭推荐的选项,致命一击. 先了解一下现在移动终端可以收集哪些 id. 不可逆、唯一性、不可篡改、一致性.

Linuxer:制作自己的Linux ID Card吧

- rex - Wow! Ubuntu
Super Boot Manager的作者Alessandro Lanave,又为Linuxer带来了一个web程序,制作Linux ID Card ,Card效果如图. 可以把ID Card做为论坛签名,博客签名,任何你需要的地方. 当然,如果觉得没有自己喜欢的发行版的模板,可以向Alessandro Lanave提交哦,.

两个 Apple ID 是很有必要的

- 闷闲居士 - Page to Page
刚买iPad的时候注册的是中国区的Apple ID,绑定了自己的信用卡. 可当搜索下载Kindle for iPad的时候才觉得,注册一个美国区的Apple ID还是很有必要的,否则很多中国区没有的App无法下载. 大致学习了2篇注册美国区ID的帖子,赶紧动手,可是还是因为疏忽产生了问题,提示我说“我的邮箱地址已经注册了”.

获取id 的一种策略

- - 企业架构 - ITeye博客
从数据库中批量(step个)拿出Id,然后使用,待消耗完后再批量拿出Id. mapLock:判断是否存在锁. mapGenId:保存每次的currNo值. mapMaxId:保存每次currNo+step后的值. 三个ConcurrentHashMap的key都为 key1. 一、由genKey、subKey构建一个锁,获取Id值时先判断是否存在锁,当不存在锁时,先初始化.