Mercurial は オフラインの海を越える 分散バージョン管理システムを 用いた高可用システムの 保守管理の試み
バージョン管理システムとは ファイルや各種のデータなどの内容を修正したり変更した内容を記録するソフトウェア 変更に一段落がつく度に、新バージョンとして登録 (commit) 修正差分を他のノードのソースへ展開する。 問題があった時に過去のバージョンに戻せる 今まで行ってきた修正が履歴として残る Repository 古いバージョンを保持しておく場所 管理対象のファイル群
バージョン管理ソフトの歴史 RCS (Revision Control System) 1 ファイル単位 修正目的は一つなのに、ファイルごとに履歴を書かなくちゃだめない ロック方式 誰からロックをかけちゃうと解除できない SI 開発ではよいが、不特定多数がパッチを作る OSS では不都合だった CVS (RCS を改良-> 一気に広まる ) ネットワーク連携 -> 中央集権型レポジトリ ディレクトリ単位で修正情報を登録 ロック方式排除 -> かわりにマージ機能 Subversion (CVS のいろんな不都合を修正 ) 余計なタグを埋め込まないので、バイナリでも安心 ファイルのリネームや移動をサポート ロールバック機能 ★  Subversion  が世界を制するかのように見えた!
なぜ  CVS/Subversion  では駄目なのか 全てのノードが オンラインであることを要求 SI 開発の場はそうではない 開発委託先と委託元 開発環境とテスト環境と本番環境 いずれも、オンラインで  IP⇔IP でつながっていることは、まずありえない。 苦肉の策は、オンラインでつながっているイントラネットごとに別々にレポジトリを立てること!
「苦肉の策」は、所詮「苦肉の策」 ファイルの移動は「 zip  でくれ」 バージョンナンバーや変更履歴がたくさん 場所 ( 本番 / 開発 / 委託先 ) ごとに違う ファイルごとに違う ( 記録の手間が一括なだけで、それぞれ別に採番 ) ファイルの同一性の保証ができない ファイルの構成が異なっている時、どのファイルを展開したらよいか、マージしたらよいかを、人間が管理しなくちゃいけない Linus  さんも駄目だと言ってる ★  これはもう破綻しているのではないだろうか
イントラネット単位? いやいや、むしろ強気にノードごとにレポジトリを設置します ノードの設置場所がバラバラであるという「現実」を踏まえた設計 それぞれのレポジトリの同一性が保たれていればよい。そのためには オフラインでもレポジトリを同期させる手段を提供できればよい。 双方のレポジトリが同一であることを保証できればよい バージョンナンバーは全体に対して、一つ採番すればよい 分散バージョン管理システムは答える 「レポジトリの分散? 上等!」
分散バージョン管理システムにも いろいろあるけれど Mercurial( マーキュリアル ) とは サーバ不要 Python 2.3 以上 ( 日本語を変更履歴に残すなら、 2.4 以上 ) Mozilla Firefox , NetBeans  などが採用 ライバルは  Git( あっちは  Linux Kernel が使ってる )
Mercurial  はオフラインの海を越える bundle / unbundle バージョン差分を 1  ファイルに抽出する ―  「 bundle 」 USB メモリ・メールなどで、差分ファイルを輸送する 差分ファイルを宛先レポジトリへ反映 ― 「 unbundle 」 開発 Repository Rev.20 USB 丸 19 ~ 20 の差分 本番 (Rev.19) 本番 (Rev.20) 同期 ! $ hg bundle –base 19 ver19to20.hg $ hg unbundle ver19to20.hg
同一性の保証 構成ファイルがなすツリー全体に対して、 一つのバージョン識別子 ―  ChangeSetID 一つでもファイルが変われば、 全体のバージョンナンバーが変わる これで「ファイルの漏れ」が分かる ChangeSetID  は通し番号ではなく、チェックサムみたいなもの 例:「 21: 4937b9f334ce 」 前半「 21 」は「単なる」通し番号 ( ノードによって違う ) 後半「 4937b9f334ce 」は一意性を示す ID つまり、 ChangeSetID  が同じなら、 レポジトリは一致しているんだよ!!!
Mercurial  は 真のバージョン管理を提供する ツリー全体の変更履歴をシーケンシャルに管理する 1 個でも変えたら、これに載る どれを変えたかも、ちゃんと載る ファイルの洩れが無いか、これで確認できる $ hg log | more changeset:  21:4937b9f334ce tag:  tip user:  [email_address] date:  Wed Mar 19 18:25:34 2008 +0900 summary:  20080319_syukka_release changeset:  20:563c0f01b2ed user:  [email_address] date:  Tue Mar 18 16:58:12 2008 +0900 summary:  * ks_limite_delte_pm : modify Makefile , remove files for schogedb because pm hogedb not need them. changeset:  19:8499441b8190 user:  [email_address] date:  Thu Feb 28 17:22:54 2008 +0900 summary:  * sequence list for rebuldsyn.rb changeset:  18:84487d3f3286 user:  [email_address] date:  Thu Feb 28 17:22:04 2008 +0900 summary:  * add export sequence script 'exp_sequences.sql'
クラスターに応用してみた クラスターは双方のノードで、同じ挙動を保証しなくてはならない。 が、共有ディスクに何もかも置くわけにはいかない TAKEOVER 時に、ディスクの受け渡しに失敗するリスクが増す だから、 DB など動的に変わるデータしか置くべきでない 1 号機と 2 号機の構成の同期は永遠の課題 ⇒  分散バージョン管理システムで同期する
Mercurial  と クラスター 1 号機で修正 1 号機で 「 hg commit 」 1 号機から 2 号機へ「 hg push 」 2 号機で 「 hg update 」 (2 を行うと 3 ~ 4 を自動化するのも可能 ) レポジトリ レポジトリ 1 号機 2 号機 $  hg commit $  hg push or $  hg pull $  hg update
どこでも  Mercurial Mercurial  はチェックアウトしたディレクトリのルートに  .hg  という隠しディレクトリを作るだけなので、どこでも管理しやすい。 というわけで、あるシステムは全てを  Mercurial  管理にした ソース  ,  スクリプトディレクトリ /etc ※ , /usr/local/dncware_scripts $ORACLE_HOME/dbs/ , $ORACLE_HOME/network/admin/ ※ cron 定義ファイルとか設定ファイル管理 別に同期させる必要はなくても、変更管理はしたいよね IP アドレスを含むディレクトリ (※) は同期させてはいけない 簡単に「ワークディレクトリ」と「レポジトリ」を複写 ( 分散 ) できる 「 hg clone  元ディレクトリ 新ディレクトリ」 やめるのも簡単:  rm -rf .hg/
まとめ Mercurial  を始めとする分散バージョン管理システムは以下のケースに強い 開発拠点の分散  ( オフラインの海を橋渡し ) 動作環境の分散  ( オフラインの海を橋渡し ) 動作ノードの分散 結果として以下の恩恵が得られる 履歴の連続性の確保 ツリー全体の同一性の保証 レポジトリ分散・バックアップによる破損回避 結論 SIer  こそは  Mercurial  を使え!

