クラスター機能

概要

これは複数の Sora でクラスターを構成し、冗長化、負荷分散を行うための仕組みです。

目的

可用性を高めるため Sora 複数台でクラスターを組み、冗長化やロードバランシングを実現します。

用語

ノード

クラスターに参加している Sora です

特徴

クライアントへの複数シグナリング設定

Sora SDK にシグナリング URL を複数指定することで、いずれかの ノードが正常に動作していれば Sora に繋がります。

ノード選択 / ロードバランス機能

クラスターを構築しているノードの中で 現在の同時接続数 を ライセンスの最大同時接続数 で割った値が一番小さいノードに、新規チャネル ID の担当を割り当てます。 この値がすべて同じ場合は、接続しに行ったノード自身が新規チャネル ID を担当します。

すでに、そのチャネル ID がクラスター内部で利用されている場合は、 そのチャネル ID を担当しているノードへ接続先が割り当てられます。

シグナリングのリダイレクト機能

"type": "connect" を送った際、認証処理に入る前に {"type": "redirect", "location": "wss://sora1.example.com/signaling"} が Sora から送られてくる場合があります。

この場合は、送られてきた location の URL にシグナリング URL を切り替えて再度 type: connect を行ってください。 その際は {type: connect, redirect: true} のように redirect: true を追加情報として入れてください。

HTTP API のリダイレクト機能

チャネル ID を指定する HTTP API を利用する場合、リダイレクトが発生することがあります。 指定されたチャネル ID を他ノードが担当している場合に、ステータスコード 307 (Temporary Redirect)の HTTP 応答により、クライアントにそのノードへのリダイレクトを要求します。

ステータスコード 307 の HTTP 応答受信時の処理は、HTTP のクライアントとして使用するツールやライブラリにより異なります。 必要に応じて、リダイレクト応答の Location ヘッダーへアクセスを継続するようにしてください。

たとえば、curl コマンドの場合は、 -L オプションを指定することでリダイレクト先への再要求を行います。

クラスター自動参加機能

クラスターにノードが自動で参加する機能です。

Sora はクラスターが有効な際、起動時に sora.conf の contact_node_name_list に存在する ノード名に対してクラスターの参加を自動で試みます。

また、そのノードが一度でもクラスターに参加したことがある場合は、そのクラスターに参加していた時の ノード一覧を利用して、クラスターへの参加を自動で試みます。

クラスター手動参加機能

クラスターを手動で構築する機能です。既存のクラスターに参加する際に、クラスターに参加させるノードで JoinCluster API を実行します。

すでクラスターに参加しているいずれかのノードの名前を contact_node_name に指定してください。 クラスターに参加していて、初期化済みであれば、どのノードでもかまいません。

クラスター自動復旧

クラスターで利用しているネットワークに障害が発生した際には、個々のノードはクラスターを構成する他のノードへの接続を試みて、復旧処理を行います。

ネットワーク分断時の接続受け付けの停止

ネットワーク分断時には Sora のノード間で通信ができずに、クラスター内の情報の整合性が取れなくなる可能性があります。 この情報の不整合を回避するために、Sora は自分がクラスター内の半数以下のグループに属した場合には、既存の接続を切断し、 さらに新規接続の受け付けも停止します。

特定ノードへの新規チャネル ID の割り当て停止

モード機能 の 新規コネクションブロックモード または 新規セッションブロックモード になっている場合は、 そのノードに対して新規チャネル ID の割り当てを行いません。

録画情報の共有

録画の情報はクラスター内部で共有されます。 たとえば StartRecording API をあるノードに対して実行した後にそのノードが停止しても 録画情報は他のノードに残り続けます。

ネットワーク障害やノード障害

Sora のクラスター機能はネットワーク障害やノード障害が発生した際に、 自動で新規接続の受け付けの停止とそこからの復旧を試みます。

発生しうる問題と新規接続の受け付け停止

ネットワーク障害等が発生した場合には、 Sora のノード間で通信ができず、クラスター内の情報の整合性が取れなくなる可能性があります。

