Elixirプログラミングに慣れてくると必ず試してみたくなるのがOTP の分散機能だと思います。巷にあるサンプルコードではNode.connnect/1やNode.ping/1等を用いて手動でノードを接続するパターンが多いと思いますが、libclusterのCluster.Strategy.Gossipを使うと簡単にノードの自動接続ができます。
これからElixirを始める方にはこのサイトがおすすめです。
Elixirとコミュニティの雰囲気をゆるく味わいたい方は「先端ピアちゃん」さんの動画が超オススメです。
ゴシッププロトコル
ゴシッププロトコルではランダムに選んだ相手と情報を交換し、自身が持つデータの更新を繰り返す。システムの参加者が不定期的に増減して全体を把握できない状況や、一時的に通信できない場合でも情報を伝搬できる。病気が伝染する様子に似ていることから、エピデミックアルゴリズムとも呼ばれる。--- ウィキペディア
P2P ネットワークで使われるプロトコルらしい。知らんけど。
libcluster
This library provides a mechanism for automatically forming clusters of Erlang nodes, with either static or dynamic node membership. It provides a pluggable "strategy" system, with a variety of strategies provided out of the box.
- Erlang ノードのクラスターを自動的に形成するメカニズムを提供
- 静的または動的なノード組織構造に対応可能
- クラスタリング戦略システムを提供
Cluster.Strategy.Gossip
libclusterでゴシッププロトコルを使いたい時に使うクラスタリング戦略。
いくつか要点を挙げます。
- 同じErlangマジッククッキーを共有している場合にのみ、それらの間で接続が確立される
- ノードのクラスターが動的に形成される
- 初期設定では暗号化されないが、クラスタリング戦略の設定で秘密(
:secret
)を指定することで暗号化が可能
実験
Elixirプロジェクトを準備
任意のディレクトリでmix newコマンドを打ち、実験用のElixirプロジェクトを作ります。
--sup
オプションをつけると監視ツリーを含むOTPアプリの骨格を生成できます。
cd path/to/my/workspaces
mix new hello_bunsan --sup
libclusterの設定
お好みのテキストエディターで作ったプロジェクトを開きます。
cd hello_bunsan
code .
mix.exs
ファイルの依存パッケージリストにlibclusterを追加します。
...
defp deps do
[
+ {:libcluster, "~> 3.3"}
]
end
...
lib/hello_bunsan/application.exs
ファイルでlibclusterの設定を追加します。
defmodule HelloBunsan.Application do
use Application
@impl true
def start(_type, _args) do
+ topologies = [
+ gossip_example: [
+ strategy: Cluster.Strategy.Gossip,
+ secret: "my-secret"
+ ]
+ ]
children = [
+ {Cluster.Supervisor, [topologies, [name: HelloBunsan.ClusterSupervisor]]},
]
opts = [strategy: :one_for_one, name: HelloBunsan.Supervisor]
Supervisor.start_link(children, opts)
end
end
分散ノードを起動
任意のターミナルでクッキーを指定してElixirアプリとともにhoge
ノードを起動します。
-
iex
コマンドで対話Elixirシェルを起動 -
--sname hoge
オプションをつけると、hoge
という名称のノードを起動 -
--cookie genki
オプションをつけると、Erlangマジッククッキーをgenki
に設定 -
-S mix
オプションをつけると、Elixirアプリを起動
cd path/to/hello_bunsan
iex --sname hoge --cookie genki -S mix
別のターミナルを開きノード名だけ変えて同様の操作をします。
cd path/to/hello_bunsan
iex --sname piyo --cookie genki -S mix
これだけで、これらのノードは自動的に接続されます。Node.list/0で接続されているノードを確認できます。
Node.list
本番環境
ゴシップ戦略はノードで遊ぶ時には便利ですが、本番環境では明示的にノード接続した方が無難かもしれません。
Cluster.Strategy.Epmdを使って:host
オプションで接続するメンバーノード(自分のノードを除く)を指定するとそれらだけに接続することができます。
Cluster.Strategy.Kubernetesを使ったやり方はこの記事が参考になるかもしれません。
Cluster.Strategy.DNSPollを使った例もあります。
資料
今回の内容についてはこれらの資料が参考になりました。オススメです。他にもいい情報があればぜひお便りください。