目次


名称

  • xpdk
  • xenowire pukiwiki decentralization kit
  • ゼノワイア PukiWiki 分散化キット


概要

PukiWiki を、異なるネットワーク上にある複数サーバで分散運用するためのキットです。
BugTrack/763 - PukiWiki-dev の rsync とは違う方法で分散します。

背景

物理的に隔絶されている安価なレンタルサーバを束ねて使用するために開発されました :D

サンプルサイト

xpdk_d.xenowire.net.png
  • http://d.xenowire.net/
    • 使用データ : 2009 年 07 月 01 日〜 2009 年 07 月 28 日
    • 費用対アクセス : 約 250 PV/円
    • 費用合計 : 約 400 円/月
    • PukiWikiデータ
      • ページ数 : 1773 ページ
      • AutoLink : 有効 (3 bytes)
      • robots : index, follow
    • アクセス数
      • クローラ除く : 約 90,000 PV/月
      • クローラ含む : 約 100,000 PV/月
      • 製薬・医療系企業 30%, 大学・病院・研究機関等 45%, 行政機関等 5%, 一般 13%, 一般(携帯端末) 7%
    • アクセス傾向
      • 営業日/平日、朝〜夜にかけて高負荷
      • 夕方〜早朝にかけて携帯端末のアクセスが顕著
    • 付加スクリプト等
      • 各ページの vispup のため PukiWiki データパースとレスポンス生成
  • マスター 1 つ
  • スレーブ 1 つ
  • マスターとスレーブは異なる SP 所管
  • マスターとスレーブは異なる AS 所管
  • DNS ラウンドロビン


xpdk 構成例

xpdk_1master_3slaves.png
  • マスター 1 つ
  • スレーブ 3 つ
  • DNS ラウンドロビンにより、ユーザーは xpdk を意識することなく利用




xpdk_2master_2slaves.png
  • マスター 2 つ (各々スレーブ兼任, うち 1 つはバックアップ)
  • スレーブ 2 つ
  • DNS ラウンドロビン




xpdk_1master_2slaves_nodns.png
  • マスター 1 つ
  • スレーブ 2 つ
  • 各サーバーへは違う URL でアクセス


特徴

  • サーバ負荷分散
    • マスター・スレーブ構成
      • 複数のスレーブサーバを指定可能
      • 複数のマスターサーバを指定可能
      • マスターとスレーブの兼任可能


  • ネットワーク負荷分散
    • 異なる場所にある ( 異なるネットワーク上にある )PukiWiki の同期が可能
    • [ 1 ネットワーク ] 対 [ n サーバ ] + [ ロードバランサ ] のような、
      ネットワーク負荷の集中しない構成が可能
      ( 同じネットワーク上にある PukiWiki の同期も無論可能 )


  • 冗長性
    • いずれかのサーバが動作していれば閲覧可能
    • いずれかのマスターサーバが動作していれば編集可能
      • スレーブを編集しようとした場合、自動的にマスターに転送
    • Alive チェックにより、ダウンしているサーバは無視


  • 即時性
    • マスターの更新は即時全スレーブへ
      • マスターに投稿される POST データをスレーブに転送
      • rsync 等ファイルレベルでの同期は利用しません


  • ファイアウォール ポリシーへの依存度の低さ
    • 同期には Outbound HTTP/HTTPS のみ使用


  • 共用レンタルサーバでも負荷分散可能


動作に必要な環境

  • PukiWiki
  • PHP4以上
  • 各サーバを識別できるホスト名
  • スレーブには編集ロックのため PukiWiki の edit_auth


問題点

  • マスターが複数ある場合、マスター同士での更新の衝突の検出ができない
    • マスター同士の更新の衝突は無視する?
  • DNS ラウンドロビンと組み合わせる場合、ダウンしているサーバーの検出ができない (DNS ラウンドロビンの問題)
    • Alive チェック用スクリプトを用意し独自の負荷分散をする?
    • レンタルサーバのダウン率は低いので問題なし?


ToDo

  • パッチ作業を必要最低限にし、導入を容易にする
  • ユーザーによるアクセスをトリガとしてマスターをチェックし、サーバダウン中に更新されたデータがあれば取得、適用する


