Consul lock を動かしてみる
お待ちかね Consul 0.5.0 が出ました -> https://hashicorp.com/blog/consul-0-5.html
今回のリリースでいろんな機能が追加されましたが lock が気になったのでとりあえず動かしてみます。
環境準備
Consulと使いそうなツールを幾つか含んだDockerコンテナで検証してみます。
FROM ubuntu:trusty MAINTAINER foostan [email protected] RUN apt-get update && apt-get install -y wget curl unzip telnet dnsutils RUN wget http://stedolan.github.io/jq/download/linux64/jq RUN chmod +x jq RUN mv jq /usr/bin ## consul RUN wget -P /tmp https://dl.bintray.com/mitchellh/consul/0.5.0_linux_amd64.zip RUN unzip /tmp/0.5.0_linux_amd64.zip -d /tmp RUN mv /tmp/consul /usr/bin
複数のターミナルでコンテナ起動
とりあえずサーバ1台と
$ docker run -it foostan/consul /bin/bash root@a95dafd4c471:/# consul agent -server -bootstrap -data-dir /tmp &
クライアント3台起動します
$ docker run -it foostan/consul /bin/bash root@730cc2b3a957:/# consul agent -join 172.17.0.34 -data-dir /tmp &
$ docker run -it foostan/consul /bin/bash root@2804f185fe4a:/# consul agent -join 172.17.0.34 -data-dir /tmp &
$ docker run -it foostan/consul /bin/bash root@14e9577a1104:/# consul agent -join 172.17.0.34 -data-dir /tmp &
メンバー確認
root@a95dafd4c471:/# consul members Node Address Status Type Build Protocol a95dafd4c471 172.17.0.34:8301 alive server 0.5.0 2 730cc2b3a957 172.17.0.32:8301 alive client 0.5.0 2 2804f185fe4a 172.17.0.33:8301 alive client 0.5.0 2 14e9577a1104 172.17.0.31:8301 alive client 0.5.0 2
lock コマンドを使ってみる
ドキュメントが相変わらずしっかりしてるのありがたいですね -> https://consul.io/docs/commands/lock.html
1つのコンテナで consul lock 実行してみます。
-verbose
つけると詳細なログが出るので挙動が確認しやすいです。
root@2804f185fe4a:/# consul lock -verbose service/foo/lock "while true; do date; sleep 1; done" Setting up lock at path: service/foo/lock/.lock Attempting lock acquisition Starting handler 'while true; do date; sleep 1; done' Fri Feb 20 16:41:13 UTC 2015 Fri Feb 20 16:41:14 UTC 2015 Fri Feb 20 16:41:15 UTC 2015 Fri Feb 20 16:41:16 UTC 2015
1秒単位で date
の結果が流れ始めます。
この状態で別のノードから同じコマンドを実行してみます。
root@14e9577a1104:/# consul lock -verbose service/foo/lock "while true; do date; sleep 1; done"Setting up lock at path: service/foo/lock/.lock Attempting lock acquisition
こちらはコマンドが実行されません。 この状態で、先ほど実行していた方を停止してみます。
Fri Feb 20 16:44:42 UTC 2015 ^CShutdown triggered, killing child Terminating child pid 2177 Error running handler: signal: terminated signal: terminated Child terminated Cleanup aborted, lock in use
すると、実行されずに待機していたほうが実行され始めました。
root@14e9577a1104:/# consul lock -verbose service/foo/lock "while true; do date; sleep 1; done" Setting up lock at path: service/foo/lock/.lock Attempting lock acquisition Starting handler 'while true; do date; sleep 1; done' Fri Feb 20 16:44:42 UTC 2015 Fri Feb 20 16:44:43 UTC 2015 Fri Feb 20 16:44:44 UTC 2015
文字だけだと分かりにくいので動画とりました。
こちらの動画では -n 2
をオプションで付けているため最大2台実行され、それ以降はコマンドを実行してもロックされます。
また途中でコマンドを停止するとロックされていたクライアントから実行するべきノードが選出されて実行されます。
簡単な解説
ロックする仕組み(実行を開始しても待機していた部分)に関しては 0.3.0 で導入されたセッションを利用しています -> http://www.consul.io/docs/internals/sessions.html
また、実行中のクライアントが停止したときに、残りの別のクライアントで再開する部分は、今回のバージョンで新しく追加された client-side Leader Election によって実現されています。
今までLeader Election(リーダー選出)はサーバ間でのみ行っており、クライアントからの要求を受けるサーバを選出するためのものでした。 またそのアルゴリズムとしてRaft(https://consul.io/docs/internals/consensus.html)が利用されていました。
で、今回追加されたのは文字通りクライアント側のリーダー選出の仕組みです。 上記動画では4台のクライアント(厳密には1台はサーバ)のうち2台がコマンドを実行し、2台は待機している状態でした。そして、1台実行を停止して2台のうち1台で実行が開始されましたが、このときにRaftによるリーダ選出が行われるわけです。 利用する側はとくに何も考えずにクライアントが選出されるのでありがたいですね。
Raftがどのようなアルゴリズムになっているかは今後論文を読んで理解を深めたいところです。
Contributeした話
consul lock は関係ないですが、Consulに投げた幾つかのPRをマージしてもらって今回のバージョンで無事リリースされました(OSSへの初PR初マージ)。
注目度の高いプロダクトにContributeすることができて単純に嬉しかったのとOSS活動へのモチベーションが上がりました。
今後も普段利用しているOSSや注目しているOSSへの感謝の気持ちを忘れずに、可能であればContributeを続けて行きたいと思います。
ちなみにマージされたPRの内容は以下の2件です。
Multiple DNS recursors
DNS Interface には recursor
という設定項目があって、これはConsul外部の問い合わせがあった時にフォワードする先を指定するもので、
{ "recursor": "8.8.8.8" }
などと設定しておくと、Consulで名前解決出来ないものを "8.8.8.8" に問い合わせてその結果を返してくれます。 で、今回送ったPRではこれを複数対応するもので
{ "recursors": ["8.8.8.8", "8.8.4.4"] }
という具合に指定できます。 運用しようと思うと地味に必要になってくるかなということで知っておくと案外助かるかもしれません。