この記事は、Elixir Advent Calendar 2024 シリーズ7 の20日目です
昨日は、@hisaway さんで 「パイプラインの流れでそのまま変数を定義したい」 でした
piacere です、ご覧いただいてありがとございます
前回 は、クラウドを使わずにリアルタイム性を担保するElixir分散コンピューティングの「クラスタリング」に入門しました
今回は、引き続き libcluster を使って、Elixir分散コンピューティングにおけるクラスターの「オートスケール/ダウン後自動復帰」を実現していきます
本シリーズの全体像は、下記になります
There are 13 Elixir Advent Calendar, making for a hot winter!
Over the past 7 years, Elixir has consistently been a top-ranking language in the programming category of the Advent Calendar, claiming the #1 spot last year. This year, too, Elixir is sure to stay at the top.
We’re feeling the excitement again this year… Please support or subscribe!
https://qiita.com/advent-calendar/2024/elixir
https://qiita.com/advent-calendar/2024/ranking/feedbacks/categories/programming_languages
EPMD戦略ではオートスケール/ダウン後自動復帰できない
前回構築したElixirクラスター で、3台目のマシン上でiexを起動する前に、下記のように3台目のノードを追加し、1台目のマシンのiexを再起動します
defmodule A.Application do
# See https://hexdocs.pm/elixir/Application.html
…
def start(_type, _args) do
topologies = [
clusters1: [
strategy: Cluster.Strategy.Epmd,
+ config: [hosts: [:"node1@172.24.176.1", :"node2@172.24.176.2", :"node3@172.24.176.3"]]
…
この時点では、3台目のマシンでiexが起動していないので、クラスター内にも2台しかリストされません
iex> Node.list
[:"node2@172.24.176.2"]
ここで、3台目のマシンでiexを起動します
iex --name node3@172.24.176.3 --cookie edge-servers -S mix
しかし、自動的にはクラスターに参加してくれません
iex> Node.list
[:"node2@172.24.176.2"]
3台目のマシンをクラスターに参加させるには、libclusterの動く1台目のマシンのiexを再起動するしかありません
iex --name node1@172.24.176.1 --cookie edge-servers -S mix
iex> Node.list
[:"node2@172.24.176.2", :"node3@172.24.176.3"]
これでは、オートスケールになっていません
また、ダウン後自動復帰についても、同様に叶いそうにありません
Elixirクラスターのオートスケール
オートスケールを実現するために、EPMD戦略から、今回はオートスケール可能な戦略の1つ、「Gossipプロトコル」戦略に切り替えます
Gossipプロトコルは、Elixirノードが追加されたとき、自動的にクラスターにノードを追加してくれるので、オートスケールを実現できます
なお、これを行う前に、1/3台目のマシンのiexを、Ctrl+cを2回押すことでダウンさせてください(で無いと、3台目のマシンが接続しっ放しになるため)
defmodule A.Application do
# See https://hexdocs.pm/elixir/Application.html
…
def start(_type, _args) do
topologies = [
clusters1: [
- strategy: Cluster.Strategy.Epmd,
- config: [hosts: [:"node1@172.24.176.1", :"node2@172.24.176.2"]]
+ strategy: Cluster.Strategy.Gossip,
+ config: [
+ polling_interval: 1_000
+ ]
]
]
children = [
# Starts a worker by calling: A.Worker.start_link(arg)
# {A.Worker, arg}
{Cluster.Supervisor, [topologies, [name: A.ClusterSupervisor]]}
]
…
1台目を起動します
iex --name node1@172.24.176.1 --cookie edge-servers -S mix
これで2台目以降のマシンも勝手にクラスター参加できるようになったので、3台目のマシンを起動します
iex --name node2@172.24.176.2 --cookie edge-servers -S mix
3台目のマシンが、自動的にクラスター参加したことが確認できました
iex> Node.list
[:"node2@172.24.176.2", :"node3@172.24.176.3"]
これでオートスケールが実現されました
Elixirクラスターのダウン後自動復帰
上記オートスケールを設定すると、同時に、ダウン後自動復帰も実現されるので、試してみましょう
2台目のマシン上のiexを、Ctrl+cを2回押すことで、ダウンさせると、クラスター内のノードが減ります
iex> Node.list
[:"node3@172.24.176.3"]
この状態から、2台目のマシンのiexを再起動します
iex --name node2@172.24.176.2 --cookie edge-servers -S mix
すると、2台目のマシンが、自動的にクラスター復帰したことが確認できました
iex> Node.list
[:"node2@172.24.176.2", :"node3@172.24.176.3"]
これでダウン後自動復帰が実現されました
ここまでで何が可能となったのか?
下記が可能となっています
- 複数ノードでクラスターを組める
nl()
でノード複製ができる- クラスターをオートスケールできる
- ノードダウン後のアップ時にクラスターに自動復帰できる
これらにより、クラウドを使わずともオートスケール/ダウン後自動復帰を含むモダンなクラスタリングが実現できるので、複数ノードで構成されるエッジサーバを簡単に実現できます
なお、Gossipプロトコルでは無く、DNSや複数IPでオートスケール/ダウン後自動復帰したい場合は、下記のようなものがあるのでトライしてみてください
- 「DNSポーリング」戦略を使う
- 「Kubernates」戦略のIPルックアップを使う
- 「dns_cluster」ライブラリを使う
終わりに
Elixirクラスターのオートスケール/ダウン後自動復帰も、とても簡単に構築できました
Elixirなら、クラウドが無くても、モダンなクラスタリングが実現できることを実感できたかと思います
次回は、オートスケール/ダウン後自動復帰を下敷きとしたDB分散を実現します
p.s.このコラムが、面白かったり、役に立ったら…
明日は、 @RyoWakabayashi さんで 「Advent of code 2015 Day 24 Part 1 & Part 2 を Livebook で楽しむ」 です