産業用ゲートウェイのオフライン再送:容量・順序・重複を検証する

産業用ゲートウェイのオフラインバッファーは、データの永続保存に関する取り決めとして仕様化すべきです。どの測定を受け付け、どれだけ保持し、いつ削除でき、受信側が再送をどう扱うかを定めます。ネットワークの復旧だけでは、過去データが完全に届いたことを証明できません。受入試験では、取得、ローカル保存、最終アプリケーションの間でレコード識別情報を照合する必要があります。

本文は蓄積後に転送するテレメトリーを扱います。回線選択と切り替えは既存のEthernet・Wi-Fi・セルラーのフェイルオーバー受入試験ガイドの範囲です。コマンドやアクチュエーター操作には別途、有効期限と実行方針が必要です。古い制御コマンドの無条件再実行は危険になり得ます。以下の計算は容量設計の例であり、ゲートウェイ性能の主張ではありません。

どの時点からデータを保護するか定義する

センサー読み取りからサーバー上の確定済みレコードまでの経路を描きます。RAM にしかない値は電源断で消える可能性があります。ソケット送信の成功は、宛先での永続保存を意味しません。「ゲートウェイが受け付けた」を文書化したローカル永続化点、「配送済み」を文書化した受信側確認点として定義します。

ポーリング型センサーでは、応答をゲートウェイが永続保存する前の停電で、その観測が失われることがあります。それ以前から保護する製品要件なら、ソース側にも保持されたシーケンスや履歴、または別の復旧機構が必要です。観測不能な時間帯まで無損失を約束せず、取得の保護境界を明示します。

実用的な取り決めは、少なくとも一回の転送と、冪等な受信側の組み合わせです。再試行は発生しても、一つの安定したレコード ID から確定済み業務レコードが一つだけ生成されます。MQTT QoS の確認応答はプロトコル層の確認であり、下流データベースのトランザクション完了を単独では証明しません。MQTT 5.0 はプロトコル内の QoS と順序を定義します。エンドツーエンド配送には、ブローカーやコンシューマー障害後の動作を含むアプリケーション側の合意が必要です。

安定したレコードID、永続キュー、再試行、受信側トランザクション、確認応答、照合を示す蓄積転送テレメトリーの流れ。
図1:アプリケーション確認応答が永続再送のループを閉じます。レコードIDにより再試行と照合を明示できます。図中の表記は英語です。

停止期間と復旧後の流量に合わせて容量を決める

毎秒レコード数、対応する最大レコードサイズ、最大停止期間、実測した保存オーバーヘッドの余裕から始めます。識別情報、タイムスタンプ、フレーミング、インデックス、ジャーナル、コンパクション用一時領域、保存方針を含めます。フラッシュチップの公称容量は、キューに使える割当量ではありません。

raw_backlog_bytes = input_records_per_second
                  * outage_seconds
                  * stored_record_bytes
planned_queue_bytes = raw_backlog_bytes * overhead_and_headroom_factor
recovery_seconds = backlog_records
                 / (durably_acknowledged_records_per_second - input_rate)

毎秒20件、1件256バイト、8時間の停止を例にすると、未処理データの生容量は147,456,000バイト、約140.6 MiBです。暫定係数を2とすると281.3 MiBになります。キュー割当量を320 MiBにすれば一定の余裕がありますが、実際の保存形式と最悪条件のペイロードで確認が必要です。ファイルシステムの予約領域、システムログ、OTA作業領域には別の予算が必要です。

この停止で576,000件が蓄積します。新しいデータが毎秒20件増え続ける間に、受信側が毎秒80件を永続的に受け付けるなら、正味の解消速度は毎秒60件で、追いつくまで9,600秒、つまり2時間40分かかります。持続可能な確認応答速度が取得速度以下なら、滞留は解消しません。Ethernet帯域から推測せず、TLS、ブローカー、データベース、レート制限を通る経路全体を測定します。

順序とレコード識別情報を明示的に選ぶ

ソースID、ストリーム世代、単調増加シーケンスなど、安定した識別情報を使います。再試行でも変更しません。再起動や工場初期化で、受信側に残るIDを再利用しないよう、世代の生成と永続化を定義します。MQTTパケット識別子は、長期利用するアプリケーションレコードIDには適しません。

可能ならソースの測定時刻、ゲートウェイ取得時刻、タイムスタンプ品質を別々に保存します。ゲートウェイは信頼できる実時刻なしで起動する場合があり、後の時刻同期によって過去のシーケンス順序を書き換えてはいけません。ローカル期限には単調な経過時間を使います。バックエンドは遅れて到着した過去サンプルと新しい測定を区別すべきです。

通常、順序が重要なのは一つのセンサーストリーム内であり、ゲートウェイの全センサー間ではありません。全体順序を要求すると、障害のある宛先一つが無関係なソースを止める場合があります。最新レコードを滞留の後ろで待たせるか、最新データ専用経路を確保するか、重み付きスケジューラーを共有するか決めます。複数経路ではシーケンス情報を付け、許可された順序の前後を受信側で処理します。「最新値」と「完全な履歴」には別の利用経路が必要になることがあります。