Mercurial はオフラインの海を越える

  • 1.
    Mercurial は オフラインの海を越える分散バージョン管理システムを 用いた高可用システムの 保守管理の試み
  • 2.
    バージョン管理システムとは ファイルや各種のデータなどの内容を修正したり変更した内容を記録するソフトウェア 変更に一段落がつく度に、新バージョンとして登録(commit) 修正差分を他のノードのソースへ展開する。 問題があった時に過去のバージョンに戻せる 今まで行ってきた修正が履歴として残る Repository 古いバージョンを保持しておく場所 管理対象のファイル群
  • 3.
    バージョン管理ソフトの歴史 RCS (RevisionControl System) 1 ファイル単位 修正目的は一つなのに、ファイルごとに履歴を書かなくちゃだめない ロック方式 誰からロックをかけちゃうと解除できない SI 開発ではよいが、不特定多数がパッチを作る OSS では不都合だった CVS (RCS を改良-> 一気に広まる ) ネットワーク連携 -> 中央集権型レポジトリ ディレクトリ単位で修正情報を登録 ロック方式排除 -> かわりにマージ機能 Subversion (CVS のいろんな不都合を修正 ) 余計なタグを埋め込まないので、バイナリでも安心 ファイルのリネームや移動をサポート ロールバック機能 ★ Subversion が世界を制するかのように見えた!
  • 4.
    なぜ CVS/Subversion では駄目なのか 全てのノードが オンラインであることを要求 SI 開発の場はそうではない 開発委託先と委託元 開発環境とテスト環境と本番環境 いずれも、オンラインで IP⇔IP でつながっていることは、まずありえない。 苦肉の策は、オンラインでつながっているイントラネットごとに別々にレポジトリを立てること!
  • 5.
    「苦肉の策」は、所詮「苦肉の策」 ファイルの移動は「 zip でくれ」 バージョンナンバーや変更履歴がたくさん 場所 ( 本番 / 開発 / 委託先 ) ごとに違う ファイルごとに違う ( 記録の手間が一括なだけで、それぞれ別に採番 ) ファイルの同一性の保証ができない ファイルの構成が異なっている時、どのファイルを展開したらよいか、マージしたらよいかを、人間が管理しなくちゃいけない Linus さんも駄目だと言ってる ★ これはもう破綻しているのではないだろうか
  • 6.
    イントラネット単位? いやいや、むしろ強気にノードごとにレポジトリを設置します ノードの設置場所がバラバラであるという「現実」を踏まえた設計それぞれのレポジトリの同一性が保たれていればよい。そのためには オフラインでもレポジトリを同期させる手段を提供できればよい。 双方のレポジトリが同一であることを保証できればよい バージョンナンバーは全体に対して、一つ採番すればよい 分散バージョン管理システムは答える 「レポジトリの分散? 上等!」
  • 7.
    分散バージョン管理システムにも いろいろあるけれど Mercurial(マーキュリアル ) とは サーバ不要 Python 2.3 以上 ( 日本語を変更履歴に残すなら、 2.4 以上 ) Mozilla Firefox , NetBeans などが採用 ライバルは Git( あっちは Linux Kernel が使ってる )
  • 8.
    Mercurial はオフラインの海を越えるbundle / unbundle バージョン差分を 1 ファイルに抽出する ― 「 bundle 」 USB メモリ・メールなどで、差分ファイルを輸送する 差分ファイルを宛先レポジトリへ反映 ― 「 unbundle 」 開発 Repository Rev.20 USB 丸 19 ~ 20 の差分 本番 (Rev.19) 本番 (Rev.20) 同期 ! $ hg bundle –base 19 ver19to20.hg $ hg unbundle ver19to20.hg
  • 9.
    同一性の保証 構成ファイルがなすツリー全体に対して、 一つのバージョン識別子― ChangeSetID 一つでもファイルが変われば、 全体のバージョンナンバーが変わる これで「ファイルの漏れ」が分かる ChangeSetID は通し番号ではなく、チェックサムみたいなもの 例:「 21: 4937b9f334ce 」 前半「 21 」は「単なる」通し番号 ( ノードによって違う ) 後半「 4937b9f334ce 」は一意性を示す ID つまり、 ChangeSetID が同じなら、 レポジトリは一致しているんだよ!!!
  • 10.
    Mercurial は真のバージョン管理を提供する ツリー全体の変更履歴をシーケンシャルに管理する 1 個でも変えたら、これに載る どれを変えたかも、ちゃんと載る ファイルの洩れが無いか、これで確認できる $ hg log | more changeset: 21:4937b9f334ce tag: tip user: [email_address] date: Wed Mar 19 18:25:34 2008 +0900 summary: 20080319_syukka_release changeset: 20:563c0f01b2ed user: [email_address] date: Tue Mar 18 16:58:12 2008 +0900 summary: * ks_limite_delte_pm : modify Makefile , remove files for schogedb because pm hogedb not need them. changeset: 19:8499441b8190 user: [email_address] date: Thu Feb 28 17:22:54 2008 +0900 summary: * sequence list for rebuldsyn.rb changeset: 18:84487d3f3286 user: [email_address] date: Thu Feb 28 17:22:04 2008 +0900 summary: * add export sequence script 'exp_sequences.sql'
  • 11.
    クラスターに応用してみた クラスターは双方のノードで、同じ挙動を保証しなくてはならない。 が、共有ディスクに何もかも置くわけにはいかないTAKEOVER 時に、ディスクの受け渡しに失敗するリスクが増す だから、 DB など動的に変わるデータしか置くべきでない 1 号機と 2 号機の構成の同期は永遠の課題 ⇒ 分散バージョン管理システムで同期する
  • 12.
    Mercurial とクラスター 1 号機で修正 1 号機で 「 hg commit 」 1 号機から 2 号機へ「 hg push 」 2 号機で 「 hg update 」 (2 を行うと 3 ~ 4 を自動化するのも可能 ) レポジトリ レポジトリ 1 号機 2 号機 $ hg commit $ hg push or $ hg pull $ hg update
  • 13.
    どこでも MercurialMercurial はチェックアウトしたディレクトリのルートに .hg という隠しディレクトリを作るだけなので、どこでも管理しやすい。 というわけで、あるシステムは全てを Mercurial 管理にした ソース , スクリプトディレクトリ /etc ※ , /usr/local/dncware_scripts $ORACLE_HOME/dbs/ , $ORACLE_HOME/network/admin/ ※ cron 定義ファイルとか設定ファイル管理 別に同期させる必要はなくても、変更管理はしたいよね IP アドレスを含むディレクトリ (※) は同期させてはいけない 簡単に「ワークディレクトリ」と「レポジトリ」を複写 ( 分散 ) できる 「 hg clone 元ディレクトリ 新ディレクトリ」 やめるのも簡単: rm -rf .hg/
  • 14.
    まとめ Mercurial を始めとする分散バージョン管理システムは以下のケースに強い 開発拠点の分散 ( オフラインの海を橋渡し ) 動作環境の分散 ( オフラインの海を橋渡し ) 動作ノードの分散 結果として以下の恩恵が得られる 履歴の連続性の確保 ツリー全体の同一性の保証 レポジトリ分散・バックアップによる破損回避 結論 SIer こそは Mercurial を使え!