たとえば、5 ノードのクラスターが 3 ノードからなるグループ A と 残りの 2 ノードからなるグループ B の 2 グループに分断されるということが起こりえます。 それぞれのグループ内では通信ができるものの、他グループへの通信ができないという状態です。

この状態ですべてのノードが接続を受け付けると、同じチャネル ID を指定していても、 あるクライアントはグループ A に繋がり、別のクライアントは グルーブ B につながる可能性があり、 それぞれのクライアント間で音声と映像が届かなくなります。

このような状況を防止するため、Sora は自分が半数以下のグループに属した場合に、新規接続の受け付けを停止します。 また、ノード数が半数以下のクラスターに参加しているノードは、接続中のすべての接続を切断し、その後は接続を受け入れません。

その後、クラスター自動復旧機能により、通信できるノードが過半数のグループとなった場合には、自動で新規接続の受け付けを再開します。

全ノードが半数以下のグループに所属した場合の挙動

ネットワーク障害等が発生したことで、いずれのグループも通信できるノードが半数以下になった場合、 どこグループでも新規接続はまったく受け付けられない状態になります。

この状態でも Sora は、永続化しておいたノード一覧を利用し自動でクラスターの復旧を試みます。 そして、クラスターが復旧して過半数のグループができた場合は新規接続が可能になります。

クラスター環境での録画

録画情報の共有

録画の情報はクラスター内部で共有されます。 たとえばレガシー録画の StartRecording API をあるノードまたに対して実行した後にそのノードが停止しても 録画情報は他のノードに残り続けます。 また指定したチャネル ID に接続がない状態であれば、 StopRecording API はどのノードに対しても実行できます。

たとえば、あるチャネル ID でレガシー録画の StartRecording API が実行された後に、 ノード A に接続がきて録画が開始したとします。 このノード A がノード障害等で終了した後に、同じチャネル ID で別の接続がノード B に来た場合には ノード B で録画が進行します。

録画ファイルの出力ノード

archive-<connection_id>.json, archive-<connection_id>.webm の録画ファイルは、接続を担当するノードで 出力されます。

次のような場合には同一の recording_id に属する録画ファイルが、 複数ノードにまたがって出力されることがありますのでご注意ください。

  1. レガシー録画機能 でチャネル ID を指定して録画開始
  2. ノード A に指定したチャネル ID の接続が来てしばらくして切断、録画ファイルがノード A に作られる
  3. ノード A が停止
  4. ノード B に指定したチャネル ID に接続が来てしばらくして切断、録画ファイルがノード B に作られる

report-<recording_id>.json ファイルの出力ノード

あるチャネルに対して、 StopRecording API を実行した場合には録画が終了し、 report-<recording_id>.json ファイルが出力されます。

このファイルの出力ノードは次のとおりです。

  • そのチャネルに接続したクライアントがひとつもなかった場合はどのノードで出力されるかは未定です
    • ただし、クラスター内のいずれかのノードで出力されます
  • そのチャネルに接続中のクライアントがいる場合は、チャネルの担当ノードで出力されます
  • そのチャネルに接続したクライアントが過去にいた場合は 2 パターンがありえます
    • クライアントが接続したノードが生存し続けている場合はそのノードで出力されます
    • ノードが落ちている、または停止した後に再起動した場合にはどのノードで出力されるかは未定です
      • ただし、クラスター内のいずれかのノードで出力されます

report-<recording_id>.json ファイルが一時的に出力されない場合

全ノードが半数以下に所属した場合には report-<recording_id>.json ファイルが出力されません。

5 ノードのクラスターがあるとして、いくつか例を示します。

  • ネットワーク障害が発生し、2 + 2 + 1 に分断された場合
  • ノード障害(運用での停止も含む)が発生し、3 ノードが停止した場合
  • ノード障害で 1 ノードが停止した状態でネットワーク障害が発生し、 2 + 2 に分断された場合

このあとに分断が解消し、過半数のグループができたあとに StopRecording API を 実行すると report-<recording_id>.json ファイルが出力されます。

report-<recording_id>.json ファイルの archives の内容と実際に出力される録画ファイルが一致しない場合

