11

Zookeeper でリーダーシップの選挙を行うために、Apache Curator ライブラリを使用しています。私は自分のアプリケーション コードをさまざまなマシンにデプロイしており、コードを 1 台のマシンからのみ実行する必要があるため、飼育係でリーダーシップの選挙を行って、自分がリーダーであるかどうかを確認してからこのコードを実行できるようにしています。

以下は、LeaderElectionExecutorアプリケーションごとに 1 つの Curator インスタンスがあることを確認するクラスです。

public class LeaderElectionExecutor {

    private ZookeeperClient zookClient;

    private static final String LEADER_NODE = "/testleader";

    private static class Holder {
        static final LeaderElectionExecutor INSTANCE = new LeaderElectionExecutor();
    }

    public static LeaderElectionExecutor getInstance() {
        return Holder.INSTANCE;
    }

    private LeaderElectionExecutor() {
        try {
            String hostname = Utils.getHostName();

            String nodes = "host1:2181,host2:2181;

            zookClient = new ZookeeperClient(nodes, LEADER_NODE, hostname);
            zookClient.start();

            // added sleep specifically for the leader to get selected
            // since I cannot call isLeader method immediately after starting the latch
            TimeUnit.MINUTES.sleep(1);
        } catch (Exception ex) {
            // logging error
            System.exit(1);
        }
    }

    public ZookeeperClient getZookClient() {
        return zookClient;
    }
}

そして以下は私のZookeeperClientコードです -

// can this class be improved in any ways?
public class ZookeeperClient {

    private CuratorFramework client;
    private String latchPath;
    private String id;
    private LeaderLatch leaderLatch;

    public ZookeeperClient(String connString, String latchPath, String id) {
        client = CuratorFrameworkFactory.newClient(connString, new ExponentialBackoffRetry(1000, Integer.MAX_VALUE));
        this.id = id;
        this.latchPath = latchPath;
    }

    public void start() throws Exception {
        client.start();
        leaderLatch = new LeaderLatch(client, latchPath, id);
        leaderLatch.start();
    }

    public boolean isLeader() {
        return leaderLatch.hasLeadership();
    }

    public Participant currentLeader() throws Exception {
        return leaderLatch.getLeader();
    }

    public void close() throws IOException {
        leaderLatch.close();
        client.close();
    }

    public CuratorFramework getClient() {
        return client;
    }

    public String getLatchPath() {
        return latchPath;
    }

    public String getId() {
        return id;
    }

    public LeaderLatch getLeaderLatch() {
        return leaderLatch;
    }
}

今、私のアプリケーションでは、次のようなコードを使用しています -

public void method01() {
    ZookeeperClient zookClient = LeaderElectionExecutor.getInstance().getZookClient();
    if (zookClient.isLeader()) {
        // do something
    }
}

public void method02() {
    ZookeeperClient zookClient = LeaderElectionExecutor.getInstance().getZookClient();
    if (zookClient.isLeader()) {
        // do something
    }
}

問題文:-

Curator ライブラリ -isLeader()ラッチを開始した直後の呼び出しは機能しません。リーダーが選ばれるまでには時間がかかります。この理由だけで、LeaderElectionExecutorコードに 1 分間のスリープを追加しましたが、これは正常に動作しますが、これは正しい方法ではないと思います。

これを行うより良い方法はありますか?これを念頭に置いて、私がリーダーであるかどうかを確認してから、このコードを実行する方法が必要です。1 つのメソッドですべてを行うことはできないためisLeader、さまざまなクラスおよびメソッドからメソッドを呼び出して、自分がリーダーであるかどうかを確認し、このコードのみを実行する必要があります。

Zookeeper 3.4.5 と Curator 1.7.1 バージョンを使用しています。

4

4 に答える 4

0
leaderLatch = new LeaderLatch(curatorClient, zkPath, String.valueOf(new Random().nextInt()));
leaderLatch.start();
Participant participant;
while(true) {
  participant = leaderLatch.getLeader();
  // Leader election happens asynchronously after calling start, this is a hack to wait until election happens
  if (!(participant.getId().isEmpty() || participant.getId().equalsIgnoreCase(""))) {
    break;
  }
}
if(leaderLatch.hasLeadership()) {
...
}

getLeader は、リーダーを選出するまで、ID "" を持つダミーの参加者を返すことに注意してください。

于 2015-08-31T22:25:28.220 に答える
0

私はこれまで飼育係や学芸員と一緒に仕事をしたことがないので、私の答えは割り引いて考えてください。

フラグを設定します。

ブール isLeaderSelected = false;

ラッチの開始時に、フラグを false に設定します。リーダーが選択されたら、フラグを true に設定します。

isLeader() 関数では:

isLeader(){
while(!isLeaderSelected){} //waits until leader is selected

//do the rest of the function
}

これも比較的ハックな回避策ですが、isLeader メソッドをできるだけ早く実行できるようにする必要があります。それらが異なるクラスにある場合、getter は isLeaderSelected を提供できる必要があります。

于 2015-02-08T09:53:03.403 に答える