⑤Elixirエッジコンピューティング：エッジサーバのオートスケール／ダウン後自動復帰

この記事は、[Elixir Advent Calendar 2024 シリーズ7](https://qiita.com/advent-calendar/2024/elixir) の20日目です

昨日は、@hisaway さんで [「パイプラインの流れでそのまま変数を定義したい」](https://qiita.com/hisaway/items/1ff1efdfda59d8c0dd85) でした

---

[piacere](https://twitter.com/piacere_ex) です、ご覧いただいてありがとございます :bow:

[前回](https://qiita.com/piacerex/items/f49b9531f86d7aa02b2a) は、クラウドを使わずにリアルタイム性を担保するElixir分散コンピューティングの「クラスタリング」に入門しました

今回は、引き続き [libcluster](https://github.com/bitwalker/libcluster) を使って、Elixir分散コンピューティングにおけるクラスターの「オートスケール／ダウン後自動復帰」を実現していきます

https://github.com/bitwalker/libcluster

本シリーズの全体像は、下記になります

:::note warn
[①クラウドからエッジ／エッジサーバに拡がる未来とElixir](https://qiita.com/piacerex/items/ba0143f784cf360dda5f)
[②Elixiが叶えるエッジコンピューティングで最も重要なこと](https://qiita.com/piacerex/items/979cfa7575b880144c4c)
[③クラウドを使わないElixir分散コンピューティング](https://qiita.com/piacerex/items/401cbe7bb5898c3d8308)
[④Elixirエッジサーバのクラスタリング入門](https://qiita.com/piacerex/items/f49b9531f86d7aa02b2a)
[⑤Elixirエッジサーバのオートスケール／ダウン後自動復帰](https://qiita.com/piacerex/items/3a19a3a43f3d49bf3f63)
:::

### :xmas-tree: There are 13 Elixir Advent Calendar, making for a hot winter! :xmas-tree:

[Over the past 7 years, Elixir has consistently been a top-ranking language](https://speakerdeck.com/piacerex/7nian-jian-sok-ke-totupurankaru-risitaelixirniyoukoso?slide=13) in the programming category of the Advent Calendar, [claiming the #1 spot last year](https://qiita.com/advent-calendar/2023/ranking/feedbacks/categories/programming_languages). This year, too, Elixir is sure to stay at the top.

We’re feeling the excitement again this year… Please support or subscribe! :bow:

https://qiita.com/advent-calendar/2024/elixir
https://qiita.com/advent-calendar/2024/ranking/feedbacks/categories/programming_languages
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/74211dea-90bd-3de9-d700-24d25414aa05.png)](https://qiita.com/advent-calendar/2024/ranking/feedbacks/categories/programming_languages)

# EPMD戦略ではオートスケール／ダウン後自動復帰できない

[前回構築したElixirクラスター](https://qiita.com/piacerex/items/f49b9531f86d7aa02b2a) で、3台目のマシン上でiexを起動する前に、下記のように3台目のノードを追加し、1台目のマシンのiexを再起動します

```diff_elixir:lib/a/application.ex【1台目のマシン】
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台しかリストされません

```【1台目のマシン】
iex> Node.list
[:"node2@172.24.176.2"]
```

ここで、3台目のマシンでiexを起動します

```【3台目のマシン】
iex --name node3@172.24.176.3 --cookie edge-servers -S mix
```

しかし、自動的にはクラスターに参加してくれません

```【1台目のマシン】
iex> Node.list
[:"node2@172.24.176.2"]
```

3台目のマシンをクラスターに参加させるには、libclusterの動く1台目のマシンのiexを再起動するしかありません

```【1台目のマシン】
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ノードが追加されたとき、自動的にクラスターにノードを追加してくれるので、オートスケールを実現できます（なお、Gossipプロトコル以外にもオートスケールを叶える方式は幾つかあるので、文末にまとめておきます）

さて、Gossipプロトコルでの実装を行う前に、1／3台目のマシンのiexを、Ctrl+cを2回押すことでダウンさせてください（で無いと、3台目のマシンが接続しっ放しになるため）

```diff_elixir:lib/a/application.ex【1台目のマシン】
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台目を起動します

```【1台目のマシン】
iex --name node1@172.24.176.1 --cookie edge-servers -S mix
```

これで2台目以降のマシンも勝手にクラスター参加できるようになったので、3台目のマシンを起動します

```【2台目のマシン】
iex --name node2@172.24.176.2 --cookie edge-servers -S mix
```

3台目のマシンが、自動的にクラスター参加したことが確認できました

```【1台目のマシン】
iex> Node.list
[:"node2@172.24.176.2", :"node3@172.24.176.3"]
```

これでオートスケールが実現されました

# Elixirクラスターのダウン後自動復帰

上記オートスケールを設定すると、同時に、ダウン後自動復帰も実現されるので、試してみましょう

2台目のマシン上のiexを、Ctrl+cを2回押すことで、ダウンさせると、クラスター内のノードが減ります

```【1台目のマシン】
iex> Node.list
[:"node3@172.24.176.3"]
```

この状態から、2台目のマシンのiexを再起動します

```【2台目のマシン】
iex --name node2@172.24.176.2 --cookie edge-servers -S mix
```

すると、2台目のマシンが、自動的にクラスター復帰したことが確認できました

```【1台目のマシン】
iex> Node.list
[:"node2@172.24.176.2", :"node3@172.24.176.3"]
```

これでダウン後自動復帰が実現されました

# ここまでで何が可能となったのか？

下記が可能となっています

- 複数ノードでクラスターを組める
- [`nl()` でノード複製ができる](https://qiita.com/piacerex/items/979cfa7575b880144c4c#%E3%83%8E%E3%83%BC%E3%83%89%E9%96%93%E3%81%AE%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E8%A4%87%E8%A3%BD)
- クラスターをオートスケールできる
- ノードダウン後のアップ時にクラスターに自動復帰できる

これらにより、クラウドを使わずともオートスケール／ダウン後自動復帰を含むモダンなクラスタリングが実現できるので、複数ノードで構成されるエッジサーバを簡単に実現できます

なお、Gossipプロトコルでは無く、DNSや複数IPでオートスケール／ダウン後自動復帰したい場合は、下記のようなものがあるのでトライしてみてください

- 「DNSポーリング」戦略を使う

https://qiita.com/RyoWakabayashi/items/b6888b510b20bb7579e8

- 「Kubernates」戦略のIPルックアップを使う

https://qiita.com/mokichi/items/c3157804faa295ce1574

- 「dns_cluster」ライブラリを使う

https://qiita.com/piacerex/items/f1cefcaa170c116db048#-dns_cluster

# 終わりに

Elixirクラスターのオートスケール／ダウン後自動復帰も、とても簡単に構築できました

Elixirなら、クラウドが無くても、モダンなクラスタリングが実現できることを実感できたかと思います

次回は、オートスケール／ダウン後自動復帰を下敷きとしたDB分散を実現します

# p.s.このコラムが、面白かったり、役に立ったら…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/907a8695-4d83-1b5c-8052-d0ce52de5f66.png) にて、どうぞ応援よろしくお願いします :bow:

---

明日は、 @RyoWakabayashi さんで[ 「Advent of code 2015 Day 24 Part 1 & Part 2 を Livebook で楽しむ」](https://qiita.com/RyoWakabayashi/items/6d3c963358bbda158af2) です