関西オープンソース 2008 30days albumの裏側
TRANSCRIPT
関西オープンソース 2008
(株) paperboy&co.
宮下 剛輔2008/11/7
アジェンダ 自己紹介 30days Album 紹介 サーバソフトウェアまわりの話 運用まわりの話
自己紹介 宮下 剛輔と申します (株) paperboy&co. で技術責任者とい
うのをやってますナウでヤングなレンタルサーバ ロリポップ!の会社です
個人的にはmizzy.org の中の人Perl プログラマの人Puppet の人ドクターペッパーの人
30days Album http://30d.jp/ オンラインアルバムサービス 30 日間限定
30 日経過すると閲覧できなくなるその後 10 日間アーカイブダウンロードができる
40 日経過後、完全に削除 合い言葉制
合い言葉を知ってる人だけ閲覧できる合い言葉を知ってる人なら誰でも投稿できる
シンプルなインターフェースあまりコンピュータ詳しくない人がターゲット
30days Album 誕生の経緯 社内プレゼン大会で優勝したアイデア
プロジェクトキックオフ飲み会でホルモン喰いながらドメイン名( 30d.jp )を決定して即取得(もちろんムームードメインで)
開発合宿(お産合宿)で実装開始
30days Album の開発体制 デザイナ 1 人 開発 3 人
フロント Web アプリストレージ APIジョブサーバ API +ジョブワーカー
サーバ周り 2人
30days Album 全体構成
リバースプロキシ
Web アプリ 画像ストレージ
ジョブサーバ データベース
リバースプロキシ
リバースプロキシ
Web アプリ 画像ストレージ
ジョブサーバ データベース
リバースプロキシ サービスの入り口 Perlbal
Perl 製のリバースプロキシ / ロードバランサーPerl でプラグイン書いて機能拡張できる
2 台で DNS ラウンドロビン ウェブアプリと画像ストレージへの振り分
け / 負荷分散 3 つの独自プラグイン
SSL 接続か否かをウェブアプリへ通知画像アクセスに対する認証URL マッピング
リバースプロキシ
リバースプロキシ
Web アプリ 画像ストレージ
ジョブサーバ データベース
http://30d.jp/img へのアクセスhttp://30d.jp/img 以外へのアクセス
Web アプリ
リバースプロキシ
Web アプリ 画像ストレージ
ジョブサーバ データベース
Web アプリ サービスの中心部分
アルバム作成 / 閲覧 / 投稿認証(メールアドレス / パスワード、合言葉)
Ruby on Rails + lighttpd + FastCGI SWFUpload BackgrounDRb
表示用サムネイル生成 ジョブサーバへの画像処理ディスパッチ
リサイズローテートアーカイブ
なぜ Ruby on Rails なのか? うちは PHP がメイン 初の Ruby を使ったサービス なぜ Ruby なのか?
それメインプログラマが Ruby 好きなのでそれだけです
開発者が一番好きな言語で開発するのがモチベーション向上には一番
画像ストレージ
リバースプロキシ
Web アプリ 画像ストレージ
ジョブサーバ データベース
画像ストレージ MogileFS + 独自のストレージ API MogileFS
Perl 製の分散ストレージシステム複数ノードへの自動振り分け自動レプリケーション
ストレージ APIMogileFS は専用クライアントライブラリが必要HTTP GET/PUT で画像の出し入れCatalyst + lighttpd + FastCGIConten-Type や Content-Length の管理
ストレージ API + MogileFS
ストレージ API
tracker(mogilefsd)
トラッカー DB
(MySQL)
storage node(mogstored)
storage node(mogstored)
ストレージノード
(mogstored)
トラッカー(mogilefsd)
ファイルの実体
ファイルのメタデータ
ストレージノード
ストレージノード
Perlbal 経由の画像取得(通常)
Perlbal
ストレージ APIストレージノード
ファイルリクエスト
ファイル取得
ファイルの内容を返す
X-REPROXY-URL ヘッダ 画像の取得をストレージ API 経由でや
るのは効率が悪いFastCGI プロセスを画像転送だけで占有してしまう
そこで画像取得時に、画像データではなく、 X-REPROXY-URL ヘッダをPerlbal に返すヘッダの値は MogileFS のストレージノード上にある、ファイルの実体を示す URL
ストレージノード
ストレージノード
X-REPROXY-URL ヘッダを使う場合
Perlbal
ストレージ APIストレージノード
ファイルリクエスト
X-REPROXY-URL:http://storage_node/dev1/0/000/...
X-REPROXY-URL ヘッダをもとにファイル取得
画像ストレージのディスク構成
/boot swap / /data
RAID1
/boot swap / /data
RAID1+LVM LVM
500GBx2 本 /boot は RAID1 swap, / は RAID1+LVM /data は LVM で 1 パーティションに見せ、
大きく使う
画像ストレージのサーバ構成
ストレージ API
mogilefsd
mogstored
ストレージ API
mogilefsd
mogstored
リリース時はサーバ 2 台 API 、トラッカー( mogilefsd )、スト
レージノード( mostored )が共存 MogileFS の機能により、 2 台のサーバ
は同じデータをストア
画像ストレージのサーバ構成
ストレージ API
mogilefsd
mogstored
ストレージ API
mogilefsd
mogstored
現在は 4 台 追加した 2 台はストレージノードとし
ての役割のみ アプリケーションの修正やサービスの再起動を全くせずに拡張できた
mogstored mogstored
画像のアクセスコントロール Web アプリ
最初の認証は必ずここメールアドレス / パスワード合い言葉認証後、セッションキーとアクセス可能なアルバムの相対 URL を memcached にセット
リバースプロキシWeb アプリが memcached にセットした情報を元に、画像へのアクセスコントロールを実施
画像のアクセスコントロール
Perlbal
Web アプリ 画像ストレージ
memcached
認証時に、セッションキーとアクセス可能なアルバム名をセット
セッションキーを元に、アクセス可能なアルバム名を取得して、リクエストを許可 /拒否
認証
画像取得
ジョブサーバ
リバースプロキシ
Web アプリ 画像ストレージ
ジョブサーバ データベース
ジョブサーバ Gearman + TheSchwartz +独自のジョブ API Gearman
Perl でできたジョブキューリアルタイム性が高いステータス管理しない
TheSchwartz Perl でできたジョブキュー MySQL でキューを管理リアルタイム性が低いステータス管理、リトライ
ジョブ API Catalyst + lighttpd +FastCGI XMLRPC でジョブ処理を受け付け後ろの Gearman, TheSchwartz へジョブ依頼
ジョブサーバの構成
ジョブ API
gearmand
gearman worker TheSchwartz worker
MySQL
ジョブの種類 Gearman
リアルタイム性の高い処理アルバムを表すサムネイル画像の回転
TheSchwartzリアルタイム性の低い処理画像リサイズアーカイブ作成
Ruby + memcached
Ruby Memcache Clientが、 memcached にデータをセットする際に、デフォルトで marshal する
Perlbal で memcached からデータを取得すると、なんかゴミが入ってる
オプションで marshal しないように設定して回避
mogstored + lighttpd
mogstored は WebDAV サーバデフォルトは Perlbal がバックエンド設定で Apache や lighttpd をバックエンドにすることができる
Perlbal だと不安定で lighttpd に変更 mogstored で保存されるファイルは、
ディレクトリが階層化されている/data/dev1/0/005/090/0000000012.fid
mogstored + lighttpd (つづき) Perlbal がバックエンドの時は、存在し
ないディレクトリにファイルを PUT しても、勝手につくってくれる
Apache や lighttpd の場合はエラーになる
MogileFS::Client に手を入れて修正PUT しようとするディレクトリの存在を確認し、存在しなければMKCOL
Perlbal の Out of memory リバースプロキシの Perlbal が頻繁に落
ちるログには Out of memory! のみ
DEBUGGING オプションつけて Perl をコンパイル
Danga::Socket の以下の行で発生してると判明my $res = sysread($sock, $buf, $req_bytes,
0);$req_bytes を小さくして対応
Puppet Ruby 製のシステム管理ツール クライアント / サーバ型 サーバの状態を独自言語で定義
マニフェストと呼ばれる マニフェストは Puppet サーバで一元管
理 各サーバで Puppet クライアントを動か
し、マニフェストを適用してサーバ構築や設定変更を行う
Puppet マニフェスト
package { ‘MogileFS-Server’: ensure => present; ‘MogileFS-Server-mogilefsd’: ensure => present; ‘MogileFS-Server-mogstored’: ensure => present;}
Puppet の構成
Puppet サーバ(puppetmasterd)
Puppet クライアント(puppetd)
Puppet クライアント(puppetd)
Puppet クライアント(puppetd)
マニフェストの取得と適用
実行結果のレポート
プロトコルは XMLRPC over HTTPS
Puppet によるサーバ構築 OS インストール ネットワーク設定 Puppet インストール Puppet 実行 完了
Puppet マニフェスト 独自の宣言型言語でサーバの状態を記述
プログラミング言語ほどの自由度はない自由度がないぶん、人による差異が出にくい
サーバの状態をテキスト形式で記述Subversion等で管理できる誰がどういう変更を行ったのか、追跡しやすい
Archer
Perl 製のデプロイツールCapistrano みたいなやつ
モバイルファクトリの松野徳大さん(id:tokuhirom) が開発
プラグインで拡張が簡単 YAML で動作を定義
Archer 設定ファイルtasks: init: - module: SVN::Update process: - module: Rsync - module: Exec::Remote config: command: /etc/init.d/lighttpd
restartprojects: days: storage_api: - storage1.30d.jp - storage2.30d.jp
対象サーバ対象サーバ
Archer の動作イメージ
Subversion
デプロイサーバ
対象サーバ
① archer.pl –c days.conf
② svn up
③前処理
④ rsync
⑤ 対象サーバ上で後処理( SSH でコマンド実行)
Days での Archer の使い方 プログラムのアップデート
プログラム修正して svn coarcher.pl –c program.conf
Puppet マニフェストのアップデートマニフェストを修正して svn coarcher.pl –c manifest.confpuppetmasterd の再起動も archer コマンド一発
独自 yum サーバ上の RPM パッケージアップデートパッケージをアップデートして svn coarcher.pl –c yum.confcreaterepo の実行も archer コマンド一発
OpenLDAP
社内で利用SSH ログインSubversion 認証Trac 認証
30days Album でも利用SSH ログインPuppet ノード管理
社内の LDAP データと同期独自の同期スクリプト
OpenSSH + LPK patch
LDAP Public Key patch $HOME/.ssh/authorized_keys の代わり
に、 LDAP 内の sshPublicKey属性を参照
各サーバに authorized_keys を配布しなくても、 SSH の公開鍵認証ができる
LPK patch 用 LDIF
dn: uid=mizzy, ou=people, o=paperboy
objectclass: ldapPublicKey
sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwq
XqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64k
APxjU9KSqIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzR
mT28I5piGzunPv17S89z8XwSsuAoR1t86t+5
dlI7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52
N/kKLG3ciBkBAw==