Skip to content.

Sections
Personal tools
You are here: Home » 技術文書 » パターン » パターンMulti-Phase Startup2.0

Document Actions
Multi-Phase Startup(多段階起動)
Ver 2.1 1999,12/12

(株)永和システムマネジメント   平鍋健児
作成日:Ver 1.0 1999,3/16
Ver 2.0 1999,6/16
Ver 2.1 1999,12/12
   目的

相互に依存し合ったサブシステムを,順序良く起動する.


   別名

ブートストラップ(bootstrap),ランレベル(run level), いち・にの・さん!(One, Two, Three!)


   動機

リアルタイムシステムや OS などのシステムの起動を考える.システムは複数 のサブシステムから構成されており,それらが相互に依存し合っているため, システム全体の起動時に各サブシステムを1つずつ一度に運用状態に起動する ことができない,という状況が起こり得る.

この様な場合,各サブシステムが提供するサービスを分割し,各サブシステム に渡るサービスの起動手順を確立して徐々に全体を立ち上げる必要がある.し かし,一般にその手順は複雑になり,また,手順の取り決めは全サブシステム の詳細な知識が必要となる.また,起動順序によっては,システム全体がデッ ドロックに陥るなどの危険性も含んでいる.

サブシステムの状態を,「停止」と「運用中」の2つに分けるのではなく,そ の中間レベルの状態(複数の場合もある)を定義する.起動時は,一旦すべての サブシステムを中間レベルで起動し,次に運用状態で起動するといった他段階 のブートストラップを行なうことで,相互依存性の問題を回避することができ る.また,中間レベルを複数持つ場合,それぞれの中間レベル状態をシステム 全体に渡って系統的に定義することができれば,起動手順の見通しが立てやす くなる.

この中間レベルの状態を表現するため,「ランレベル」という整数を定義し, システム全体で各ランレベルに関する申し合わせを規定することで, 起動手順に関する系統的な取り決めとする.

次のような例を考えよう.

ある OS には「ファイルシステム」(以下 FS と略)というサブシステムと, 「ネットワークインターフェイス」(以下 NI と略)というサブシステムが存在 した.従来,起動時にはまず FS を起動し,あるファイルに記述してある NI に必要な IP アドレスなどの情報を取得し,次に NIを起動して,最終的に 運用状態に立ち上がる,というブートストラップ手順を踏んでいた.最近に なってこの OS に,「ネットワークファイルシステム」(以下 NFS と略)と いう新たなファイルシステム種別が追加された.従来,FS は NIに依存してい なかったが,この新機能の導入により,FS と NIの相互依存関係が発生した. 即ち,

  1. NI は起動条件取得のために FS に依存する
  2. FS は NFS の起動のために NI に依存する

このように,サブシステム間に相互依存が生じると,まずファイルシステム,次に ネットワークインターフェイス,というように単純にサブシステム毎に起動する ことが出来なくなる.そこで,次のような便宜的な方策が採られた.

  1. FS は,まずローカルディスクのファイルシステムのみを起動する.
    ネットワークに接続されておらず,ローカルディスクのみで起動した状態を ランレベル1 と定義する.
  2. NI は,ローカルディスクに記述された起動条件によってネットワークに接続する.
    ローカルディスクおよび,ネットワークの基礎接続まで起動した状態をランレベル2 と定義する.
  3. 最後に,FS は NI が提供しているサービスを利用して NFS が利用できるようにする.
    この状態をランレベル 3 と定義し,これを最終の運用状態とする.

別な例として,java 言語のコンパイラを考える.相互に依存し合った2つ のクラスA.java, B.java を同時にコンパイルする場合,A.java をコンパイル するには B.java の知識が必要となるし,B.java をコンパイルするには A.java の知識が必要となる.この場合も,まず A.java ,次に B.java とい う単純なコンパイル順序では対処できないため,次のような3段階でコンパイ ルする戦略が考えれる.

  1. ソースコード中に定義されているクラス名を発見,登録する.(フェーズ1)
  2. クラスの中の,公開インターフェイスを発見,登録する.(フェーズ2)
  3. 上記を使用して,各クラスの実装をコンパイルする.(フェーズ3)

ここでも,相互依存を解きほぐすために,フェーズを分けて徐々に最終目的段 階へと進んで行く方策が採られている.この「多段階起動パターン」では,こ のように多くの場面に登場する「起動時の相互依存関係の解決」という問題と その一解法を提示する.


   適用可能性

  • 相互依存するサブシステムを起動したい場合.
  • 相互依存するサブシステムの優雅に停止したい場合.
  • 分散システムにおいて依存関係が循環する場合の起動.

   構造

