グリーの大規模分散ストレージ戦略(nanofs)

はじめに

はじめまして、グリー株式会社でエンジニアをしておりますkgwsと申します。今回は、グリー内で写真データの保存を行っている分散ストレージ(nanofs)を紹介させていただければと思います。

背景

弊社で運営させていただいている "GREE" ではユーザの写真や動画データを保存することができます。1億ユーザを目指すグリーは、ユーザの増加とともに写真や動画データは上限なしに増加していきます。またユーザの皆様の大切なデータを失うことは許されませんし、サービスを止めることも許されません。そんな状況の中、様々な技術や仕組みを使いサービスを運営してまいりました。
グリーのストレージの歴史は大きく分けて3世代がありました。

第一世代

第一世代ではアプリケーションサーバからNFSサーバをマウントし画像データを保存しておりました。簡単に導入できることと高価なサーバを使用すれば信頼性や安定性も保たれるので利用しておりましたが、アプリケーションサーバへのトラフィックが増加するとNFSへのトラフィックが増え、結果としてNFSサーバのパフォーマンスが低下してしまいました。より高価なNFSサーバを導入すれば解決できるのですが安価なサーバでスケールアウトする仕組みを導入しない限りエンドレスに高価なサーバを買いつづけなければいけないため早い段階で第二世代に移行されました。

第二世代

第二世代ではまずユーザ毎にパーティションを設定し1パーティションに対し2台のwebDAVサーバにダブルライトする仕組みを取り入れました。このことにより比較的安価なサーバでスケールアウトすることが可能となりサーバ費用を圧縮することができました。しかし、ユーザの増加とともにパーティション数を増やさなければいけなくなり多くのwebDAVサーバを構築し運用しなければいけなくなるため、運用コストの増加が問題となりました。
スケールアウトしてサーバが増えることは必ずしもよいことではありませんでした。
サーバが増えることは壊れる可能性が増えユーザの皆様にご迷惑をおかけすることにつながります。大規模サービスではスケールアウトする仕組みを導入することは重要なのですが同時に運用コストを減らしていかないとサーバの構築だけで一日が終わってしまいます。

第三世代

第三世代では、第二世代の仕組みに加え高価なサーバを購入することにより1台のサーバでより多くのユーザを処理できるようにパフォーマンスを向上させました。同時に1台のサーバ内の複数のHDDに画像データを保存するため信頼性を向上し、また多くの画像を保存できるためサーバの台数を減らすことができました。しかし1台のサーバへのトラフィックが上がりwebDAVサーバのアプリケーションが処理しきれなくなってしまいました。ある程度はアプリケーションのチューニングにより改善を行うことは可能ですがトラフィックを分散させない限りいつかアプリケーションの限界を迎えることとなります。スケールアウトするのでサーバを増やせばよいのですが今度はサーバ費用が増加することになります。

そんな、悩ましい日々がつづきました。

画像データをどのように管理し、どのように運用していくべきなのか。第四世代目はどうあるべきなのか。

次回にご期待ください!

うそです。

序盤で熱くなってしまい大変申し訳ありませんでした。

第四世代目のストレージシステム

これまでの経験上Webサービスに適したシステムは下記の3つです。

  • Scalability     (拡張性)
  • Availability    (可用性)
  • Maintainability (保守性)

この3つのことをグリーの一部では "SAM(サム)" と呼ばれております。テストにはでませんので忘れてください・・・。

Scalability(拡張性)は、スケールアウトすることがトラフィックを分散させることに繋がります。

Availability(可用性)は、一部のサーバで障害が発生しても安定して稼働しつづける冗長化が保たれたシステムが好ましいと考えます。

Maintainability(保守性)は、運用コストが低く運用し易いシステムであるべきと考えました。
この3つに当てはまるアプリケーションとなるとMogileFSが思い浮かんだのですがよりシンプルな構造の分散ストレージがよかったので自社で開発する道を選びました。

分散ストレージ(nanofs)構成

nanofsは、主に3つのプロセスで構成されております。

nanofsd(dispatcher)

  • アプリケーションサーバからリクエストを受け取り実際に保存されているnanofsnに振り分ける
  • 5つのHTTPメソッドをサポートしている(GET、PUT、DELETE、HEAD、MKCOL)
  • データベースに保存したデータの情報を送る
  • queueに処理の指示を送る

nanofsw(worker)

  • queueに送られた指示にしたがい非同期に処理を行う
  • 複数のnanofsnにデータをコピーする
  • nanofsnに保存されているデータを削除する

nanofsn(node)

  • データを保存する

特徴

nanofsは下記の特徴を持っています。

  • ファイル毎の分散
  • データベースとの通信以外HTTPで通信する
  • データベースはKVSを使用
  • 開発言語はRuby

さいごに

nanofsのソースコードはもし反響がございましたら公開させていただきたいと考えております。
次回はnanofsのHTTPメソッド毎の処理の流れについて書きたいと思います。