Azure IoT Edge を運用していると、次のような問題を考える必要があります。
Azure IoT Hubとの通信が一時的に切れたとき、送信できなかったデータはどうなるのか?
Internet回線やFirewall、DNS、Proxyなどをどれだけ調整しても、通信断を完全にゼロにすることはできません。
そこで重要になるのが、Azure IoT Edge の Store-and-Forward です。
この記事では、
- Azure IoT Edgeで通信断が発生したときの動作
-
edgeHubが担うStore-and-Forward -
localstorageとの違い - Message保持時間
- Disk容量
- Restartをまたぐ場合の考え方
- 実際の通信断試験
-
edgeHubLogの確認方法
を整理します。
結論:通信断時のMessage保持はedgeHubが中心
先に結論を書くと、Azure IoT Edge のMessage Routingでは、
Application Module
↓
edgeHub
↓
Azure IoT Hub
という形で edgeHub がCloudとのMessage配送を仲介します。
CloudへMessageを配送できない場合は、
Application Module
↓
edgeHub
↓
Message保持
↓
通信復旧
↓
Azure IoT Hub
という Store-and-Forward の動作を利用できます。
つまり、
通信断
=
即データ消失
ではなく、
通信断
=
一時的にEdge側へ保持
=
通信復旧後に送信
という設計にできます。
ただし、
保持期間・Disk容量・Restart時の永続化まで含めて設計する必要があります。
なぜ通信断を前提にする必要があるのか
理想的には、
Medical Device
↓
Edge PC
↓
Cloud
が常に接続されている状態が望ましいです。
しかし実際の現場では、
Medical Device
↓
Edge PC
↓
×
Network
×
↓
Cloud
という状態は普通に発生します。
例えば、
- Internet回線の一時断
- Router / Firewallの一時的な問題
- DNS障害
- Proxy障害
- Network機器の再起動
- Cloud Service側の一時的な障害
などがあります。
前回は、施設ごとのNetwork Policyの違いを吸収するため、
AMQP
↓
AMQP over WebSocket
へ変更しました。
AMQP over WebSocketでTCP 443を利用すれば、通信を通しやすくすることはできます。
しかし、
通信を通しやすくすることと、通信が絶対に切れないことは別問題です。
そのためEdge Systemでは、
通信断を防ぐ
だけでなく、
通信断が発生したとき
Systemがどう動くか
まで考える必要があります。
Store-and-Forwardとは
Store-and-Forwardは名前の通り、
Store
↓
一時的に保持
Forward
↓
後から送信
する仕組みです。
例えば、正常時に
Data A → Cloud
Data B → Cloud
まで送信できた後にNetworkが切断されたとします。
その後、
Data C
Data D
Data E
が発生した場合、それらをすぐに捨てるのではなくEdge側へ保持します。
イメージとしては、
× Network disconnected
│
Medical Device
↓
Edge PC
│
├─ Data C
├─ Data D
└─ Data E
という状態です。
Networkが復旧したら、
Edge PC
│
├─ Data C ─→ Cloud
├─ Data D ─→ Cloud
└─ Data E ─→ Cloud
と送信を再開します。
これにより、
通信断
=
Data Lost
ではなく、
通信断
=
Data Delivery Delay
として扱えるようになります。
Azure IoT EdgeではedgeHubが通信の中心になる
今回使用しているEdge PCでは、Azure IoT Edge上で複数のModuleを動作させています。
概念的には次のような構成です。
edgeAgent
edgeHub
Application Module
TCPServer
SendAzure
localstorage
この中でCloudとのMessage Routingにおいて重要なのが、
edgeHub
です。
概念的には、
Application Module
↓
edgeHub
↓
Azure IoT Hub
という位置にあります。
正常時は、
Data
↓
Application Module
↓
edgeHub
↓
Network
↓
Azure IoT Hub
という流れになります。
Networkが切れるとどうなるか
Cloudとの通信が切れると、
Data
↓
Application Module
↓
edgeHub
↓
× Azure IoT Hub
となります。
ここでStore-and-Forwardが重要になります。
Messageをローカル側へ保持できれば、
edgeHub
[Message Store]
Data A
Data B
Data C
Data D
という状態にできます。
その後、Networkが復旧すると、
edgeHub
↓
Data A
Data B
Data C
Data D
↓
Azure IoT Hub
と、Cloudへの配送を再開できます。
つまり、Cloudとの接続状態だけを見て、
Connection lost
=
System failure
とするのではなく、
Connection lost
↓
Messageを保持
↓
Connection recovered
↓
Messageを送信
という復旧フローをSystemとして持たせます。
localstorageとedgeHubのMessage Storeは別物
ここは最初に構成を見たとき、少し分かりにくかったポイントです。
今回の構成には、
localstorage
というModuleも存在しています。
実際には、
azure-blob-storage:1.4.4-linux-amd64
として動作しています。
名前だけを見ると、
localstorage
↓
通信断中のDataを保存
↓
復旧後に再送
という役割に見えます。
しかし、
IoT Edge Message RoutingにおけるStore-and-Forwardと、Blob Storage Moduleは分けて考える必要があります。
今回整理している役割は、
edgeHub
=
IoT Edge Message Routing
+
Store-and-Forward
です。
一方、
localstorage
=
Edge上で利用するBlob Storage
です。
したがって、
edgeHub Message Store
≠
localstorage Module
です。
localstorageという名前だけを見て、
「通信断中のMessageを全部このModuleが保存している」
と考えないことが重要です。
「再送できる」だけでなく保持時間を設計する
Store-and-Forwardを利用するときは、
どれくらいの時間Messageを保持するのか
を決める必要があります。
edgeHubには、
storeAndForwardConfiguration
があり、その中の、
timeToLiveSecs
でMessageの保持期間を設定します。
概念的には次のような設定です。
"storeAndForwardConfiguration": {
"timeToLiveSecs": 7200
}
例えば 7200 秒なら、
7200秒
=
120分
=
2時間
です。
重要なのは、単純に大きな値を設定すればよいわけではないことです。
設計時には、
何分程度の通信断を想定するか
数時間切れた場合はどうするか
1日以上切れた場合はどうするか
その間に何件のDataが発生するか
を考える必要があります。
例えば、
想定通信断
=
数秒
のSystemと、
想定通信断
=
数時間
のSystemでは、必要なStorage容量が大きく変わります。
Disk容量も必ず確認する
Dataをローカルに保持する以上、当然Diskを使用します。
そのため、
Data発生量
×
最大通信断時間
を最低限考える必要があります。
例えば、
1 Message = 10 KB
1分 = 100 Message
通信断 = 6時間
なら、
10 KB
×
100
×
60
×
6
となり、おおよそ、
360 MB
のDataが発生します。
実際には、
- Message StoreのOverhead
- Log
- Docker / Container
- OS
- その他のApplication Data
などもDiskを使用します。
そのため、
Data発生量
+
想定最大通信断時間
+
Message保持期間
+
使用可能Disk容量
をまとめて確認します。
Edge PCのDiskがいっぱいになれば、
通信断対策
↓
Disk Full
↓
別の障害発生
となってしまいます。
つまり、
Offlineに耐える設計は、Network設計であると同時にStorage設計でもあります。
Restartをまたいでも大丈夫か確認する
もう一つ重要なのがRestartです。
例えば、
Cloud通信断
↓
MessageをEdgeへ保持
↓
Edge PC再起動
↓
Message消失
となってしまうと、長期間の無人運用では不十分です。
特にEdge PCでは、安定運用のために、
OS Restart
IoT Edge Restart
Container Restart
などを運用に含めることがあります。
そのため、通信断試験では、
Network disconnected
だけを見るのではなく、
Network disconnected
+
OS Restart
や、
Network disconnected
+
IoT Edge Restart
といった条件も確認する必要があります。
考えるべきなのは、
Containerの一時領域だけに依存していないか
です。
必要なDataやMessage Storeについては、Host側のStorageを利用して永続化し、
Restart
↓
Container再起動
↓
必要な状態を復元
できる構成になっているか確認します。
実際に通信を切ってStore-and-Forwardを試験する
設定しただけでは十分ではありません。
実際に通信を切断して確認します。
1. 正常時のData送信を確認
まず、
Medical Device
↓
Edge PC
↓
Azure IoT Hub
まで正常にDataが届くことを確認します。
2. Edge PCからCloudへの通信を遮断する
次に、
Medical Device
↓
Edge PC
↓
×
Azure IoT Hub
という状態を意図的に作ります。
この状態でDataを発生させます。
確認するポイントは、
Edge側Applicationが異常終了しない
Moduleが停止しない
Data入力を継続できる
通信断中のMessageが保持される
ことです。
3. Networkを復旧する
その後、Networkを復旧します。
Medical Device
↓
Edge PC
↓
Azure IoT Hub
ここで、
通信断中に発生したData
がCloudへ配送されることを確認します。
4. Restartを追加して再試験する
さらに、
Cloud通信断
↓
Data発生
↓
Message保持
↓
IoT Edge Restart
↓
Network復旧
や、
Cloud通信断
↓
Data発生
↓
Message保持
↓
OS Restart
↓
Network復旧
も試験します。
これによって初めて、
Onlineなら動く
だけではなく、
Offlineになっても復旧できる
Systemになっているか確認できます。
edgeHubのLogを確認する
Store-and-Forwardの動作確認では edgeHub のLogが重要です。
直近30分を見るなら、
iotedge logs edgeHub --since 30m
で確認できます。
通信関連のLogを絞りたい場合は、
iotedge logs edgeHub --since 30m 2>&1 | \
grep -Ei 'cloud|connect|disconnect|message|queue|store'
のようにすると、
Cloud connection
Reconnect
Message
Queue
Store
周辺を追いやすくなります。
Moduleの状態も確認する
各Moduleの状態は、
iotedge list
で確認します。
例えば、通信断を発生させた結果、
edgeHub
↓
Stopped
となってしまっている場合、
Store-and-Forward以前に別の問題が発生しています。
通信断中でも、
edgeAgent
edgeHub
Application Module
が期待した状態を維持しているか確認します。
Disk使用量も確認する
Offline Dataを保持する以上、Diskも確認します。
df -h
です。
長時間の通信断試験を行う場合は、
watch -n 5 df -h
として、Disk使用量の変化を見る方法もあります。
重要なのは、
Network
だけを見ることではありません。
Cloud Connection
+
edgeHub
+
Application Module
+
Message
+
Storage
を一つのSystemとして確認します。
通信断試験で確認したいチェックリスト
実際の試験では、私は次のように整理して確認しています。
[ ] 通常時にCloudへDataが届く
[ ] Cloud通信を切断する
[ ] Edge Applicationが停止しない
[ ] edgeHubが停止しない
[ ] Medical DeviceからのData入力を継続できる
[ ] 通信断中のMessageが保持される
[ ] Disk使用量が異常増加しない
[ ] Network復旧を検知する
[ ] CloudとのConnectionが再確立される
[ ] 通信断中のDataがCloudへ送信される
[ ] Backlogが最終的に解消する
[ ] IoT Edge Restartをまたいでも復旧できる
[ ] OS Restartをまたいでも必要なDataを維持できる
この試験まで行って初めて、
「通信断に対応している」
と言えると考えています。
Edge SystemはCloudがなくても一定時間動けるようにする
Cloudを使ったSystemを設計していると、
Cloudにつながっていること
を前提にしてしまいがちです。
しかしEdge Computingでは、
Online
↓
Cloudへ送信
だけではなく、
Offline
↓
Edge側の処理を継続
↓
Data保持
↓
Network復旧
↓
Cloudへ再送
まで一連の動作として成立させることが重要です。
つまり目指したいのは、
Network disconnected
=
System stopped
ではなく、
Network disconnected
=
Temporary offline operation
です。
通信断そのものを完全になくすことよりも、
通信断が起きてもDataを失わず、安全に復旧できるSystemを作る
ことの方が、現場で長期間運用するEdge Systemでは重要だと考えています。
まとめ
Azure IoT EdgeでCloudとの通信断に備える場合は、edgeHub のStore-and-Forwardを中心に考えます。
Application Module
↓
edgeHub
↓
Cloud
という通信経路でCloudへ送れない場合、
edgeHub
↓
Message保持
↓
通信復旧
↓
Cloudへ配送
という仕組みを利用できます。
ただし、Store-and-Forwardを有効にするだけでは十分ではありません。
確認したいのは、
保持期間
+
Data発生量
+
Disk Capacity
+
Restart時の永続化
+
通信復旧後の再送
です。
そして最後は、
実際にNetworkを切って試験する
ところまで実施します。
「通信が正常ならDataを送れる」ではなく、
「通信が切れてもDataを失わず、復旧後に元の状態へ戻れる」
ところまで確認することで、24時間365日の無人運用に近づけることができます。
次回:Windows 11のフリーズ原因をLinuxで切り分ける
以前の記事では、Windows 11 Proを搭載したEdge PCで発生した完全Freezeに対して、
不要なDriverを減らす
Graphic Driverを見直す
Device構成を減らす
常駐Softwareを減らす
といった切り分けを行いました。
しかし、一つ疑問が残ります。
本当にDriverだけが原因なのか?
Windows上でDriverを減らしても、
Power Management
Background Service
標準Driver
Kernel
など、Windowsそのものの影響までは完全には切り離せません。
そこで次はHardwareを変更せず、
Windows 11
↓
Linux
へOSを変更して切り分けます。
いきなり本番環境をLinuxへ移行するのではなく、
USBからLinuxを起動
↓
最小構成で動作確認
↓
Edge Applicationを導入
↓
オンサイト環境で長期試験
という順番で、条件を一つずつ追加して検証します。