技术关键点--构建全局严格递增ID

2019-08-16  本文已影响0人  旺叔叔

当前的消息推送系统设计中,每一个入库的消息必须要有一个全局严格递增ID。
一开始想到的自然是Long
9223372036854775807的最大值,够用到天荒地老,海枯石烂。
然后开始思考落地细节。
并发获取倒是没什么问题,LongAdder天助我也。
问题来了。
这样的ID为了严格递增,down机或重启后。
要保证能够产生比之前所有值都大的值继续生成。
1.这不久持久化吗,上一个最大ID不就在系统里?
不这么简单,后期的架构中,系统会针对推送主体产生茫茫多的推送队列。
每个队列在关系型数据库里就是一张表,在nosql数据库里就是一个对象。
每次重启,在这几十上百万甚至上千万张表或者对象中搜索一个最大数值。
不科学。
2.用时间,timestamp不是正好是Long?
重启后获得新的时间一定更大。
不太好,这样就限制了每秒最多1000个ID产生,并发瓶颈太低。
timestamp左移,剩下位用来递增?
嗯....左移后,大小可就不确定了。
况且有个万分之一的情况,服务器被时间回退。
3.傻乎乎地试了试Long后补数用decimal存,结果做索引效率和Long比起来,那是天差地别。
1000W条数据,分页查递增的1000条,一个0.037秒,一个23秒。
4.那就单独在配置表上留一个字段记录吧。
那么这个字段的更新频率也成为了性能瓶颈,一秒钟10W次写mysql,哪怕一个字段,也会蹦。
5.那就定时写?
每隔10秒,写入一次当前值,然后继续递增。
貌似也不妥,写完后递增一段时间后,突然挂了可咋整,这期间的递增数不久丢了?

一筹莫展之际。
等等,谁说定时写要写当前值!!!!!
比如当前值是0,提前预估个100W的提升,直接把100W写进库里,一定时间或者到达100W后再次写库,这样下次拿到的虽然不是连续递增,但是永远严格单调!
挂一次最多可能浪费100W?对Long来说简直毛毛毛毛毛毛毛毛毛雨。
解决!

上一篇下一篇

猜你喜欢

热点阅读