録画中のノードがクラスターから分離された場合に report-<recording_id>.json ファイルの archives に全ての録画ファイルが含まれないケースがあります。

録画中のノードがクラスターから分離された場合は別のノードが report-<recording_id>.json ファイルを出力しますが、クラスター分離前に共有された録画情報の内容で出力し、 分離直後に作成された録画ファイルは含まれないためです。

設定

cluster

クラスター機能を利用する場合、 sora.conf にて cluster を true を設定する必要があります。

デフォルトでは cluster は有効になっていません。

cluster = true

node_name

クラスター機能を利用する際のノード名を指定して下さい。

この名前はクラスター内のノードの識別に使われます。 具体的には、クラスターノード間の通信相手の特定や、 sora.conf の contact_node_name_list 、 JoinCluster API、 PurgeClusterNode API で指定する名前として利用します。

ノード名の @ の前には、正規表現 [0-9A-Za-z_\\-]+ にマッチする任意の文字列を指定してください。 また @ の後ろには、他のノードからアクセス可能なこのノードのドメイン名(FQDN)や、IP アドレスを指定してください。

@ の後ろにホスト名("." を含まない文字列)のみを指定すると、ノード間で通信が行えなくなってしまいますので、ご注意ください。

# ドメイン名を指定する例
node_name = node01@node01.example.com
# IP アドレスを指定する例
node_name = node02@192.0.2.1

contact_node_name_list

クラスター機能が有効な場合で、 sora.conf の contact_node_name_list が指定されていた場合、 起動時に自分以外のノード名に対して自動でクラスターの参加を試みます。

node_name_list = sora1@192.0.2.1, sora2@192.0.2.2, sora3@192.0.2.3

cluster_auto_reconnect

クラスター機能が有効な場合で、 sora.conf の cluster_auto_reconnect が true の場合、 ネットワーク障害やノード障害の発生時に自動で再接続を試みます。

この設定はデフォルトで有効です。

cluster_auto_reconnect = true

external_signaling_url

sora.conf にてシグナリングの URL を指定して下さい。 この URL はクラスター機能を利用した際に "type": "redirect" の "location" の値として払い出されます。

external_signaling_url = wss://node1.example.com/signaling

例えば、上記の設定の場合は、シグナリングのリダイレクトが必要な際に Sora から {"type": "redirect", "location": "wss://node1.example.com/signaling"} として払い出されます。

external_api_url

sora.conf にて API の URL を指定して下さい。 この URL はクラスター機能を利用した際に、API を適切なノードに HTTP 307 でリダイレクトさせる場合の HTTP の location ヘッダーの値として払い出されます。

external_api_url = https://node1.example.com/api

cluster_listen_{min,max}_port

sora.conf にてクラスター情報の同期に利用する TCP の受信ポートの範囲を指定してください。

デフォルトでは 49010 - 49020 が指定されています。

cluster_listen_min_port = 49010
cluster_listen_max_port = 49020

API

クラスター初期化 API

クラスターを構築するときは、まずクラスターの初期化を行います。

クラスターの初期化を実行する場合は 20221221.InitCluster API をクラスター構築するいずれかのノードで実行します。 node_name_list にはクラスターを構成するノードを、 20221221.InitCluster API を実行するノードを含め指定してください。

API の詳細は InitCluster API をご確認ください。

$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20221221.InitCluster \
    node_name_list:='["node-02@192.0.2.7", "node-03@192.0.2.8", "node-01@192.0.2.5"]' \
    -vvv
POST / HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 83
Content-Type: application/json
Host: 127.0.0.1:3000
User-Agent: HTTPie/3.2.2
x-sora-target: Sora_20221221.InitCluster

{
    "node_name_list": [
        "node-02@192.0.2.7",
        "node-03@192.0.2.8",
        "node-01@192.0.2.5"
    ]
}


HTTP/1.1 200 OK
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, x-sora-target
access-control-allow-methods: POST, OPTIONS
access-control-allow-origin: *
access-control-max-age: 1000
content-length: 80
content-type: application/json
date: Wed, 06 Dec 2023 06:52:47 GMT
server: Cowboy

