大規模ブログサイト「DECOLOG」の開発・運用ノウハウを公開します。

利用特性に合わせたシステムを構築しよう

»

 こんにちは、hiroshiです。 自分のことをhiroshiとかアルファベットで表現すると、軽く有名人っぽくて気分がいいです。みなさんもぜひやってみてください。

 さて、以前ITmediaさんで、DECOLOGの画像配信の仕組みについて紹介させていただきました。 あの仕組みは「デコメで投稿される記事に使われている画像」の特性から現状のあの構成になりました。

 一方、DECOLOGで扱われる画像はもちろん記事画像だけではありません。 代表的なものに、ブログTOP画像というものがあります。

 ブログTOP画像は、その名の通りブロガーのみなさんの“顔”ともいえるブログのTOPページを飾る画像です。

図1.ブログトップページサンプル

 上図のとおり、ページ上部に配置される画像であるため、携帯画面でのファーストビューはこのブログTOP画像で占めらる割合が大きいです。 つまり、「ブログTOP画像=ブロガーのみなさんの顔」といっても過言ではなく、少しでも早く表示させたい画像なわけです。

 さて、、こちらで、記事画像配信の仕組み変遷の歴史画像を掲載していますが、あれの3代目まではこのブログTOP画像も同じパケットのフローに乗っていました。違っていたのは、一番下のDBだけです。

 しかしながらブログTOP画像と、記事画像では大きな違いが2点あります。

  1. アクセスの頻度が違う。記事画像は時間が経てばが落ちるが、ブログTOP画像は一定
  2. データ量が違う。記事画像は際限なく増加するが、ブログTOP画像は仕様上、ブログ開設数×2が上限

 1から、アクセス頻度がロングテール化する、記事画像のようなアーカイブ方式はそぐわないことが分かります。 このように、大きな違いを持つ2種類の画像が共存していたため、squidのキャッシュ効率も悪く(たぶん)、ブログTOP画像の表示がもっさりする、登録しても反映が遅い(=replication delayの発生)ことがしばしばありました。

 なので、「まずブログTOP画像をなんとかしよう!」ということで対策会議を開きました。といっても技術責任者のstoneと2人でベランダでタバコすいながら「なんかいい方法ないっすかねー」みたいなノリでしたけど。 で、いろいろ議論を重ねた末に、「とりあえずこれでやってみっか!」となったのが下図の構成です。

図2.ブログトップ画像構成

 Before、Afterでの大きな違いは、画像の保持方法を動的(DB管理)から静的(FS管理)に変えたことです。 2の「データ量が違う」ということから、inodeの枯渇の心配もないことが分かり、だったらDBにぶち込まないでそのまま置いといたほうが早くね? ということでそうしてみました。

 画像サーバは読み取りと書き込み用にポートを分けておき、書き込み用には画像を受け取る用のPHPスクリプトを置いておきます。

 書き込み処理の流れを追ってみます。ブログトップ画像の登録はメール送信で行われます。

  1. qmailで受け取ったメールはパイプ処理でPHPプログラムに渡す
  2. phpでメールの中身を解析し、画像ファイルの取り出し・加工処理などを行った後、
  3. DBにぶち込み、
  4. HTTPでブログIDをキーに決められた格納先画像サーバとバックアップ用画像サーバにPUTする

 PUTと言っても、単純にrequestに画像データをぶち込んで画像サーバの81に向けて特定のURLを呼び出すだけです。

 methodとしてのPUTを使ってみる方法(WebDAVとかを使うんだったけかなあ?)も試行錯誤してみたんですが、作業を担当したのが2流の僕なのですぐ音を上げました。「stoneさん、これムリっす!」「じゃあ、あと1時間だけ挑戦してダメだったらやめよっか」やっぱりだめでした……。

 言い訳っぽいのですが、あのまま試し続けていればカッコいい方法が実現できたかもしれません。ただ、慣れてない方法でやるよりも、シンプルかつ自分が完全に理解できている方法でやった方が、トラブル時などの対策案も多々浮かんできます。それになにより、人がいないので、方針を決めたら作業完了までの工数が読めない方式は取りたくない、というのもありました。

 一方で、どこかで新しいことやモノに挑戦していかないと手元のカードは増えません。状況に余裕があるときであれば、新しい手法・試したことのない手法はどんどん突っ込んでいくべきだと思います。

 ということで、まあ当時は余裕がなかったんです。

 さて、話を元に戻します。 ユーザーから送られてきた画像は、3個所に書き込まれます。もちろん理由があります。 内訳はDB1個所に画像サーバ2個所。

 画像サーバ2個所に書き込んである理由はすぐ分かります。画像サーバがぶっ壊れたらすぐ代替と交換できるように、そうしてます。なので、バックアップ用サーバはすべての画像を保持しています。

 DBに書き込んでいる理由も、やっぱり画像サーバがぶっ壊れたときのためです。 どこかの画像サーバがぶっ壊れても、バックアップサーバを突っ込めばサービスとしては問題ない状態になりますが、その間に復旧作業をしなければなりません。

 バックアップ用サーバからrsyncで、とかもちょっと考えましたが、普及中もユーザーによる追加/更新が行われ続けるため、完全に同期がとれるのかがすごく疑問でした。また、その検証方法も思いつきませんでした。

 一方、DBで持っておけば、その辺の取り回しはいくらでも融通が効くので、復旧用のスクリプトさえ用意しておけば数時間で普及できる計算が成り立ちました。ということでDBにも書き込んでいるわけです。

 読み込み処理の流れはシンプルです。URLにその画像がどの画像サーバにあるかが分かるようになってるのでmod_proxyで振り分けるだけです。

 この仕組みは想定どおりの結果が得られ、今でも非常に安定して稼働しています。

 本当は、既存の仕組みから新しい仕組みに切り替えるときに発生する「移行」についてもいろいろ工夫してきた話があるのですが、これはまた後日にさせてください。

 では、また次回に会いましょう。

Comment(0)