zoukankan      html  css  js  c++  java
  • twitter snowflake 全局唯一ID算法

    研发页游时,经常需要合服,每次合服,最浪费时间的就是重复ID的合并,后来,渐渐的有人用了各个大区集中到ID分配节点上获取一定量的ID,来分配。对于ID分配节点来说,有一定的单点风险。对于使用这些预约的ID,每次关服,开服都需要重新存储,加载剩余的可用ID个数,位置等等,还挺麻烦。
    最近做不分区的游戏,发现了Twitter的分布式唯一ID生成算法snowflake,发现不光在不分区的分布式游戏节点上用合适,也可以用在分区分服的传统页游、手游上。
     
    1,符号位不用,JAVA类语言不好处理,跟其他平台对接时会带来麻烦
    2,范围为39bit,当前时间戳-开服时间戳(比如20150916,写死在代码里,不可以配置)的差值,1<<39 -1 = 17.4年。可用17年的ID,我觉得38bit ,可以实现8.7年 的存储,足够一个游戏的生命周期了。
    3,10bit,服务器ID,最大值1023,可以支持开到1000多个服。(游戏太火,1000多不够?这么火的游戏,正好上面时间戳差值可以节省1个bit,够开2047个服了。还不够?那下面两个想着省点呗)
    4,4bit,每个服的节点(或线程)ID,最大值15。一般,需要开这么线程才能处理完的业务量时,都会再开新服了,15个用不完的。还不够的话,下面的自增序列肯定用不完,可以拿个过来。
    5,10bit,自增序列最大值为 1023,每毫秒内可产生1023个不重复ID供使用,每秒100W个不重复ID。角色ID自增,以及道具、建筑ID自增,建议每个业务都用自己的一个ID生成器,不要共用同一个。每个游戏进程按照QPS为1W来算,一个请求注册1个用户的话,实际用到的每秒1W即可。若用于道具ID生成,每个查询会生成10个来算,每秒可生成10W即可。也就是说 自增序列占7bit即可,其余3个可分配到其他存储位置上。
     
    这么分配ID的话,以后合服只需要直接合并导入数据,不用担心ID重复的问题了。
     
    Golang语言版的gosnowflake : https://github.com/Terry-Mao/gosnowflake/blob/master/id.go
    PHP版的IDWork: https://github.com/zhouyuan24/IDWork/blob/master/idwork.php
    JAVA版的 idcenter:https://github.com/adyliu/idcenter/blob/master/src/main/java/com/sohu/idcenter/IdWorker.java
     

     

  • 相关阅读:
    [PHP] class_exists类不存在时会调用__autoload函数
    [Redis] Redis的消息机制- 发布订阅
    [发电] 现在正式入驻爱发电平台
    [MySQL] PHP IP登录限制的实现
    [Redis] 哈希表的Rehash机制
    [Redis] redis的hash类型底层结构哈希表
    [Linux] ls命令的几个常用参数实现按时间/文件大小排序
    [Go] 在gin框架gorm下查询一对多的数据
    [Redis] list底层的数据结构
    [GO]go redis实现滑动窗口限流-redis版
  • 原文地址:https://www.cnblogs.com/Jeely/p/12386573.html
Copyright © 2011-2022 走看看