クラスター機能¶
注意
クラスター機能を利用する場合は事前にサポートまでご連絡ください
警告
クラスター機能は 実験的機能 のため、正式版では仕様が変更される可能性があります
概要¶
これは複数の Sora でクラスターを構成し、冗長化、負荷分散を行うための仕組みです。
ひとつのチャネル ID をクラスターに参加している複数の Sora で共有することができます。 そのため、Sora をクラスターに追加で参加させることで 1 チャネル単位での配信をスケールアウトさせることができます。
ここではクラスター機能ついて説明しています。
クラスター機能を動かしてみる場合は クラスター機能のチュートリアル をご確認ください
クラスター機能の運用については クラスター機能の運用 をご確認ください
クラスター機能利用時の録画については クラスター機能での録画機能 をご確認ください
用語¶
- ノード
クラスターに参加している Sora
- リレー
ノード間での音声、映像、データの転送すること
- アフィニティ
同一セッションの接続を同一ノードに集約すること
クライアントへの複数シグナリング設定¶
Sora SDK にシグナリング URL を複数指定することで、いずれかの ノードが正常に動作していれば Sora に繋がります。
注釈
最低 3 つの URL を渡す事を推奨しています。
リレー機能¶
重要
リレー機能を利用するには 最大ノード数ライセンス が必要になります。
Sora クラスターはリレーという仕組みで、クラスターに参加しているノード同士で、クライアントの音声や映像、データを共有します。
例えば 3 ノードのクラスターがある場合、すでに接続しているクライアントがいるノードとは異なるノードにクライアントが接続した場合、 Sora はその異なるノードにすでに接続しているクライアントの音声や映像、データをリレーします。
この機能を利用することで 1 チャネルでのスケールアウトを実現できるようになります。
リレー機能はクラスター機能が有効な場合に利用できます。
リレー機能はデフォルトで有効になっています。
無効にしたいしたい場合は sora.conf
の cluster_relay を変更してください。
cluster_relay = false
リレー発生のタイミング¶
リレー機能利用時、リレーが発生するタイミングは別ノードに同一チャネルへ参加しているクライアントがいる場合のみです。
同一ノードのみの場合は他のノードへのリレーは発生しません。
メッセージングのリレー¶
リレー機能は音声と映像だけでなく、データもリレーを行います。そのため、リレー機能ではメッセージング機能も利用できます。
アフィニティ機能¶
重要
アフィニティ機能を利用するには 最大ノード数ライセンス が必要になります。
Sora クラスターはリレー機能利用時に、同一セッションの接続を同一ノードに集約するアフィニティ機能を提供します。
同一セッションへの接続を同一ノードに集約することでレイテンシーを低減し、より低遅延な通信を実現できます。
アフィニティ機能はデフォルトで有効になっています
無効にしたい場合は sora.conf
の default_cluster_affinity を変更してください
cluster_affinity = false
アフィニティはクラスター単位でのデフォルト値以外に、セッション単位やコネクション単位で指定することもできます。
セッション単位の指定は、
sora.conf
の default_cluster_affinity の値を上書きしますコネクション単位の指定は、
session.created
ウェブフックの値を上書きします
特定のコネクションだけアフィニティを行わず、最初に接続したノードで WebRTC の確立を試みることもできます。
もし接続したノードがライセンスの最大同時接続数に達している場合は、 余裕のある別ノードへのリダイレクトを行います。
注釈
リレー機能を検証したい場合は sora.conf
の default_cluster_affinity を false
に設定してください。
セッション単位でのアフィニティ指定¶
セッションウェブフック session.created
の戻り値で cluster_affinity
を指定することができます。
{
"cluster_affinity": "<boolean>"
}
"cluster_affinity": true
を指定した場合、そのセッションでは同一ノードへの集約を試みます。
"cluster_affinity": false
を指定した場合、そのセッションでは同一ノードへの集約を行わず、接続したノードでの WebRTC 確立を試みます。
コネクション単位でのアフィニティ指定¶
認証ウェブフックの認証成功時の払い出しで cluster_affinity
を指定することができます。
{
. "allowed": true,
"cluster_affinity": "<boolean>"
}
"cluster_affinity": true
を指定した場合は、接続したノードがセッションを集約しているノードでなければ、
"type": "redirect"
をクライアントへ返し、集約しているノードへの再接続を要求します。
"cluster_affinity": false
を指定した場合は、ノードへの集約を行わず、接続したノードでの WebRTC 確立を試みます。
テンポラリーノード機能¶
重要
テンポラリーノード機能を利用するには 最大ノード数ライセンス が必要になります。
クラスター機能にはスケールアウトの目的でクラスターに一時的に登録するテンポラリーノードという仕組みがあります。
テンポラリーノードを利用すると、クラスターを気軽にスケールアウトすることができます。一時的に同時接続数を増やしたい場合に利用してください。
設定¶
sora.conf
で cluster_temporary_node
を true
に設定することでテンポラリーノードとして扱われます。
cluster_temporary_node = true
登録¶
クラスターへの登録は RegisterClusterNode API を利用するか、
sora.conf
の contact_node_name_list を利用してください。
再登録¶
テンポラリーノードはクラスターから一度クラスターから認識されなくなると、再度クラスターに自動で再登録するには contact_node_name_list を利用する必要があります。
もし contact_node_name_list が設定されていない場合は、 RegisterClusterNode API を利用して再登録してください。
削除¶
テンポラリーノードはクラスターを維持するためのノードとして認識されません。そのため、クラスターへの登録も一時的なものになり、ノード破棄時に PurgeClusterNode API での削除を行う必要がありません。
注意¶
テンポラリーノードだけでクラスターを構築する事はできません
テンポラリーノードは InitCluster API で初期化することはできません
テンポラリーノードは PurgeClusterNode API でノードを削除することはできません
ノード選択とロードバランス機能¶
クラスターを構築しているノードの中で 現在の同時接続数
を
ライセンスの最大同時接続数
で割った値が一番小さいノードに、新規チャネル ID のセッションを割り当てます。
この値がすべて同じ場合は、接続しに行ったノード自身が新規チャネル ID のセッションを担当します。
リレー機能無効時¶
すでに、そのチャネル ID がクラスター内部で利用されている場合は、 そのチャネル ID を担当しているノードへ接続先が割り当てを試みます。
ただし、そのノードの同時接続数がライセンスの上限に達していた場合、 接続に失敗します。
リレー機能アフィニティ機能有効時¶
すでに、そのチャネル ID がクラスター内部で利用されている場合は、 そのチャネル ID を担当しているノードへ接続先の割り当てを試みます。
担当しているノードの同時接続数がライセンスの上限に達していた場合、 他のノードへのリダイレクトを試みます。
リレー機能アフィニティ機能無効時¶
すでに、そのチャネル ID がクラスター内部で利用されている場合でも、 そのノードで接続を行います。
シグナリングのリダイレクト機能¶
重要
Sora の SDK を利用している場合は、 基本的にここに書かれているリダイレクトの細かい仕様を把握する必要はありません。
"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 に存在する
ノード名に対してクラスターの参加を自動で試みます。
また、そのノードが一度でもクラスターに参加したことがある場合は、そのクラスターに参加していた時の ノード一覧を利用して、クラスターへの参加を自動で試みます。
クラスター手動参加機能¶
重要
sora.conf
の contact_node_name_list を利用したクラスター自動参加機能の利用を推奨しています。
クラスターを手動で構築する機能です。既存のクラスターに参加する際に、クラスターに参加させるノードで RegisterClusterNode API を実行します。
すでクラスターに参加しているいずれかのノードの名前を contact_node_name
に指定してください。
クラスターに参加していて、初期化済みであれば、どのノードでもかまいません。
クラスター自動復旧¶
クラスターで利用しているネットワークに障害が発生した際には、個々のノードはクラスターを構成する他のノードへの接続を試みて、復旧処理を行います。
ネットワーク分断時の接続受け付けの停止¶
ネットワーク分断時には Sora のノード間で通信ができずに、クラスター内の情報の整合性が取れなくなる可能性があります。 この情報の不整合を回避するために、Sora は自分がクラスター内の半数以下のグループに属した場合には、既存の接続を切断し、 さらに新規接続の受け付けも停止します。
特定ノードへの新規チャネル ID の割り当て停止¶
モード機能 の 新規コネクションブロックモード または 新規セッションブロックモード になっている場合は、 そのノードに対して新規チャネル ID の割り当てを行いません。
録画情報の共有¶
録画の情報はクラスター内部で共有されます。 たとえば StartRecording API をあるノードに対して実行した後にそのノードが停止しても 録画情報は他のノードに残り続けます。
合計接続数維持機能¶
重要
合計接続数維持機能を利用するには 最大ノード数ライセンス が必要になります。
クラスターを構築している場合、特定のノードがハードウェア障害などで利用できなくなった場合、 残りのノードで障害が発生したノードの同時接続数を引き継ぎます。
例えば 100 同時接続のノードを 3 つでクラスターを構築している場合、 1 つのノードに障害が発生した場合は 2 つのノードで 300 同時接続を維持できます。
割り当ては 1 つのノードが 150 までの同時接続数を許容できるようになります。
障害が発生したノードが復旧したとしても 100 を超えている接続を切断することはありません。 ただし 1 ノードの最大同時接続数の 100 までに戻ります。
設定¶
cluster¶
クラスター機能を利用する場合、 sora.conf
にて cluster を true
を設定する必要があります。
デフォルトでは cluster
は有効になっていません。
重要
cluster = true にして Sora を起動した場合、 Sora は InitCluster API を実行するか、クラスターに参加して過半数のグループになったタイミングでのみ利用可能になります。
cluster = true
cluster_relay¶
重要
クラスターリレー機能を利用する場合は 最大ノード数ライセンス が必要になります。
クラスターリレー機能を利用する場合、 sora.conf
にて cluster を true
を設定する必要があります。
cluster_relay
のデフォルトは true
になっています。
cluster = true
default_cluster_affinity¶
クラスターリレー機能でアフィニティ機能を利用する場合、 sora.conf
にて cluster と sora_conf-cluster_relay` を true
を設定する必要があります。
default_cluster_affinity
のデフォルトは true
になっています。
default_cluster_affinity = true
node_name¶
クラスター機能を利用する際のノード名を指定して下さい。
この名前はクラスター内のノードの識別に使われます。
具体的には、クラスターノード間の通信相手の特定や、
sora.conf
の contact_node_name_list 、 RegisterClusterNode API、
PurgeClusterNode API で指定する名前として利用します。
重要
node_name
はクラスター内のすべてのノードでユニークである必要があります
ノード名の @ の前には、正規表現 [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 が指定されていた場合、
起動時に自分以外のノード名に対して自動でクラスターの参加を試みます。
注釈
自分自身のノード名が contact_node_name_list
に含まれていても無視します。
node_name_list = sora1@192.0.2.1, sora2@192.0.2.2, sora3@192.0.2.3
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¶
以下の API はクラスター機能が有効な場合に 全てのノードの結果 をデフォルトで返すようになります。
そのため、ノード単体での結果を取得したい場合は local
パラメータに true
を指定してください。
クラスター初期化 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¶
Tip
sora.conf
の contact_node_name_list を利用したクラスターへの自動登録の利用を推奨しています。
参加するノードに対して、すでにクラスターに参加しているノードを指定してクラスターへ参加します。
API の詳細は RegisterClusterNode API をご確認ください。
下記は、これから参加する既存クラスター内の node-01@192.0.2.5 ノードを contact_node_name に指定して、新規に登録させるノードで RegisterClusterNode APIを実行しています。
$ http POST 127.0.0.1:3000/ x-sora-target:Sora_20211215.RegisterClusterNode \
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 で完全消去した結果はクラスター内部で共有されます。
警告
PurgeClusterNode API はクラスターからノードを完全に消去するための API です。 再度参加するノードに対しては基本的に使用しないでください。 この API を含めた運用の手順は cluster_operation をご確認ください。
詳細は PurgeClusterNode 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"
}
クラスターノード一覧 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
}
]
}
]
シーケンス図¶
リレー機能かつアフィニティ機能が有効¶
アフィニティ機能により、寄せが発生する
リレー機能が有効だが、アフィニティ機能が無効¶
アフィニティ機能による寄せが発生しない