{
    "node_name_list": [
        "node-02@192.0.2.7",
        "node-03@192.0.2.8",
        "node-01@192.0.2.5"
    ]
}

クラスター参加 API

参加するノードに対して、すでにクラスターに参加しているノードを指定してクラスターへ参加します。

API の詳細は JoinCluster API をご確認ください。

下記は、これから参加する既存クラスター内の node-01@192.0.2.5 ノードを contact_node_name に指定して、新規に参加させるノードで JoinCluster APIを実行しています。

$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20211215.JoinCluster \
    contact_node_name=node-01@192.0.2.5
HTTP/1.1 200 OK
content-length: 80
content-type: application/json
date: Tue, 16 Nov 2021 08:42:25 GMT
server: Cowboy

{
    "node_name_list": [
        "node-01@192.0.2.5",
        "node-02@192.0.2.7",
        "node-03@192.0.2.8"
    ]
}

クラスターノード完全消去 API

あるノードが障害で再度の参加が難しい、またはスケールインのためにノード破棄する場合は、 破棄するノードを停止後に PurgeClusterNode API を利用して、そのノード情報を完全消去してください。

20220629.PurgeClusterNode API は、クラスターに参加している破棄するノード以外のどのノードでもかまわないので 1 回だけ実行します。 この API で完全消去した結果はクラスター内部で共有されます。

$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20220629.PurgeClusterNode \
    target_node_name=node-01@192.0.2.5
HTTP/1.1 200 OK
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, x-sora-target
access-control-allow-methods: POST, OPTIONS
access-control-allow-origin: *
access-control-max-age: 1000
content-length: 40
content-type: application/json
date: Wed, 06 Dec 2023 07:16:06 GMT
server: Cowboy

{
    "target_node_name": "node-01@192.0.2.5"
}

詳細は PurgeClusterNode API をご確認ください。

クラスターノード一覧 API

詳細は ListClusterNodes API をご確認ください。

$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20211215.ListClusterNodes
HTTP/1.1 200 OK
content-length: 1006
content-type: application/json
date: Tue, 16 Nov 2021 08:36:25 GMT
server: Cowboy

[
    {
        "external_api_url": "http://192.0.2.5:3000/",
        "license_max_connections": 600,
        "license_max_nodes": 10,
        "license_serial_code": "ABCDEF-SRA-E001-203801-400",
        "license_type": "Experimental",
        "node_name": "node-01@192.0.2.5",
        "connected": true,
        "mode": "normal",
        "external_signaling_url": "wss://node-01.example.com/signaling",
        "version": "2023.2.0"
    },
    {
        "external_api_url": "http://192.0.2.7:3000/",
        "license_max_connections": 600,
        "license_max_nodes": 10,
        "license_serial_code": "ABCDEF-SRA-E002-203801-400",
        "license_type": "Experimental",
        "node_name": "node-02@192.0.2.7",
        "connected": true,
        "mode": "normal",
        "external_signaling_url": "wss://node-02.example.com/signaling",
        "version": "2023.2.0"
    },
    {
        "external_api_url": "http://192.0.2.8:3000/",
        "license_max_connections": 600,
        "license_max_nodes": 10,
        "license_serial_code": "ABCDEF-SRA-E003-203801-500",
        "license_type": "Experimental",
        "node_name": "node-03@192.0.2.8",
        "connected": true,
        "mode": "normal",
        "external_signaling_url": "wss://node-03.example.com/signaling",
        "version": "2023.2.0"
    }
]

クラスターチャネル割り当て一覧 API

詳細は ListClusterChannels API をご確認ください。

$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20211215.ListClusterChannels
HTTP/1.1 200 OK
content-length: 461
content-type: application/json
date: Tue, 16 Nov 2021 08:42:25 GMT
server: Cowboy