ファイル構成 (xpdk 0.1.3)

pukiwiki_root/
├index.php ( パッチ )
├syncconf.php - 同期設定ファイル
├syncfunc.php - 同期に使用される関数など
├syncrecv.php - 受信用スクリプト
├syncsend.php - 送信用スクリプト
├lib/
│├auth.php ( パッチ )
│└html.php ( パッチ )
└plugin/
 ├edit.inc.php ( パッチ )
 ├freeze.inc.php ( パッチ )
 ├newpage.inc.php ( パッチ )
 ├rename.inc.php ( パッチ )
 └unfreeze.inc.php ( パッチ )


状態

  • 開発中
  • 試験運用中
  • 公開予定

案とメモ

  • index.php への POST をリモートの index.php に転送するだけでいいかも?
    • プラグインに個別にパッチを当てる必要がない
      • lib/edit.php だけはダイジェストチェックがあるのでパッチ必要
    • 転送する cmd または plugin を指定
      • search プラグインの POST は転送しない
    • 転送がループしないように SERVER_ADDR チェック
    • PukiWikiの管理パスワードを同一に設定
    • POST 転送元の検証
      • REMOTE_ADDR
      • 同期用パスワードの設定 ( 転送元が POST に混ぜて送る )


各サーバに配置する xpdk.php :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
<?php
    //
    // 設定 {
    //
    // 実装時には設定は別ファイルにして xpdk_sync() で include する
    //
 
    // サーバIPアドレス => PukiWiki への連想配列
    $g_xpdk_svs = array
    (    '000.000.000.001' => 'http://pkwk1.xenowire.net/index.php'
    ,    '000.000.000.002' => 'http://pkwk2.xenowire.net/pukiwiki/index.php'
    ,    '000.000.000.003' => 'http://editor:editor@pkwk3.xenowire.net/pukiwiki/index.php'
    ,    '000.000.000.004' => 'https://pkwk3.xenowire.net/pukiwiki/index.php'
    );
 
    // 同期用パスワード
    $g_xpdk_pass = 'xpdkpassword';
 
    // 転送する cmd または plugin の指定
    $g_xpdk_cmds = array
    (    'edit'
    ,    'rename'
    ,    'freeze'
    ,    'unfreeze'
    );
 
    //
    // } 設定
    //
 
    // 同期用関数
    function xpdk_sync()
    {
        global $g_xpdk_svs, $g_xpdk_pass, $g_xpdk_cmds;
 
        // リクエストのチェック
        if( count( $_POST ) == 0 )
            return;
 
        //
        $args = array_merge( $_GET, $_POST );
 
        // 転送する cmd または plugin のチェック
        if(    !in_array( $args['cmd'], $g_xpdk_cmds )
        &&    !in_array( $args['plugin'], $g_xpdk_cmds )
        )
            return;
 
        // ブラウザからの POST であれば他サーバに転送
        if(    $args['xpdk_pass'] != sha1( $g_xpdk_pass )
        ||    !array_key_exists( $_SERVER['REMOTE_ADDR'], $g_xpdk_svs ) 
        )
        {
            // 他サーバに転送
 
            // 同期用パスワードを混ぜる
            $_POST['xpdk_pass'] = sha1( $g_xpdk_pass );
            
            // 転送
            foreach( array_keys( $g_xpdk_svs ) as $ipa )
            {
                // 自分には転送しない
                if( $ipa == $_SERVER['SERVER_ADDR'] )
                    continue;
                
                xpdk_post( $g_xpdk_svs[ $ipa ], $_GET, $_POST );
            }
        }
    }
 
    // $u + $g に $p を POST する関数
    function xpdk_post( $u, $g, $p )
    {
        // 実装済みなので省略
    }
?>


各サーバの index.php に追記 :

  1
  2
  3
  4
  5
  6
<?php
 
    include 'xpdk.php';
    xpdk_sync();
 
?>

トップ 編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード 新規 一覧 単語検索 最終更新 リンク元 ヘルプ 最終更新のRSS xenowire
Last-modified: Thu, 17 Dec 2009 18:37:13 JST