第三回 ライブドア・テクニカルセミナーに行ってきた

livedoor Techブログ : 第三回 ライブドア・テクニカルセミナーのお知らせに行ってきました。

内容が濃くてメモしきれないところもあったのですが載せておきます。

クラウド時代のWebストレージ/データベース戦略」

  • ライブドアが求めるストレージは?
    • webサービスのメディアストレージ
    • 安価に容量を拡張可能
    • データの冗長化、高可用性
    • 実際の構成は(あまり)意識したくない ※あまり、というのがポイント。自社で使う分にはうすらぼんやり見えているといい
    • 自社で使う向けに作った
  • HTTPを利用した分散ストレージ
  • Pros
    • シンプルなKey-Value
    • クライアントから巨大なストレージプールとして見える
    • 普通のサーバを使用して拡張可能
    • データのレプリケーション
    • Apacheモジュールベースなので拡張可能
  • Cons
    • ファイルシステムとしてマウントできない→コードの書きかえ
    • すでにあるオブジェクトに追記できない
    • オブジェクトの一部書き換えができない
    • パーミッション/アクセス制御ができない
  • REST API
    • GET/PUT/DELETEをサポート
    • バケットの作成/削除
    • オブジェクトの取得/作成/更新/削除
    • レプリカの作成数等はヘッダで指定
  • HTTPヘッダ
    • Content-MD5 これを入れておくことによってファイル欠けを検出することが可能
    • X-Replication-count レプリケーションする数を指定することができる
  • 実装
    • ApacheモジュールをCで実装
    • URI→物理ロケーションのマッピングMySQLに保存
    • MessageQueueを利用した非同期処理 Q4MとかActiveMQ
    • 非同期処理のワーカーはPerlで記述 ※ここが一番要件が変わる部分なのでPerlで書いておいて柔軟に対応したい
  • CAP定理
    • Consistency(一貫性), Availability(可用性), Partition Tolerance(ネットワーク分断の耐性)の3つのうちどれか一つを捨てなければいけないというのがある
    • 今回は、一貫性を捨てている。物理的には一貫性が崩れている瞬間があるけれどもそこを捨てている
  • MySQL/Memcached
    • ディスパッチャ
    • ストレージノード
    • Queue
    • Worker
  • テーブル構成
    • URL: 実体のマッピング/メタ情報
    • storage
    • bucket
    • object: URIとObjectID
      • Auto Incrementではなく、GUID 64bitのintになるように設定(Perlモジュールを移植したとおっしゃってたけど、Data::GUIDのことかな?)
    • entity: ObjectIDとファイル実体
  • mod_stf_storage.c
    • GET/PUT/DELETEメソッドを受け付けてファイルの読み書き
    • GETはdefault-handlerまかせ
    • PUTはRecursiveにディレクトリを作成
    • 同一ファイル名での上書きはできない
      • 更新は一回消して内部的には別ファイルを作成
  • Queue
    • 結果整合性を取るために使っている
    • MessageQueue経由
    • レプリケーション
    • オブジェクトの実体削除
      • 最初にDELETEするときはMySQLでdeleteするだけ→実体は非同期に消す
    • バケット削除時の再帰的削除
    • 使用容量の計算
  • Storage管理用のWebIF
    • Catalystベース
    • 機能
      • ストレージの追加
        • サーバをセットアップしてWebIFから追加
      • 利用状況の確認
      • ストレージのモード切り替え
  • 画像加工はImlib2かImageMagickから選べる
  • Squidにキャッシュしている
  • 今後の展望
    • MySQL依存からの脱却
    • 特定のノードの使用(SSD対応)
      • 最新のものと人気があるものしか参照しないように
  • 現在運用されている状況
    • 20TB〜30TBは用意されていて、運用されているのが10数TB
    • 1TB/月くらいで増える
  • なんでMogileFSにしなかったの?
    • MogileFSはソースが長い。書く時間と読む時間を考えたら書いた方が早い(かっこいい!)