[
    {
        "channel_id": "sora",
        "owners": [
           {
               "node_name": "node-01@192.0.2.5",
               "connected": true
           }
        ]
    },
    {
        "channel_id": "lemon",
        "owners": [
           {
               "node_name": "node-01@192.0.2.5",
               "connected": true
           }
        ]
    },
    {
        "channel_id": "hisui",
        "owners": [
           {
               "node_name": "node-03@192.0.2.5",
               "connected": true
           }
        ]
    },
    {
        "channel_id": "zakuro",
        "owners": [
           {
               "node_name": "node-03@192.0.2.5",
               "connected": true
           }
        ]
    }
]

クラスター運用

推奨ノード数

Sora のクラスター構築ノード数は 3 ノードが推奨となっております。

クラスターからの一時的な離脱

モード切り替え API を利用し、 新規コネクションブロックモード または 新規セッションブロックモード に 切り替えます。 その後、すべての接続がいなくなったタイミングでノードを終了してください。

一時的に離脱したノードは、再起動するとそのままクラスターに参加して動作します。

一時的に離脱したノードを含めるクラスターノード一覧

ListClusterNodes API では現在クラスターに参加しているノードの一覧が返ります。

クラスターからノード情報の完全消去

特定のクラスターノードで障害が起きた後、復旧が難しい場合は PurgeClusterNode API を利用して、 クラスターに参加しているノードから、障害が起きたノードの情報を完全消去してください。

また、スケールインのためにノードを破棄する場合も同様に PurgeClusterNode API を 利用して、破棄したノードの情報を完全消去してください。

この作業はクラスターの新鮮さを保つために必要な作業となります。 この作業を行わないと存在していないノードが残り続けることで過半数かどうかの判断を誤る場合があります。

クラスターのアップデート

  1. アップデート対象のノードを ChangeMode API で 新規コネクションブロックモード または 新規セッションブロックモード に切り替えます
  2. すべての接続がなくなったら Sora を停止させます
  3. 新しいバージョンの Sora へ入れ替えます
  4. 新しいバージョンの Sora を起動します
  5. ListClusterNodes API で新しいバージョンの Sora がクラスターに参加できているかを確認します

上の手順を 1 ノードごと に繰り返してください。

Sora のバージョンダウン

クラスターのアップデート の仕組みを使って、Sora のバージョンを下げることはできません。

そのため、クラスターのアップデート後に何らかの問題が発生し、 以前のバージョンに戻したい場合には、クラスターの再構築を行う必要があります。

再構築の際には、事前に全ノードを停止し、 data/ ディレクトリを削除した上で、 以前のバージョンの Sora を使用してクラスターの構築を行ってください。

クラスター破綻からの再構築手順

クラスターのうち、過半数のノードが停止した場合、クラスターのすべてのノードは接続を受け付けなくなります。 この状態からでも、停止したノードを再開させ、過半数のノードが正常に戻ったタイミングで、接続を受け付け始めます。 その場合は、ここで書かれている手順は必要ありません。

ただし、停止したノードがディスク障害などで data/ ディレクトリを失ってしまったときや、使っていた IP アドレスが使えなくなってしまうなどの理由で、再開できないこともあります。

ここでは、3 ノードクラスターを組んでいたものの、うち 2 つのサーバーがディスク障害で data/ ディレクトリを失った状態からの再構築手順を示します。

  • まずすべての Sora プロセスを停止状態にします
  • ディスク障害がおきたサーバーでは
    • Sora をインストールしなおします
    • 必要に応じて sora.conf 設定を行います
  • ディスク障害がおきなかったサーバーでは
    • data/ ディレクトリを削除します
    • これを忘れると正しい再構築ができません、必ず削除してください
  • ここまでで、完全にまっさらの Sora クラスターを構築する準備ができたことになります
  • すべてのノードを起動します
  • InitCluster API を発行し、クラスターを初期化します

以上の手順で、あたらしい 3 ノードのクラスターが動き始めます。

ノード名変更手順

sora.conf の node_name を変更する際の手順を示します。

