设为首页 收藏本站
查看: 1226|回复: 0

[经验分享] zookeeper全局唯一id生成

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2019-1-7 14:19:07 | 显示全部楼层 |阅读模式
一背景
传统生成id方式可以靠数据库的自增来实现,但是在分布式环境下不太适应。依赖数据库容易造成单点。
为什么不用UUID的,网上看别人介绍的时候,从两个方面去分析:
1 大并发的情况下,UUID会出现重复。
2.UUID是随即的,含义不明。从业务角度去考虑,如果用作订单,用户查询订单在数据分片的情况下很可能分散在多个库,查询困难。
全局唯一id的要求比较高:
不能有单点故障。
性能好,毫秒级返回。
能顺序便于DB存储及划分。
二 使用zookeeper生成全局唯一id.
2.1 利用Zookeeper的znode数据版本生成序列号


客户端采用:zkClient (https://github.com/adyliu/zkclient


  
      
        com.github.adyliu  
        zkclient  
        2.1.1  
      java 代码实现

public class ZKSeqTest {  
    //提前创建好存储Seq的"/createSeq"结点 CreateMode.PERSISTENT  
    public static final String SEQ_ZNODE = "/seq";  
        //通过znode数据版本实现分布式seq生成  
        public static class Task1 implements Runnable {   
            private final String taskName;         
            public Task1(String taskName) {  
                this.taskName = taskName;  
            }         
            @Override  
            public void run() {  
                ZkClient zkClient = new ZkClient("192.168.190.36:2181", 3000, 50000);  
                Stat  stat =zkClient.writeData(SEQ_ZNODE, new byte[0], -1);  
                int versionAsSeq = stat.getVersion();  
                System.out.println(taskName + " obtain seq=" +versionAsSeq );  
                zkClient.close();  
            }  
        }  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
        //main  
        final ExecutorService service = Executors.newFixedThreadPool(20);  
        for (int i = 0; i < 10; i++) {  
            service.execute(new Task1("[Concurrent-" + i + "]"));  
        }  
    }  
}  

public class ZKLock {  
      
    //提前创建好锁对象的结点"/lock" CreateMode.PERSISTENT  
    public static final String LOCK_ZNODE = "/lock";  
    //分布式锁实现分布式seq生成  
    public static class Task2 implements Runnable, IZkChildListener {  
        private final String taskName;  
        private final ZkClient zkClient;  
        private final String lockPrefix = "/loc";  
        private final String selfZnode;  
        public Task2(String taskName) {  
            this.taskName = taskName;  
            zkClient = new ZkClient("192.168.190.36:2181", 30000, 50000);  
            selfZnode = zkClient.createEphemeralSequential(LOCK_ZNODE + lockPrefix, new byte[0]);  
        }  
        @Override  
        public void run() {  
              createSeq();  
        }      
        private void createSeq() {  
            Stat stat = new Stat();  
            byte[] oldData = zkClient.readData(LOCK_ZNODE, stat);  
            byte[] newData = update(oldData);  
            zkClient.writeData(LOCK_ZNODE, newData);  
            System.out.println(taskName + selfZnode + " obtain seq=" + new String(newData));  
        }  
        private byte[] update(byte[] currentData) {  
            String s = new String(currentData);  
            int d = Integer.parseInt(s);  
            d = d + 1;  
            s = String.valueOf(d);  
            return s.getBytes();  
        }  
        @Override  
        public void handleChildChange(String parentPath,  
                List currentChildren) throws Exception {  
            // TODO Auto-generated method stub  
        }      
    }  
  
    public static void main(String[] args) {  
                final ExecutorService service = Executors.newFixedThreadPool(20);  
                for (int i = 0; i < 10; i++) {  
                    service.execute(new Task2("[Concurrent-" + i + "]"));  
                }  
                service.shutdown();  
    }  
}  

  
  利用带序列号的znode实现

  [java] view plain copy



  

  后端看日志就是运行期间有临时节点,会话结束后自动删除。
三 开源方案
网上还有开源的更好的开源实现方案值得借鉴。


3.1Flikr
  基于int/bigint的自增
  优:开发成本低
  劣:如果需要高性能,需要专门一套MySQL集群只用于生成自增ID。可用性也不强
  

3.2 Snowflake
twitter利用zookeeper实现了一个全局ID生成的服务snowflake,https://github.com/twitter/snowflake,可以生成全局唯一的64bit ID。
生成的ID的构成:
时间--用前面41 bit来表示时间,精确到毫秒,可以表示69年的数据  
机器ID--用10 bit来表示,也就是说可以部署1024台机器  
序列数--用12 bit来表示,意味着每台机器,每毫秒最多可以生成4096个ID

  优:可用性强,速度快,id保存信息多。
  劣:需要引入zookeeper 和独立的snowflake专用服务器
  

3.3instagram
instagram参考了flickr的方案,再结合twitter的经验,利用Postgres数据库的特性,实现了一个更简单可靠的ID生成服务。
copy


  •   使用41 bit来存放时间,精确到毫秒,可以使用41年。  
  •   使用13 bit来存放逻辑分片ID。  
  •   使用10 bit来存放自增长ID,意味着每台机器,每毫秒最多可以生成1024个ID  


优: 开发成本低
劣: 基于postgreSQL的存储过程,通用性差
  还有基于redis的全局id生成方案:http://blog.csdn.net/hengyunabc/article/details/44244951


参考:
http://blog.csdn.net/bohu83/article/details/51457961
  





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-660410-1-1.html 上篇帖子: zookeeper 数据迁移及恢复操作 下篇帖子: Zookeeper详解(八):Zookeeper数据存储
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表