構造
structure

   構成要素

  • System
    • システム全体の起動を司るクラス(Singleton であることが多い)
    • サブシステムへの参照を保持する.
  • SubSystem
    • サブシステムの抽象クラス
    • System へ各ランレベルへのエントリポイント(enterRunlevel)を提供する.
    • ConcreteSubSystem へ拡張ポイントとして(doRunlevel)を提供する.
  • ConcreteSubSystem
    • 実際の具体的なサブシステム
    • 具体的なサブシステムの,指定ランレベルでの動作を記述する.

   協調関係

  • System クラスは,自分が管理する各 SubSystem クラスに,各ランレベル 状態に入るように要請する.
  • 各 ConcreteSubSystem クラスは,自分自身を指定ランレベルの状態 に立ち上げる.

協調関係
collaboration


   実装

実装に置いては,以下の点を考慮する必要がある.
  • 実装に入る前に,各ランレベルの意味をシステム全体に渡って定義する 必要がある.各ランレベルでサブシステムごとにどの機能があてにされるのか を前もってシステム全体で合意しなければならない.
  • ある1つのサブシステムが特定のランレベルに入れないとき,エラーとし てシステムが認識し,次のランレベルへの移行を諦める,一定時間 待ってリトライする,あるいはエラー状況をサブシステムに伝える, などの方策が必要になることが多い.

   バリエーション

以下のようなバリエーションが考えられる.
  • ランレベルを3つに縮退させ,生成,init, start と名付けた例が多く使用される.

    3段階の実装
    3phase

  • System と SubSystem の関係を再帰的に階層化することで,他階層 システムに適用することができる.

    階層を持つ実装
    hierarchy

  • 起動のみならず,全体を優雅に停止させるためにも使用することができる.
  • より柔軟な解決として,System がトップダウンにレベルを管理するのではなく, 各 SubSystem 側に依存関係の解決とコンテキストの保持,および次の段階への上昇 を任せてしまう方法もある.この場合,System は各 SubSystem に対して,その SubSystem が運用状態に起動するまで何回でも start() を呼び出す.

    トップダウンなレベル管理を行なわない実装
    not-topdown

    この実装により,System 全体はより自律分散型となる.ただし,この実装を 行なった場合,全体の起動が正しく行なわれることを保証するのは難しい. すなわち,各 SubSystem は互いに他を観測可能でなければならず,お互いの 進行状況を見ながらの起動となる.実際に起動を始めて見ると,起動の進行 具合によって,デッドロックが発生してしまうことがあり得る.

    各 SubSystem の状態を1変数として n 個の SubSystem の状態を n 変数で 表現する n 次元状態空間を考える.初期状態から運用状態への移行は, 状態空間内での点の移動として捉えられるが,自律的な起動方法では 進行具合によりこの移行パス中に潜むデッドロック領域に落ち込んでしまう 可能性がある.

    トップダウンなレベル管理を行なった場合,この状態空間内での遷移パスに, 「ランレベル」と命名されたチェックポイントを置くこととに相当する. チェックポイントの導入によって,デッドロック領域を意識的に回避すること が可能となる.これは,「哲学者の食事」問題において「執事」(調停者)を導 入することによりデッドロックを回避する状況と等価なものである.

    トップダウンにレベル管理を行なった起動を行なうか,あるいは自律分散的 に起動を行なうかは,システムの複雑さ,起動時障害に対する要求の厳しさ, システムの柔軟性などのトレードオフとなる.

    システムの状態空間とデッドロック
    state-space

   結果

  • 相互依存したサブシステムが起動できるようになる.
  • 起動の手順に関するサブシステムに渡る申し合わせが明らかになる.

   使用例

  • UNIX システムの起動とランレベル.
  • 複雑なリアルタイムシステムの起動と終了.
  • 分散協調システムの起動と終了.

   関連するパターン

  • GoF の Singleton パターンが System/SubSystem に用いられることが多い
  • GoF の Composite パターンが 多階層の SubSystem に用いられる

   謝辞

このパターンを洗練していく過程で,JPLoP の参加者の方から数多くの 意見を頂いたことに感謝する.中でも,トップダウンなレベル管理を行なわない, より柔軟なバリエーションの提案は平澤さんであり,そのバリエーション では解決できない問題と,このパターンの本質に潜むヒューリスティック性の 発見は藤野さんである.


Kenji Hiranabe <hiranabe@esm.co.jp>
Last modified: Sun Dec 12 12:55:07 1999




この記事への評価にご協力をお願いします。

良かった 普通 イマイチ