この手順は、例えば Sora が動作するサーバーの IP アドレスが変わり、 node_name の IP アドレス部分を 変更する場合に必要になります。

  • 対象のノードを停止します
  • data/ ディレクトリを削除します
    • これを忘れるとノード名変更が正しく実行できません、必ず削除してください
  • クラスターの起動しているノードのいずれかに対し、 PurgeClusterNode API を発行し、 対象のノードをクラスターから削除します
  • sora.conf の node_name を変更します
  • 対象のノードを起動します
  • JoinCluster API でクラスターにあらたに参加します

ノード名を変更する場合の contact_node_name_list の扱い

ノード名の変更をするときに、クラスター自動参加を利用する方法を示します。 クラスター自動参加を使わずに JoinCluster API を使う場合は この説明は関係しません。

関連する sora.conf の設定は contact_node_name_list です。 この設定は sora 起動時のときのみ利用されます。 また、一度クラスターに参加して初期化済みとなった場合には、正しいノードリストを知っているため、 この設定は無視されます。

以下、具体的に、3 ノードクラスターがあり、全ノードの IP アドレスが変わる状況を考えます。

状況:

  • 現状のノード名: sora1@192.0.2.101, sora2@192.0.2.102, sora3@192.0.2.103
    • 既にクラスターを組んでいる
  • それぞれを新規のノード名 sora1@198.51.100.1, sora2@198.51.100.2, sora3@198.51.100.3 に変更する
    • まず sora1 を入れ替える
    • それが成功した後に sora2 を入れ替える
    • それが成功した後に sora3 を入れ替えと進める

現状のノードでは、既にクラスターを組んでいるため concact_node_name_list は利用されません。 そのため、sora.conf の設定を変更する必要はありません。

新しいノードでは、起動時に contact_node_name_list が利用されます。 入れ替えは順番に実行する必要があるため、現状のノードのみが起動中である状態や 新規ノードのみの状態、または混在している状態がありえます。

  • 最初に sora1 を入れ替える際には、残り2ノードは現状のノード sora2@192.0.2.102, sora3@192.0.2.103 です
  • 途中で sora2 を入れ替える際には、残り2ノードは現状のノード sora3@192.0.2.103 と新規 sora1@198.51.100.1 が混在しています
  • 最後に sora3 を入れ替える際には、残り2ノードは新規のノード sora1@198.51.100.1, sora2@198.51.100.2 です

このパターンに対して、ノード個別に contact_node_name_list を設定するのは複雑になってしまいます。 しかし、 contact_node_name_list に指定したノードのうち、起動していないノードは無視されますので、 既存ノードと新規ノードをすべて sora1@192.0.2.101, sora2@192.0.2.102, sora3@192.0.2.103 sora1@198.51.100.1, sora2@198.51.100.2, sora3@198.51.100.3 指定することで、全ノードの入れ替えに対応できます。

ロードバランサーの導入

クラスター機能を利用した場合は、シグナリング URL に対してロードバランサーが利用できます。

ただし、ロードバランス自体は Sora が行うため、 ロードバランサーの導入はシグナリング URL の 1 本化が目的となります。

  • ロードバランサーは WebSocket に対応している必要があります
  • ロードバランサーで TLS 終端はせず TLS で Sora へ接続する必要があります
  • Sora はロードバランサー経由以外にクライアントと直接接続できる必要があります
    • これはリダイレクトが発生し、ロードバランサーを経由せずに接続する可能性があるためです
  • Sora の WebSocket 通信は 30 秒に 1 回通信を発生させるため、ロードバランサーのタイムアウトは 30 秒以上にする必要があります
クライアントロードバランサーSora1Sora2アプリケーションサーバーBクライアントロードバランサーSora1Sora2アプリケーションサーバーBwss://sora.example.com/signalingwss://0001.sora.example.com/signalingWebSocket 確立"type": "connect""type": "connect""type": "redirect""location": "wss://0002.sora.example.com/signaling""type": "redirect""location": "wss://0002.sora.example.com/signaling"WebSocket 切断wss://0002.sora.example.com/signalingWebSocket 確立"type": "connect"認証ウェブフック"allowed": true"type": "offer""type": "answer"WebRTC 確立

もしシグナリング URL の 1 本化を検討している方で、不明点がある場合はサポートまでご連絡ください。

