code: static int run(List<InetSocketAddress> namenodes,
        Configuration conf) throws IOException, InterruptedException {
      final long sleepms = 1000L * 2 * conf.getLong("dfs.heartbeat.interval", 3);
      LOG.info("namenodes = " + namenodes);
      Formatter formatter = new Formatter(System.out);
      System.out.println("Time Stamp               Iteration#  Bytes Already Moved  Bytes Left To Move  Bytes Being Moved  Iterations Left  Seconds Left");
  
      final List<Balancer> balancers
          = new ArrayList<Balancer>(namenodes.size());
      boolean failNN = false;
      try {
        for(InetSocketAddress isa : namenodes) {
          try{
            Balancer b = Balancer.getBalancerInstance(conf);
            b.init(isa);
            balancers.add(b);
          } catch (IOException e) {
            e.printStackTrace();
            LOG.error("Cannot connect to namenode: " + isa);
            failNN = true;
          }
        }
  
        boolean done = false;
        for(int iterations = 0; !done && balancers.size() > 0; iterations++) {
          done = true;
          Collections.shuffle(balancers);
          Iterator<Balancer> iter = balancers.iterator();
          while (iter.hasNext()) {
            Balancer b = iter.next();
            b.resetData();
            final int r = b.run(iterations, formatter);
            if (r == IN_PROGRESS) {
              done = false;
            } else if (r != SUCCESS) {
              //Remove this balancer
              b.close();
              LOG.info("Namenode " + b.namenodeAddress + " balancing exits...");
              iter.remove();
              continue;
            }
          }
  
          if (!done) {
            Thread.sleep(sleepms);
          }
        }
      } finally {
        for(Balancer b : balancers) {
          b.close();
        }
      }
      if (failNN) {
        LOG.warn("Could not initialize all balancers");
        return NOT_ALL_BALANCED;
      }
      return SUCCESS;
    }
docs: Balance all namenodes.
  For each iteration,
  for each namenode,
  execute a {@link Balancer} to work through all datanodes once.