GMO Pepabo, Inc.
Ryo kuroda @lamanotrama
2015/08/29 第3回ペパボテックカンファレンス
MogileFS
をバックエンドとした
Private S3の作り方
黒田 良 @lamanotrama
> 技術基盤チーム
> インフラ担当
前半 (自分)
• 全体アーキテクチャ
• インフラ
後半 (@hiboma)
• APIアプリケーション
前半アジェンダ
> 何故Private S3?
> アーキテクチャ
> 大規模MogileFSの運用
> Gatewayの仕組み
> データインポート
何故Private S3
全社的にサービスインフラを
オンプレミスから
Private Cloud(Open
Stack)に移行
課題
静的コンテンツの保存、配信
> 主に画像
> 容量がそれなりに大きい
> 各サービスがそれぞれ違った仕組みで独自に構築している
> Nyah(IaaS)上に各サービスが再構築するのは非効率
> 可用性
> スケーラビリティ
> 構築、運用コスト
→ 求められる大統一オブジェクトストレージサービス
ペパボのオブジェクト
ストレージと言えば
30days Album
30days Album
> 2008年リリース
> 大規模分散オブジェクトストレージ
> perl製のMogileFSを使用
> 総容量: 750TB
> 累計オブジェクト数: 22億
高いデータ耐久性、稼働率
> 7年間でデータロストは一回(4個)
> (不幸なレア条件が重なったため。鋭意シス
テム改善中!)
> 計画メンテを除いたサービスダウンは
ほぼ無い
> (以前は不安定な時期もありました)
vs OpenStack Swift
OpenStackにもオブジェクトストレージを提供するコンポー
ネントはあるが…
> 大規模分散オブジェクトストレージを安定運用するのは甘
くない
> 30days AlbumのMogileFSは十分に安定している
最初からS3互換APIを備えているというメリットはあるが、
長い目でみるとそこの開発コストは十分相殺されると考えた。
vs AWS S3
フルマネージドのS3でいいじゃん?
> 容量や転送量のコスト面でオンプレの方が明ら
かに優位
> 同程度の規模だと容量課金のみで数百万円/月
> 長年のノウハウ蓄積によってMogileFSの運用
コストはかなり下がった
名称
ペパボストレージ
名称
ペパボストレージ
Bayt
アーキテクチャ
30days
30days + Bayt
Bayt
①
②
1. gateway
> Nginx + ngx_mruby
> インターネット、インターナルからリク
エストを受ける
> http(s)://<bucket_name>.hitmitsu.no.domain/
> http://bayt.30d.lan/<bucket_name>/
> apiにproxy
> apiだけでは出来ないあれこれ(後ほど)
2. api
> Rails + Unicorn
> mogilefsd、メタデータdbとのや
りとり
> 詳細は後半で
この2つを作れば
基本的にはOK
と、その前に
既存システムコンポーネントの
強化、安定化
安定稼働しているとはいえ、全社的
に使うには心もとない部分もある
メトリクスの充実化、可視化
storageサーバの高集積化
自作サーバ期など、紆余曲折を経て
今は/dev/sdarまであるみっしり筐体がメイン
DB(MySQL)サーバのリプレース
> 2台→3台 (総入れ替え)
> MySQL5.1→MySQL5.5
> MHA導入
短時間のダウンタイムを許容できるなら2台
でもいけなくはない。
が、メンテナンス性がとにかく悪い。
mogilefsdクラスタの強化
負荷が高くなるのは明白なのでスペッ
クアップ&台数++
問題発生
mogilefsdがスケールしない
mogilefsdはマスタープロセスからワーカ
を生やすpreforkモデル
_ mogilefsd
_ mogilefsd [monitor]
_ mogilefsd [replicate]
_ mogilefsd [replicate]
_ mogilefsd [replicate]
_ mogilefsd [replicate]
_ mogilefsd [queryworker]
_ mogilefsd [queryworker]
_ mogilefsd [fsck]
_ mogilefsd [fsck]
_ mogilefsd [reaper]
_ mogilefsd [delete]
…
mogilefsdがスケールしない
子が少ないうちは大丈夫
mogilefsdがスケールしない
増やすと親が子からのメッセージに応答し
なくなる(約700プロセスを境に)
❌ ❌
❌
mogilefsdがスケールしない
スループットが大幅に低下。
困った。
❌ ❌
❌
mogilefsdがスケールしない
親に気合をいれてみた。
renice -20 -p 親
❌ ❌
❌
mogilefsdがスケールしない
元気でた。
副作用
mogilefsdサーバがコンスタントに高負荷で
落ちる。
1. 稀に子の調子がわるくなり、親から殺される
2. 新しく生まれた子は-20の子なので-20
3. 過負荷で不安定になる
4. 更に子が死ぬ
5. -20っ子がモリモリ増える
6. もう無理
過剰なやる気
mogilefsd起動直後と、その後もこ
まめにcronで親子のnice値の面倒を
みることで解決。
(もうちょい綺麗になんとかしたい…)
DB刺さる問題
1. MySQL5.5化以来、コンスタントにDBが刺さる
(デッドロック)
2. 負荷がじりじり上がる
3. MHAマネージャからのヘルスチェックがコケて、
自動でマスターフェイルオーバー
4. 復旧
入れててよかったMHA…とか言ってる場合ではない。
雑に解決
> クエリの実行計画が変わったことで、元々使わ
れていなかったindexが使われるようになった
ことが原因
> mogilefs.file_to_replicate nexttry
> 要らんからdrop
色々調査、検証したけど長くなるので省略…
既存の画像配信の品質向上
Bayt GWの仕組みと共通するため、まずは既存(30days)の画像配信周り
(Nginx)の改善。
> Keep Alive (client - nginx - unicorn)
> Last-Modifiedヘッダ取り回しのバグ修正
> TLSオプティマイズ
> upstream、reproxyのフォールバック設定見直し
> storage(WebDAV)サーバのメモリバッファ上限引き上げ、worker数の調整
等などで、
30%程度高速化。レスポンスタイム、スループットの安定化。
@cubicdaiya さんの資料が大変参考になりました。
https://speakerdeck.com/cubicdaiya/nginxfalsepahuomansutiyuningu
gateway
(再度構成図)
実URLへのreproxy処理
gw
api
storage
実URLへのreproxy処理
GET http://mybucket.domain/a/b.jpg
GET http://192.168.1.3/a/b.jpg
Host: mybucket.domain
gw
api
storage
実URLへのreproxy処理
X-Accel-Redirect: /reproxy
X-Reproxy-URL:
http://192.168.1.4/dev1/123.fid
http://192.168.1.6/dev8/123.fid
gw
api
storage
実URLへのreproxy処理
gw
api
storage
GET http://192.168.1.4/dev1/123.fid
実URLへのreproxy処理
gw
api
storage
❌
実URLへのreproxy処理
gw
api
storage
GET http://192.168.1.6/dev8/123.fid
実URLへのreproxy処理
gw
api
storage
1. apiへproxy
2. 内部リダイレクトとproxy
3. 2つ目のURLへフォールバック
ややこしいけど便利
apiに届かなかった場合のエラードキュメント
S3互換にしないとクライアントで困る。
bodyだけでなくstatus codeも。
ngx_mruby
の活用
Serverヘッダ変更
Server: Bayt で帰ってくるとかっこいい。
(add_headerディレクティブでは変更できない)
リクエストUUID(ぽいもの)の発行
Railsまで届かなかった場合でもclient、gw、apiでユ
ニークなリクエストIDを共有する為にgwで発行。
apiでHMAC認証をskipさせるヘッダを付与
特定の条件を満たすリクエスト
> internalリクエスト
> 認証未対応のクライアントからの特定バケットへのリクエスト
(S3とは関係ないBayt独自仕様)
ngx_mrubyのオーバーヘッド
ほぼ無い(実質的に問題にならない)
リクエストトータル
で掛かった時間
(mrubyの処理が介
在しない)upstream
へのリクエストのみ
で掛かった時間
太らない
活発な開発。劇的改善。@matsumotory ++
(スパイクはNginxと関係ないバッチ処理によるもの)
ngx_mruby v1.12.14
既存データの
import
S3互換なので
> 既存のS3クライアント実装をそのままつ
かえる
> 某サービスの場合だと画像サーバ上のデー
タpathをそのまま s3cmd sync
DBメンテ祭り
import検証中に発覚した問題への対応。
> ETag(md5値)保存用のカラム追加
> インデックスの追加
> path(object key)カラムのサイズを255→512に変更
> pathをcase sensitiveにする為にcollationを変更
約9億レコードのテーブルへのALTERで最長25時間。
MHAのオンラインマスター切り替えを利用したメンテナンスで
全てサービスダウンタイムは無し。
粛々とインポート、移行
> 適当な単位でCDNからのOrigin指
定を切り替え
> 3TB、1億オブジェクトを移行済
絶賛安定稼働中
今後
> 全サービスのデータを移行
> マルチロケーション(DC)化
> ディザスタリカバリ
> サービスエンドポイントの冗長化
> 動的画像リサイズ機能
> URLパス、クエリパターンで動的にリサイズ、
配信
以上。後半に続く。
API編 by @hiboma

MogileFSをバックエンドとしたPrivate S3の作り方