ログの出力

クラスターに関するログは log/cluster.jsonl に生成されます。

ログの詳細については ログファイル をご確認ください。

注意

ライセンス

クラスターの 1 ノードにつき 1 ライセンスが必要になります。 3 台のノードでクラスターを構築する場合は 3 ライセンスが必要になります。

ポートの開放

以下のポートを開放して下さい

  • epmd(Erlang Port Mapper Daemon)で利用する TCP ポート
    • 4369
  • ノード間通信に利用する TCP ポート
    • 49010 - 49020
    • sora.conf の cluster_listen_{min,max}_port にて指定できます

ノード間通信の暗号化

Sora のノード間通信は暗号化されておりません。 そのため、安全なプライベートネットワークの利用を推奨します。

もし、パブリックネットワークを利用してクラスターを構築する場合は、ノード間の通信を暗号化する必要があります。その場合は Tailscale の利用をお勧めします。

Tailscale · Best VPN Service for Secure Networks

参考までに、下記は弊社の Tailscale 利用事例です。

ベアメタルサーバーを利用したクラウドサービスで発生する課題を Tailscale で解決する · Tailscale

クラスターのノード数

最低ノード数

Sora は最低 3 ノードのクラスターを構築してください。

  • 1 ノードで構築されたクラスターはクラスターを構築していないのと同様です
  • 2 ノードで構築されたクラスターは片方のノードが停止すると、正常なノードも過半数の条件を満たさなくなるため接続を受け付けなくなってしまいます

最大ノード数

クラスターを構築するノードの最大数は 10 ノードを想定しています。 これ以上のノード数を検討されている場合はサポートまでご連絡ください。

クラスター構成情報ファイル

Sora でクラスターを利用する場合、クラスター参加後のノード情報を永続化するためのファイルを data/ ディレクトリ以下に生成します。

Sora のバージョンアップ時

Sora のバージョンアップ時に data/ ディレクトリをコピーする必要はありません。 このファイルが無い場合、 Sora の起動の際に生成されます。

クラスターからのノードの完全消去について

クラスターからノードを完全に消去させる場合は bin/sora stop で停止させた後に、 クラスターを構成してる実行中のノードのいずれかに対して、 消去するノードのノード名を target_node_name に指定して PurgeClusterNode API を実行します。

PurgeClusterNode API で完全消去したノードの再度の参加

クラスターからノードを完全消去した場合、そのまま再度参加をすることはできません。 再度クラスターに参加する場合は data/ ディレクトリを削除する必要があります。

PurgeClusterNode API を実行して、さらにそのノードの data/ ディレクトリを削除した場合、そのノードは 完全に新規のノードとして取り扱われます。

この状態になったノードは新規ノードですので、 JoinCluster API をつかうか、 sora.conf の contact_node_name_list を利用してクラスターに参加できます。

クラスターから消去されたノードを別クラスターに参加させたい場合

あるクラスター A に参加していたノードを、A から削除して別のクラスター B に参加させたい状況を考えます。

PurgeClusterNode API で消去されたノードは以下の 2 点で以前参加していたクラスター A のノード群を覚えています。

  • sora.conf の contact_node_name_list
  • sora 起動ディレクトリ以下の data/ ディレクトリ内のデータ

そのため、再利用する場合には下記の手順で、クラスター A に関する情報を無くす必要があります。

  • contact_node_name_list は新しい別クラスター B のノードのリストに変更するか、または、リストを空にする
  • data/ ディレクトリを削除する

上記の手順の後は Sora を起動し、クラスター参加の手順に従って、ノードをクラスターに参加させます。

シーケンス図

Sora から別ノードへのリダイレクトを要求される

クライアントSora1Sora2Sora3アプリケーションサーバークライアントSora1Sora2Sora3アプリケーションサーバー"type": "connect"このノードは同時接続が多かったので、Sora2 へリダイレクト提案"type": "redirect""type": "connect", "redirect": true認証ウェブフック200 OK{"allowed": true}"type": "offer""type": "answer"WebRTC 確立イベントウェブフック"type": "connection.created"200 OK