Zeus-Master-选举

2016-07-07  本文已影响193人  PunyGod

Zeus负责调度的节点称之为 Master, Master节点是单点运作的,为了保持系统的高可用性,每台worker都可以去竞争当Master,但在系统之中同时只会存在一个Master。
Zeus和Zeus2中的使用的分布式锁选举主节点的方案是使用数据库的方案,
每台worker内设置一个定时线程,每隔一分钟查询一次数据库的zeus_lock表:

如果作为worker角色,自己之前连接的主节点并不是数据库中的,则重新连接到新的master上并汇报自己的心跳信息;

部分代码如下:

/**
 * 定时扫描任务
 * 每隔一分钟扫描一次zeus_lock表
 * 判断ScheduleServer是否正常运行
 * @author zhoufang
 *
 */

private void update(){
   DistributeLock lock=(DistributeLock) getHibernateTemplate().execute(new HibernateCallback() {
      @Override
      public Object doInHibernate(Session session) throws HibernateException,
            SQLException {
         Query query=session.createQuery("from com.taobao.zeus.store.mysql.persistence.DistributeLock where subgroup=? order by id desc");
         query.setParameter(0, Environment.getScheduleGroup());
         query.setMaxResults(1);
         DistributeLock lock= (DistributeLock) query.uniqueResult();
         if(lock==null){
            lock=new DistributeLock();
            lock.setHost(host);
            lock.setServerUpdate(new Date());
            lock.setSubgroup(Environment.getScheduleGroup());
            session.save(lock);
            lock=(DistributeLock) query.uniqueResult();
         }
         return lock;
      }
   });
      if(host.equals(lock.getHost())){
      log.info("hold the locker and update time");
      lock.setServerUpdate(new Date());
      getHibernateTemplate().update(lock);
            zeusSchedule.startup(port);
   }else{//其他服务器抢占了锁
      log.info("not my locker");
      //如果最近更新时间在2分钟以上,则认为抢占的Master服务器已经失去连接,本服务器主动进行抢占
      if(System.currentTimeMillis()-lock.getServerUpdate().getTime()>1000*60*2L){
         log.error("rob the locker and update");
         lock.setHost(host);
         lock.setServerUpdate(new Date());
         lock.setSubgroup(Environment.getScheduleGroup());
         getHibernateTemplate().update(lock);
         zeusSchedule.startup(port);
      }else{//如果Master服务器没有问题,本服务器停止server角色
         zeusSchedule.shutdown();
      }
         }
      try {
      worker.connect(lock.getHost(),port);
   } catch (Exception e) {
      ScheduleInfoLog.error("start up worker fail", e);
   }
}

使用轮询的方式来选主,不可避免的会导致没办法在第一时间监测到主节点的不可用,会用一定的延迟性。目前主流的服务发现方案可以使用zk来实现主节点选择的策略;

上一篇 下一篇

猜你喜欢

热点阅读