18
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirAdvent Calendar 2022

Day 2

Elixir Node.ping/1で気軽に分散システムを楽しむ

Last updated at Posted at 2022-11-26

ノード間の通信Node.ping/1が便利だなと思ったのでメモ。

ただノードの接続を確認するだけではなく、未接続の場合には接続を確立してくれます。Livebookでも使用されています。

この記事も参考になりました。

Erlangの分散機能について

ポイントがいくつかあります。

ノードの名前

分散ノードを起動する方法は2つあります。

  • --snameオプション
    • 短い名前
    • 同一のホスト上にクラスターを設けるときに便利
  • --nameオプション
    • ノードの場所(例、IPアドレス)を含む完全修飾名

Erlangクッキー

  • クラスターを識別するためのもの
  • セキュリティ用ではない
  • ノードを接続するためには同じErlangクッキーを共有する必要

epmd (Erlang Port Mapper Daemon)

  • 登録されたノードのポートを追跡するプロセス
  • 分散ノードでBEAMを起動するときに起動
  • デフォルトではポート4369で動作
  • ノードが他のノードへの接続が成功した時点でランダムなポートが割り当てられるらしい

epmd -namesコマンドですべてのノードのポートが確認できます。

$ epmd -names

epmd: up and running on port 4369 with data:
name piyo at port 63110
name fuga at port 63108
name hoge at port 63106

メッシュネットワーク

  • 新しいノードがクラスタに加わると、メッシュネットワークが形成されます。
  • クラスタの全てのノードは他の全てのノードに接続されます。

論よりRun
:speaking_head: < :computer:

同一PC上でクラスタを作ってみる

シェルを複数起動

複数のシェルを起動します。

シェルを複数起動.png

IExセッションからノードを起動

hogefugapiyoの三つのノードをそれぞれ別々のIExセッションで起動します。

--snameオプションでノード名を指定します。

iex --sname hoge@localhost
iex --sname fuga@localhost
iex --sname piyo@localhost

IExセッションからノードを起動.png

Erlangクッキーを設定

ノードが接続する際に必要になります。あるクラスターに属するすべてのノードが同じクッキーを共有することになります。

Node.set_cookie(:mycookie)

Erlangクッキーを設定

ちなみにiexコマンドの--cookieオプションまたは--erlオプションを用いることにより、Erlangランタイムシステム起動時にクッキーを設定することも可能です。

iex --sname hoge --cookie mycookie
iex --sname hoge --erl "-setcookie mycookie"

Node.ping/1でノードを接続

hogeノードのIExから他のノードに接続します。

:pong = Node.ping(:"fuga@localhost")
:pong = Node.ping(:"piyo@localhost")

Node.ping/1は、成功した場合は :pong、失敗した場合は:pangを返します。

Node.list/0で現在接続されているノードのリストが確認できます。この時点で全てのノードが他の全てのノードに接続されているはずです。

Node.ping/1でノードを接続

別ノードでコードを実行

fugaノードのIExにToukonモジュールを貼り付けて定義します。

defmodule Toukon do
  def aisatsu, do: "元氣ですかーーーーッ!"
end

piyoノードのIExからfugaノードで定義されたToukonモジュールを実行します。

Node.spawn(
  :"fuga@localhost",
  fn -> Toukon.aisatsu() |> IO.puts() end
)

別ノードでコードを実行

Nodeモジュール

Nodeモジュールの関数はすべて、Erlangの実装に委譲されています。分散ノードに関連する関数を便宜上まとめたものと言えます。

Node.ping/1が便利なのでいまいちNode.connect/1の使い道がわかりません。LivebookではNode.ping/1でノードを接続しているので、深く考えずNode.ping/1でいいんじゃないかなと思ってます。

ご参考までに

18
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?