最後のブログ私たちは、飼育係のプロフィールについて語った、とのコマンドを使用https://www.cnblogs.com/cxiaocai/p/11597465.htmlを。私達は私達の飼育係のクラスタ構成およびJavaのAPI関連の操作を探してこの時間。
クラスター:
通常の状況下で、我々は、飼育係のミッションコントロールセンターで行う、そうすることはできませんスタンドアロンおよびダウンすることはありません、我々は、スタンドアローン決してダウン、その後、彼を信頼していない、高可用性がなければなりませんクラスタ処理は、当社の高可用性を実現するために行われる必要があります。
クラスタを構成するとき、我々は設定するには、奇数サーバーの使用を最大限に、それは何を意味するのでしょうか?飼育係は、2つがダウンし、それは飼育係通常動作と考えられている稼動されるデフォルトのサーバーの半分は、そのような私たちは今、配備されているように、4つのZooKeeperサーバー、より多くのを認識しますので、設定するには、3,5,7,9のサーバーを使用してみてください、その後、飼育係は、3がダウンして、クラスタ、我々は場合は5台のサーバーがある場合と同じように、ダウン2があるとき、あなたは正常な実行することができます使用不能とみなされますが、使用できないと考えられていましたこの機構は、この背後にあるの選挙を含め、非常に重要です。限られた資金は、ああ、私は飼育係のクラスタで3台のサーバで設定してみましょう。
1.クラスタ構成
ああ何を言わないで抽出する必要があり、我々はそれに直接設定ファイルを見て、最後の時間を述べています。そして、スタンドアロン構成が一貫している、我々が表示さ DATADIR =を/ tmp /飼育係を、つまり、我々のデータ・ストレージ・パス、確立された3つの文書のMYID、内部デジタル入力1〜255
各サーバーを繰り返してはいけない、何の対応を/ tmp /飼育係のディレクトリが存在しない、我々はそれ以外の場合はエラーがMYIDがファイルを見つけることができません開始報告されます、ディレクトリに対応するコンフィギュレーションファイルDATADIRに構築する必要があります覚えて、あなたはそれを起動することができ、再び飼育係は、フォルダを閉じていましたまたは手動で作成するために必要。
そして、各設定ファイル内の設定を追加
server.1 = 172.16.140.106:2888:3888
server.2 = 172.16.140.105:2888:3888
server.3 = 172.16.214.74:2888:3888
server.myid(デジタルMYIDファイル)= IP(MYIDおよび対応するIP):選挙のIP通信:IPのクラスタ間の相互通信。サーズプロファイルは同じです。
私たちは、開始しようとしていました。ここでは、成功したクラスタ構成です。
正常に起動した後、我々は入力された./bin/zkServer.sh状況当社は、当社のサーバーの役割を見ることができます
2.役割:
メインノードのリーダーは、また指導者として知られています。ダウンタイムは新しいマスターノードを選出する場合は、データを書き込むために、選挙によって生成されます。
フォロワー子ノードは、また信者として知られています。データを実装するために読み込まれます。彼はまた、候補ノードのマスターノードであり、投票権を持ちます。
オブザーバー二子ノードは、また、オブザーバーとして知られています。投票権をマスターノードとして選択することはできませんことを除いて、データ、およびfllowerを読み取るため。そして、クラスタが利用できる計算に観測者にカウントされません。それが私たちの原理計算の半分です。
オブザーバの構成:
ただ、例えば、オブザーバーのクラスタ構成に接尾辞を追加します。
server.3 = 127.0.0.1:3889:2889オブザーバー
選挙のメカニズム:
私は、単純な投票メカニズムについてお話しましょう。私たちは今、選挙に5人の1,2,3,4,5フォロワーを持っていると仮定します。
このプロセスは、彼らがリーダーに選出されるために持っているが、選挙プロセスが失敗し、IDの近くに全体的なドラッグに自分のチケットを作り、その後、継続する必要があり、1が得られます、最初のラウンドは、彼らがいると思うことがあり、単純ですああ、ああ半分は2.5である2チケットが、2は今2票を持っており、その半分は十分ではありません見つけ、よく継続する必要があり、2は、2票は3,3が、その後3票を獲得した自分自身を取得します選出された指導者の半分よりも大きいです。
每轮选举结束后都会统一来处理,如果一轮投票就发现server1的zxid较大,那么直接server1会当选leader。
优先检查ZXID。ZXID比较大的服务器优先作为Leader。
如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。
留下一个思考题,5台服务器,如果启动可以指定 4号为leader服务 。
javaAPI相关操作
maven的pom文件内加入
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.5.5</version> </dependency>
首先我们先初始化我们的Zookeeper的连接
connectString ->连接String连接串,包括ip+端口 ,集群模式下用逗号隔开192.168.0.149:2181,192.168.0.150:2181
sessionTimeout ->会话超时时间,类型int,该值不能超过服务端所设置的minSessionTimeout(默认2s)和maxSessionTimeout(默认60s),单位毫秒
watcher -> 会话监听器Watcher,服务端事件将会触该监听
sessionId -> 自定义会话ID long
sessionPasswd ->byte[] 会话密码
canBeReadOnly ->boolean该连接是否为只读的
hostProvider ->HostProvider 服务端地址提供者,指示客户端如何选择某个服务来调用,默认采用StaticHostProvider实现
@Before public void init() throws IOException { String conn = "47.111.109.3:2181"; // 连接字符串 int sessionTimeout = 4000; //连接超时时间 zooKeeper = new ZooKeeper(conn, sessionTimeout, new Watcher() { public void process(WatchedEvent watchedEvent) { } }); }
我们先来看看我们的新增节点,删除节点等操作吧。
查看节点:
我们使用getData方法,添加三个参数,分别是路径,是否监听,和返回值(状态stat)。
/** * 获取数据 * * @throws KeeperException * @throws InterruptedException */ @Test public void getData() throws KeeperException, InterruptedException { byte[] data = zooKeeper.getData("/root", false, null); System.out.println(new String(data)); }
添加监听:
/** * 添加监听,结果在初始化里 * * @throws KeeperException * @throws InterruptedException */ @Test public void getWatchData() throws KeeperException, InterruptedException { byte[] data = zooKeeper.getData("/root", true, null); System.out.println(new String(data)); Thread.sleep(Long.MAX_VALUE); }
这个监听是一次性的,而且结果在我们的初始化的watch里,初始化方法改为
@Before public void init() throws IOException { String conn = "47.111.109.3:2181"; // 连接字符串 int sessionTimeout = 4000; //连接超时时间 zooKeeper = new ZooKeeper(conn, sessionTimeout, new Watcher() { public void process(WatchedEvent watchedEvent) { System.out.println(watchedEvent.getPath()); } }); }
永久监听设置,我们只要将Watcher新建一下就可以了吗...我们来看一下实现
/** * 永久监听 * * @throws KeeperException * @throws InterruptedException */ @Test public void getWatchDataForever() throws KeeperException, InterruptedException { byte[] data = zooKeeper.getData("/root", new Watcher() { public void process(WatchedEvent watchedEvent) { try { zooKeeper.getData(watchedEvent.getPath(),this,null); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(watchedEvent.getPath()); } }, null); System.out.println(new String(data)); Thread.sleep(Long.MAX_VALUE); }
stat:
/** * Stat * * @throws KeeperException * @throws InterruptedException */ @Test public void getDataStat() throws InterruptedException, KeeperException { Stat stat = new Stat(); zooKeeper.getData("/root",false, stat); System.out.println(stat); }
输出结果和我们命令stat的输入其实是完全一致的,只不过一个事16进制,一个事10进制的,可以自己对比一下。
获取子节点 :
/** * 获取子节点 * * @throws KeeperException * @throws InterruptedException */ @Test public void getWatchChildDataForever() throws KeeperException, InterruptedException { List<String> children = zooKeeper.getChildren("/root", false); for (int i = 0; i < children.size(); i++) { System.out.println(children.get(i)); } }
删除节点:
/** * 删除节点 * * @throws KeeperException * @throws InterruptedException */ @Test public void deletePath() throws KeeperException, InterruptedException { zooKeeper.delete("/root/d2", 0); }
创建节点:
/** * 创建节点 * * @throws KeeperException * @throws InterruptedException */ @Test public void createPath() throws KeeperException, InterruptedException { List<ACL> acl = new ArrayList<ACL>(); int perm = ZooDefs.Perms.ADMIN | ZooDefs.Perms.CREATE | ZooDefs.Perms.READ; ACL aclObj = new ACL(perm, new Id("world", "anyone")); acl.add(aclObj); zooKeeper.create("/root/d4", "hello".getBytes(), acl, CreateMode.CONTAINER); }
说到这我们的API和集群操作就差不多说完了。
这次代码不多,就先不上传了,写完下次博客再一起上传。