ローカルで確定し、合意した確認応答後に削除する

整合性確認と復旧スキャンを備えた追記ログまたはトランザクション型データベースを使います。グループコミットは書き込み負荷を減らせますが、未確定グループは損失可能期間に残ります。同期前に受け付けたと扱うなら、その期間を文書化します。実際のファイルシステム、フラッシュ、ドライバー、電源回路を試験します。ソフトウェアのフラッシュ処理では、それを正しく実行しないストレージを補正できません。

SQLiteはLinuxでの選択肢であり、MCUゲートウェイの必須要件ではありません。アトミックコミットの文書は、トランザクションの前提を説明します。WALモードではsynchronous設定が電源断時の耐久性を変えます。NORMALでは直近の確定済みトランザクションが失われる場合があり、FULLはトランザクション単位の同期を追加します。耐久性を意図的に選択・検証し、WALとチェックポイントの領域も割当量に含めます。

以下はアプリケーション確認応答の概略です。実装には認証、サイズを制限したバッチ、障害処理、受信側の永続的な一意性制約を追加する必要があります。

gateway:
  persist(record_id, payload) before marking locally accepted
  send(record_id, payload)
receiver transaction:
  insert record if record_id is absent
  verify duplicate IDs refer to the same content
  commit
receiver:
  acknowledge(record_id) after the durable commit
gateway:
  persist acknowledgement, then reclaim the queued record

サーバーで確定した後に確認応答が失われると、ゲートウェイは同じIDで再試行します。確認応答後、ローカル削除前に停電した場合も再試行し得ます。受信側は両方に対応しなければなりません。先頭から連続して確定済みの範囲が成立していない限り、観測した最大番号未満をすべて削除してはいけません。順序が前後した場合の欠番を失うためです。

バッファー満杯時の動作を見えるようにする

承認したオーバーフロー方針を一つ選びます。受付停止、可能な場合のソースへのバックプレッシャー、最古データの破棄、最新データの破棄、指定データの集約などです。製品によって適切な選択は異なります。損失カウンターと影響したシーケンス/時間範囲を記録します。無言の上書きは後の照合を不可能にします。満杯時でもオーバーフローを報告できるメタデータ領域を予約します。

優先順位の取り決めが許す場合に限り、緊急イベントを周期テレメトリーと分離します。再試行の待機時間に上限を設け、機器ごとにジッターを加えて、復旧拠点からサーバーへの集中を防ぎます。取得期限、ローカルUI応答、通常通信を守る再送速度の予算を適用します。受信側の重複排除情報は、許容する再送/再試行期間全体をカバーする必要があります。古いレコードを再導入する可能性のある復元可能バックアップも含めます。

受入試験でIDを照合する

故障注入 証拠 提案する受入条件
最大入力負荷で8時間相当の停止 生成、ローカル受付、キュー内のIDと実バイト数 宣言した割当量と保存期間内で受付済み全レコードを保持
追記、同期、確認応答処理中の電源断 外部ソース台帳と復旧したキュー 永続受付した全IDが復旧、または受信側で確定済み
サーバー確定後にアプリケーション確認応答を破棄 繰り返された転送IDとサーバー行 再試行し、IDごとに業務レコードは一つ。同一IDで内容が異なる競合を明示
取得継続中の再接続 滞留量の傾き、取込遅延、CPU/ストレージ負荷 正味解消速度が正で、最新データと取得の予算を維持
キュー満杯、書き込み失敗、ストレージの読み取り専用化 故障状態、損失範囲、再起動動作 承認済みの容量超過/障害方針に従い、永続受付したと誤って扱わない
時計補正と機器再起動 ID、世代、シーケンス、時刻品質フィールド IDを再利用せず、許可されたストリーム順序を維持

試験装置には独立したソース台帳を保持します。ゲートウェイのキューだけを正としても、キュー投入前の損失は分かりません。受付済みID集合と確定済みID集合を比較し、ペイロードハッシュ、単位、ストリームごとの必要順序を検証します。転送の重複試行とアプリケーション行の重複を区別します。キュー最大使用量、最古レコードの経過時間、再送速度、未解決の損失を報告します。

実際のアプリケーションに合わせてバッファー範囲を決める

Obeitaの機器接続サービスでは、収集とサーバーメッセージの境界定義を相談できます。STM32収集・MQTT接続の納入事例は、オフライン保存を、保持容量と再送方針の合意が必要な追加範囲として明示しています。関連する納入事例ですが、その説明は特定バッファー寿命や容量の試験結果を示しません。

ソースプロトコル、ペイロード例、最大取得速度、停止期間の要件、ストレージハードウェア、サーバー確認応答の動作を提示します。「データ損失なし」という要件を受け入れる前に、納品範囲には容量モデル、IDスキーマ、容量超過方針、耐久性の前提、照合レポートのひな形を含めるべきです。

類似投稿