YARN Service的原理及应用

Service Type

  • AbstratService
  • CompositeService

Service Example

class Agent {
    private final int id;

    public Agent(int id) {
        this.id = id;
    }

    // hashCode and equals method must be implemented  if the object is used in HashMap as key or HashSet.
    @Override
    public int hashCode() {
        return id;
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (obj == null) {
            return false;
        } else if (this.getClass() != obj.getClass()) {
            return false;
        } else {
            Agent other = (Agent) obj;
            return this.id == other.id;
        }
    }

    @Override
    public String toString() {
        return "Agent: " + id;
    }
}

Service class

class AgentManager extends AbstractService {
    private static final Log LOG = LogFactory.getLog(AgentManager.class);
    private int expireInterval;
    private int monitorInterval;
    private Thread checkerThread;
    private boolean stopped = false;
    private Map<Agent, Long> running;

    public AgentManager() {
        super("AgentManager");
    }

    @Override
    protected void serviceInit(Configuration conf) throws Exception {
        super.serviceInit(conf);
        int expireIntvl = conf.getInt("com.baidu.dscheduler.agent.expire.ms",
                1000 * 60 * 10);
        //need some sanity check
        this.expireInterval = expireIntvl;
        this.monitorInterval = expireInterval / 3;
        this.checkerThread = new Thread(new PingChecker());
        this.checkerThread.setName("Ping Checker");
        this.checkerThread.setDaemon(true);
    }

    @Override
    protected void serviceStart() throws Exception {
        super.serviceStart();
        this.checkerThread.start();
    }

    @Override
    protected void serviceStop() throws Exception {
        stopped = true;
        checkerThread.interrupt();
        super.serviceStop();
    }

    private class PingChecker implements Runnable {
        private PingChecker() {
        }

        public void run() {
            while (!AgentManager.this.stopped && !Thread.currentThread().isInterrupted()) {
                synchronized (AgentManager.this) {
                    Iterator<Map.Entry<Agent, Long>> iterator = AgentManager.this.running.entrySet().iterator();
                    long currentTime = System.currentTimeMillis();

                    while (true) {
                        if (!iterator.hasNext()) {
                            break;
                        }

                        Map.Entry<Agent, Long> entry = (Map.Entry) iterator.next();
                        if (currentTime > ((Long) entry.getValue()).longValue() + (long) AgentManager.this.expireInterval) {
                            iterator.remove();
                            //AgentManager.this.expire(entry.getKey());
                            AgentManager.LOG.info("Expired:" + entry.getKey().toString() + " Timed out after " + AgentManager.this.expireInterval / 1000 + " secs");
                        }
                    }
                }
                try {
                    Thread.sleep(AgentManager.this.monitorInterval);
                    continue;
                } catch (InterruptedException e) {
                    AgentManager.this.LOG.info( AgentManager.this.getName() + " thread interrupted");
                }
            }
        }
    }
}

Test case

public class ServiceTest {

    @Test
    public  void basicTest() {
        Configuration conf  = new Configuration(false);
        //conf.addResource();
        AgentManager agentManager = new AgentManager();
        System.out.println("agentManager status after created: " + agentManager.getServiceState());
        agentManager.init(conf);
        System.out.println("agentManager status after instantiated: " + agentManager.getServiceState());
        agentManager.start();
        System.out.println("agentManager status after start: " + agentManager.getServiceState());
        agentManager.stop();
        System.out.println("agentManager status after stop: " + agentManager.getServiceState());
    }

    @Test
    public  void testStateChangeListener() {
        Configuration conf  = new Configuration(false);
        //conf.addResource();
        AgentManager agentManager = new AgentManager();
        agentManager.registerServiceListener(new ServiceStateChangeListener() {
            @Override
            public void stateChanged(Service service) {
                System.out.println("The state of service "
                        + service.getName()
                        + " changed to :"
                        + service.getServiceState());
            }
        });
        System.out.println("agentManager status after created: " + agentManager.getServiceState());
        agentManager.init(conf);
        System.out.println("agentManager status after instantiated: " + agentManager.getServiceState());
        agentManager.start();
        System.out.println("agentManager status after start: " + agentManager.getServiceState());
        agentManager.stop();
        System.out.println("agentManager status after stop: " + agentManager.getServiceState());
    }
}

Composite Service

 this.rmDispatcher = this.setupDispatcher();
 this.addIfService(this.rmDispatcher);
 this.adminService =  this.createAdminService();
 this.addService(this.adminService);

Service State

NOTINITED(0, "NOTINITED"), /** Constructed but not initialized */
INITED(1, "INITED"), /** Initialized but not started or stopped */
STARTED(2, "STARTED"), /** started and not stopped */
STOPPED(3, "STOPPED"); /** stopped. No further state transitions are permitted */
 private static final boolean[][] statemap =
    {
      //                uninited inited started stopped
      /* uninited  */    {false, true,  false,  true},
      /* inited    */    {false, true,  true,   true},
      /* started   */    {false, false, true,   true},
      /* stopped   */    {false, false, false,  true},
    };

Why Use Service

  1. Make sure state change correctly, including concurrent call service.{init, start, stop} method.

@Override
  public void init(Configuration conf) {
    if (conf == null) {
      throw new ServiceStateException("Cannot initialize service "
                                      + getName() + ": null configuration");
    }
    if (isInState(STATE.INITED)) {
      return;
    }
    synchronized (stateChangeLock) {
      if (enterState(STATE.INITED) != STATE.INITED) {
        setConfig(conf);
        try {
          serviceInit(config);
          if (isInState(STATE.INITED)) {
            //if the service ended up here during init,
            //notify the listeners
            notifyListeners();
          }
        } catch (Exception e) {
          noteFailure(e);
          ServiceOperations.stopQuietly(LOG, this);
          throw ServiceStateException.convert(e);
        }
      }
    }
  }

Test case:

@Test (expected = org.apache.hadoop.service.ServiceStateException.class)
    public  void testRestart() {
        Configuration conf  = new Configuration(false);
        //conf.addResource();
        AgentManager agentManager = new AgentManager();

        System.out.println("agentManager status after created: " + agentManager.getServiceState());
        agentManager.init(conf);
        System.out.println("agentManager status after instantiated: " + agentManager.getServiceState());
        agentManager.start();
        System.out.println("agentManager status after start: " + agentManager.getServiceState());
        agentManager.stop();
        System.out.println("agentManager status after stop: " + agentManager.getServiceState());
        agentManager.start();
    }
2. Eliminate the need to copy common code.
  • common code will be in different services .
  • Composite service needs all the inner service start or stop.
   public void start() {
       service1.start();
       service2.start();
       service3.start();
       ...
   }

Use Context to get various service

If we have many services, how can we get the one needed.
The answer is use a context object and pass it every where.

Take RMContext as an example:
RMContext has only one instance in the system.

    ContainerAllocationExpirer getContainerAllocationExpirer();

    DelegationTokenRenewer getDelegationTokenRenewer();

    AMRMTokenSecretManager getAMRMTokenSecretManager();

    RMContainerTokenSecretManager getContainerTokenSecretManager();

    NMTokenSecretManagerInRM getNMTokenSecretManager();

    ResourceScheduler getScheduler();

    NodesListManager getNodesListManager();

    ClientToAMTokenSecretManagerInRM getClientToAMTokenSecretManager();

    AdminService getRMAdminService();

    ClientRMService getClientRMService();

    ApplicationMasterService getApplicationMasterService();

    ResourceTrackerService getResourceTrackerService();

    void setClientRMService(ClientRMService var1);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值