# データベースを介した疎結合なモジュール連携 ## 定義 データベースを介した疎結合なモジュール連携とは、複数のモジュール(プロセス)が互いを直接呼び出す代わりに、共有のデータベース(状態ストア)への書き込み・変更通知(Pub/Sub)の購読・読み出しという間接的な経路だけでやり取りする設計パターンである。呼び出し側は相手のプロセスの存在やAPIを意識する必要がなく、共有データベースのテーブル/キーのスキーマだけを知っていればよい。SONiCではこのパターンがモジュール間通信の原則であり、「8.2 モジュールからデータベースへのアクセス」で解説されるアクセス方法(DBConnector・Table・ProducerStateTable)を双方のモジュールが実施することで成立する。(Source: [[@2025__Gihyo__実践SONiC入門 - Chapter 8 SONiCの内部構造:ステートの流れとモジュール連携]] ch.8 §8.2, §8.4) ## SONiCにおける実現要素 - **アクセスクラスの3層**: DBConnector(接続・基本操作)→Table(テーブル単位の読み書き、セパレータの違いを吸収)→ProducerStateTable(パイプライン処理による高速化)という3層構造が、モジュールごとに異なる実装を書かずに同じ疎結合パターンへ乗せることを可能にする。(Source: ch.8 §8.2.1, §8.2.2) - **Pub/Sub変更通知**: Redisのsubscribe機能により、あるモジュールの書き込みが別モジュールの動作開始トリガーになる(例: portsyncdのSTATE_DB書き込み→portmgrd/intfmgrd/vlanmgrdの起動)。データベースは単なる保存場所ではなく、疎結合な連携のためのイベントバスとしても機能する。(Source: ch.8 §8.1, §8.6.1) - **例外としてのorchagent内部通信**: `xxxOrch`という機能毎のクラス間では、他のOrchインスタンスを引数にコンストラクトすることで直接メソッド呼び出しが可能になる(例: SRv6OrchがNeighOrch::getNextHopId()を呼ぶ)。これは同一プロセス内のクラス間通信であり、デザイン文書上は他モジュールと同格に描かれるにもかかわらず、疎結合パターンから外れる唯一の例である。(Source: ch.8 §8.4.1) - **多段リレーとしての伝播**: ルーティング情報の伝播(BGP受信→ASIC反映)は、bgpd→zebra→fpmsyncd→APPL_DB→orchagent→ASIC_DB→syncd→SAI APIという経路で、データベースを2回(APPL_DB、ASIC_DB)経由する多段リレーとして実現される。疎結合であることの代償として、ホップ数に比例した伝播段数が生じる。(Source: ch.8 §8.7.2) ## 横断的知見 - 第7章がswssコンテナのモジュール群を`*orch`/`*syncd`/`*mgrd`という役割別命名規約で分類したのに対し、第8章はこの3分類がいずれも同一の下部メカニズム(データベースへの書き込み→Pub/Sub通知の購読→別モジュールによる読み出し)の上に成り立つことを示す。すなわち命名規約は「データがどちら向きに流れるか」を表す表層のラベルであり、その下には単一の疎結合パターンが共通して存在する。(Source: [[@2025__Gihyo__実践SONiC入門 - Chapter 7 SONiCの内部構造:アーキテクチャとサブシステム]] ch.7 §7.1.2, [[@2025__Gihyo__実践SONiC入門 - Chapter 8 SONiCの内部構造:ステートの流れとモジュール連携]] ch.8 §8.2, §8.4) - orchagent内部の`xxxOrch`間通信という例外は、疎結合と密結合の境界が「プロセス境界」と一致するのではなく、「デザイン文書上でモジュールとして扱われるかどうか」という設計判断で引かれていることを示す。第7章はorchagentを「swssコンテナ上で単一プロセスだがソースコードは機能ごとの`*orch.cpp`に分割される」と説明し、第8章はその内部クラスがデザイン文書上で他モジュールと同格に描かれると補足する。両者を合わせると、SONiCの疎結合設計はプロセス分離ではなく「デザイン文書がどう境界を引くか」という設計上の慣習によって運用されていることがわかる。(Source: ch.7 §7.5.5, ch.8 §8.4.1) ## 未解決の問い - データベースを介した通知の配送保証(at-least-once/at-most-once等)や順序保証はどの程度か。本書はRedisのsubscribe機能の存在のみを述べ、配送セマンティクスには踏み込んでいない。 - モジュール数・データベース段数が増えるにつれ、この疎結合パターンは全体のステート伝播レイテンシにどう影響するか(ルーティング反映は2段のデータベース経由で9ステップを要する)。 - [[Watch(状態変更通知)]]が指摘する「pubsubはメッセージング抽象化とハード状態のストレージ層を一体化(bundle)している」という限界は、SONiCのRedis Pub/Subにもそのまま当てはまるか。SONiCの疎結合設計はストレージとメッセージングを分離せず一体化したRedisを土台にしており、watch抽象化が目指す「ストレージを明示的に露出し通知を薄いレイヤーとする」設計とは異なる系統に位置づけられる可能性があるが、本書はこのトレードオフに言及していない。 - orchagent内部の直接呼び出しという例外は、機能追加のたびに増える可能性がある(xxxOrch間の依存が密になるほど密結合な近道が選ばれやすくなる)。この例外がSONiCの成長とともにどの程度広がっているかは本書からは読み取れない。 ## 関連 - ソース: [[@2025__Gihyo__実践SONiC入門 - Chapter 7 SONiCの内部構造:アーキテクチャとサブシステム]] / [[@2025__Gihyo__実践SONiC入門 - Chapter 8 SONiCの内部構造:ステートの流れとモジュール連携]] - 実体: [[SONiC]] - 概念: [[SONiCのモジュール責務分離]] — 命名規約による表層の分類。本conceptはその下部にある共通メカニズムを扱う。 / [[インメモリデータベース]] — Redisというインメモリストアの一般的性質。 / [[Watch(状態変更通知)]] — ストレージとメッセージングを分離する設計との対比。 ## 出典 - 海老澤健太郎, 『実践SONiC入門』, 技術評論社, 2025, 第7章・第8章.