ライブドアクラウド的サービス」

  • 仮想化技術の選定
    • VMware
      • 予算的にきつい
    • KVM
      • RedHatサポート
      • 管理ツールはあるが、X11ベース
      • それぞれのサーバに専用プログラムを導入する必要がある
    • Enormaly
    • Parallels製品に決定!
  • ソーシャルアプリ向けに開発した
  • Spec
    • Parallels Server 4 Bare Metal
    • CentOS 5.4 x86_64
    • OSバーチャライゼーションを使用
      • (HostOSの再起動が不要なため?)
  • 実装
    • リアルサーバの中にインスタンスがある
    • LVSの冗長構成の下にインスタンスを増やしていっている
      • ラックが埋まったらLocal Switch経由で移動
    • ネットワークの区切り方はtag VLANで区切る
    • LVSでスケールアウト
    • スケールアップ
      • ライブマイグレーション
        • UNITに余裕があるサーバにマイグレーションを行ってからスケールアップ
        • rsyncでコピーして、メモリ同期して、ネットワーク切り替えを行う
        • 使用しているディスク領域が多いと時間がかかる
        • 30GBでrsyncに1時間くらいかかるのでちょっといやだ
  • LVSのサーバの性能は?
    • 250台くらいまでは大丈夫だそう。
  • APIでプログラムから叩きたい
    • Parallelは叩くことはできるがサービス的には対応してない
    • API公開は必須条件なので対応していく予定
  • 課金形態は話し合い中
  • フルマネージドホスティングをベースにして、自動化できるところを自動化するというポリシー

livedoor Readerの新機能とは?」

  • 新機能の紹介
    • livedoor streaming API
    • フィードの更新情報をリアルタイムで取得するAPI
    • 外部ドメインでも普通に動く
    • 非公開フィードの記事はでない
    • ストリーミング、といっても、Readerがクロールしたタイミングにはなる
  • Q4m
  • TokyoTyrant
  • Nginx
    • Streaming APIのフロントエンドとして利用
    • long-pollコネクション可
  • Plack
    • そろそろnginx + Plackに変えたい
  • Coro AnyEvent
  • MySQL
    • 5.0
    • 5.1 記事クラスタで使っている。
    • InnoDB Plugin
      • データを圧縮して、メモリ効率を上げられる
      • 記事データ用に使用
      • Master/Slave 3+3台
  • Perl 5.8.7
  • Q4M
    • クローラとジョブ管理
    • Q4M専用MySQLを2台
    • クローラ専用4台
  • memcachedの代わりにTokyoTyrant
    • HashDB7台
  • Coroで作られたDOSツール
    • 大量のコネクションを張ってテストするのに使っている
  • データ量
  • クローラ
    • メッセージキューを使った分散処理
    • MySQLQ4M
    • クローラを細かいタスクに分割して実行
    • Q4Mでバケツリレー式に処理
  • 処理の内容
    • Brocker
      • クロール対象をキューに入れる
      • cronで1分置きに起動
      • このとき必要なデータをMemcachedに入れる
    • Fetcher
      • Parallel::PreforkとClass::Triggerつかっている
      • daemontoolsで管理
        • 一定件数処理したら死ぬように作っている
      • Coroを使って並列処理をしている。1プロセスで50~100(HTTPDのコネクション)くらい。
      • レスポンスが遅いものがあってもクローラが遅れないようにしている
    • Parser
      • XML::LibXMLとXML::Liberal+独自
        • 独自、というのは、巨大フィードを途中で中断するなど
        • feedburner.origLink保存するなど
      • 一番CPUパワーに依存する処理
      • 並列数増やしても意味がない
    • Updater
      • DBの処理速度に依存
      • 1台あたり10程度
  • 記事の振り分け
    • SKIP
    • INSERT
    • UPDATE
    • SILENT_UPDATE
      • ちょっとしか更新されてない
      • 一定文字数意外更新されたもののみ
  • フィードごとに既出フラグを保存している
    • 既出フラグの保存をmemcachedTokyoTyrantに移行
    • このとき、ストレージとネットワークIOの節約のため、既出フラグをfeedごとにまとめた。
    • フラグだけで5億件!→180万件に減った
  • ハッシュ値
    • 記事ごとにハッシュ値を作る
    • 本文からスペースとタグを取り除く
    • フィードごとに同じ記事は1件のみ
  • XMLとしては変化しているが記事は変更されていないケースが実は非常に多いことが判明
    • 配信元サーバがコメントで書かれてるとか
    • lastBuildDateがアクセス日時になってるとか
    • 独自のネームスペースにアクセス回数やコメント数が含まれているとか
  • そこで前回のパース結果をTokyoTyrantに保存
    • 前回更新時のフィードに含まれていた記事は既出の記事である
    • Parserの段階で不要な記事にはSkipFlagをつける
    • updaterキューへの送信数が半減
  • Async::Queue
    • Perlで書かれたメッセージキュー
    • AnyEvent+JSON RPC
      • 複数のキューサーバを1台に見せかけることができる
    • Q4Mのバグに当たった
      • dead lock接続待ちで応答なし(最新版で修正済み)
      • コンパクションが起こるタイミングでパフォーマンスが悪化する
  • クライアント側は書けませんでしたごめんなさい><