Your SlideShare is downloading. ×
はてなブックマークのシステムについて
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

はてなブックマークのシステムについて

12,787
views

Published on

Published in: Technology

0 Comments
16 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
12,787
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
115
Comments
0
Likes
16
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. はてなブックマークの システムについて 株式会社はてな / {Shibuya, Kansai}.pm 伊藤 直也
  • 2. 自己紹介
    • 株式会社はてな 執行役員 CTO
  • 3. アジェンダ
    • はてなブックマークのこれまでと現状
    • 各種機能の実現方法
    • パフォーマンスに関する話
  • 4. はてなブックマークの これまでと現状
  • 5. はてなブックマーク
  • 6. はてなブックマークのこれまで
    • 2005/2 ベータ版リリース
    • 2005/8 正式版リリース
    • 2008/7 関連エントリー機能
      • 株式会社プリファードインフラストラクチャー  (PFI) と共同開発
    • 2008/11 はてなブックマーク 2
      • システムリニューアル
      • 全文検索 (w/ PFI) 、カテゴライズ etc
    • 2009/4 Firefox 拡張
    • 2009/5 はてなブックマークプラス
      • 有料オプション
  • 7. 現在の数字
    • 300,000 ユーザー登録
    • 400万セッション/月 (Google Analytics)
    • 1,600万 URL / 4,700万 ブックマーク
  • 8. データの規模の例 mysql> select count(*) from relword; +-----------+ | count(*) | +-----------+ | 351277311 | +-----------+ 1 row in set (0.00 sec)
  • 9. データの規模
    • レコード数
      • 1,600万 エントリー
      • 4,700万 ブックマーク
      • 5,000万 タグ
    • データサイズ (MySQL MyISAM)
      • エントリー 3GB
      • ブックマーク 5.5GB
      • タグ 4.8GB
      • HTML 200GB超 (zlib で圧縮済み)
  • 10. 中規模 ~ 大規模ウェブサービス
    • サーバ台数
      • httpd
      • mysqld
      • そのほか
    • コードの規模
      • Perl コード 10 万行弱 (WAF 等抜きで 45,000 行 )
      • .pm ファイル 1,200 個強 (600 個 )
    • Google, Yahoo!, Amazon が超大規模とすると中規模くらい
      • レコード数 千万件単位、データ規模は GB 単位
  • 11. 開発体制
    • 8名体制
      • ディレクター (マネージャ) 1名
      • エンジニア 3名 +アルバイト 3名
      • デザイナー 1名 +アルバイト 1名
  • 12. システム構成
    • 基本は LAMP
      • ウェブアプリ部分はオーソドックスな構成
      • Linux (Xen), Apache, MySQL, Perl
    • 用途によってはサブシステムあり
      • 検索用サーバー群 (PFI の Sedue 、自社開発の検索サーバ )
      • カテゴライズサーバー
      • スペルミス修正サーバー
      • 非同期タスク用に TheSchwartz
      • 分散ファイルシステムに MogileFS
      • etc.
  • 13. プログラミング言語
    • Perl 5.8
      • mod_perl
      • WAF ・・・ Ridge ( 自社開発 )
      • O/R マッパ ・・・ DBIx::MoCo
    • JavaScript
      • Ten.js ( 自社開発 )
    • C++
      • Thrift
      • メモリ要件、速度要求が厳しい箇所
  • 14. 利用している主なソフトウェア
    • Perl, JavaScript, C++
    • LAMP, Xen
    • LVS + keepalived
      • ロードバランサ
    • Thrift
      • 多言語 RPC フレームワーク (by Facebook)
    • TheSchwartz
    • MogileFS
    • Lux IO
      • Key Value Store
    • Squid
  • 15. 各種機能の実現方法
  • 16. 本文抽出
  • 17. HTML::ExtractContent
    • はてなブックマーク2用に開発した本文抽出モジュール
      • HTML から「良い感じ」に本文テキストを抽出
      • CPAN に公開済
        • JavaScript 版を現在開発中
      • サイボウズ・ラボの中谷秀洋氏の Ruby 実装を Perl に移植
    • 後述の検索、カテゴライズの精度に大きく影響
  • 18. HTML::ExtractContent の仕組み
    • 正規表現だけで高速に
    • ヒューリスティクスで " 本文らしさ " を判定
      • HTML を適当なブロック要素ごとに分割
      • 各ブロックにスコアリング
        • 本文っぽさでスコア増 ( 句読点、テキストノードの文字列長 etc)
        • 本文っぽくなさでスコア減 ( リンクばかり並んでいる etc)
      • つながっているブロックをまとめてクラスタにする
        • 高スコアが続いたらクラスタ、低スコアが来たら切れ目
        • ブロックスコアの合計がクラスタのスコア
      • スコアの一番高いクラスタが本文
    • 詳しくは : http://d.hatena.ne.jp/tarao/20090322#1237750634
  • 19. HTML::LayeredExtractor ( 非公開 )
    • 新聞など ・・・ ExtractContent で OK
    • 一部のサイト ・・・ 確実に抜き出せる別の方法
      • <!-- google_ad_section_start -->
      • Web API
        • ニコニコ動画、 YouTube 、 Amazon.co.jp
      • 特定サイトはルールベースに処理
        • 自社サイト、大手サイトは XPath で、など
      • フィードを利用
      • 複数試して一番良い結果を選択するメタエンジン
    • Chain of Responsibility で順番に試して駄目なら ExtractContent に fallback
  • 20. 全文検索機能
  • 21. 2 つの全文検索システム
    • 全登録文書からの全文検索
      • PFI の Sedue
    • 自分のブックマークからの全文検索
      • 有料オプション限定の機能
      • 自社開発の Perl 検索エンジン
  • 22. 1. 全文書からの全文検索
    • Sedue
      • http://preferred.jp/sedue/
      • 圧縮 Suffix Arrays
    • スコアリングのアルゴリズム
      • よく知られた幾つかのヒューリスティクス
      • ブックマーク数やブックマークされた時間を加味
    • 文書登録 , 更新
      • ブックマークのタイミングに合わせて TheSchwartz で
      • 1st ブックマークから数分後には検索可能
  • 23. 2. 個人のブックマークからの全文検索
    • &quot;マイブックマーク全文検索&quot;
    • Perl で独自の全文検索システムを開発
      • オーソドックスな転置インデックス方式
        • ユーザー毎にインデックスを構築
      • 動的に更新可能
      • id:naoya プロトタイプ -> id:r_kurain ( 倉井龍太郎 ), id:tarao が中心に開発
  • 24. 転置インデックス
    • 辞書 -> 含む文書のID 列 (Postings List) の索引
    ... perl => [1, 5, 20, 333, 350, 362 ...] python => [8, 10, 11, 52 ...] ruby => [1, 10, 21, 333, 350, 428 ...] ...
  • 25. 転置インデックスの構成
    • 二つのインデックス
      • 辞書が N-gram のインデックス
        • ノイズが少なく、且つ検索漏れして欲しくないデータ用のインデックス
        • タイトル、コメント、タグ、 URL 文字列など
      • 辞書が形態素解析のインデックス
        • 本文テキスト (by ExtractContent) などノイズの多い箇所
        • MeCab ( はてなキーワード + MeCab 辞書 )
      • 検索は両者から行って、結果をマージ
    • Postings List には文書 ID と単語出現位置を記録
      • スニペットの表示やスコアリングに出現位置が必要
      • [ 10: 2, 100, 108, ... ]
  • 26. 転置インデックスの構成 ( 続き )
    • 転置インデックスの圧縮
      • Postings List の差分を取って VB 符号 ( 相当 )
      • Array::Gap
        • http://d.hatena.ne.jp/naoya/20080906/1220685978
    • 転置インデックスの保存に Lux IO
      • Lux の KVS
      • Perl バインディング Lux::IO (id:antipop)
      • シンプルで高速
      • ユーザー毎にファイルひとつ。本システムの運用に最適
        • 索引を作り直したかったらファイルを削除して再構築
        • 分散したいなら、ユーザー ID などでパーティショニング
  • 27. 検索結果のスコアリング
    • 本夏のインターンシップで開発
      • id:yaotti, id:nyanp
  • 28. スコアリングの手法
    • 複数のヒューリスティクスの結果を重み付き線形和で
      • (例) Score = 0.5 * TF-IDF + 0.2 * ブクマ数 + 0.3 * 新鮮度
      • 重みは適当
        • 本格的にやるなら正解データからの機械学習
  • 29. スコアリングの手法の一部 ( 続き )
    • クエリがタイトル等に含まれているかどうか
    • 複数クエリ語の近傍度
    • クエリの出現位置 ・・・ 前半であるほど良
    • クエリのマッチの仕方 ( 単語境界かどうか etc)
    • TF-IDF
    • ブックマーク数
    • 文書の新鮮度
      • 文書の 1st ブックマーク日時
    • 特定の URL にボーナス
      • Wikipedia, d.hatena.ne.jp/keyword など
      • ルートドキュメント
  • 30. スコアリング今後
    • PageRank や HITS 的なリンク解析
    • クリックストリームからのフィードバック学習
  • 31. 検索エンジンとアプリケーションのやりとり
    • JSON-RPC で Web API
      • アクセス制限などはウェブアプリケーション側で
      • 検索システムはあくまで検索結果を返すだけに専念
    • Web API は一般にも公開
      • google &quot;マイブックマーク全文検索API&quot;
  • 32. Firefox 拡張 + マイブックマーク検索
    • 拡張から Web API で検索結果を取得
  • 33. スペルミス修正機能
    • もしかして
  • 34. スペルミス修正サーバー
    • クエリ語に対して修正候補を返す
    • C++ と Perl ・・・ Thrift
      • スコアリングエンジンを C++ で、問い合わせは Perl で
    • スペルミス修正のアルゴリズム
      • はてなキーワードを辞書に補正
      • N-gram 索引を使って候補を絞り、 Jaro-Winkler 距離 ( 編集距離のようなもの ) で近似度を測定
      • 詳しくは google &quot;Kansai.pm スペルミス &quot;
  • 35. 関連エントリー機能
  • 36. レコメンドエンジン BSim
    • PFI のレコメンドエンジン
      • ブックマークのタグを入力
        • ほかも幾つか試したがタグの精度が圧倒的に良かった
        • タグは記事推薦に非常に有効
    • Perl とのやりとり
      • C++ で書かれたエンジンと Perl アプリ
      • Thrift を利用して RPC で
  • 37. カテゴライズ機能
  • 38. 文書分類エンジン BDog
    • 自社開発の文書分類エンジン
      • C++ で実装、 Thfirt で Perl から利用
    • 本文テキスト (by ExtractContent) から単語ベクトルを作って判定
    • ベイジアンフィルタ
      • Complement Naive Bayes
        • http://d.hatena.ne.jp/tkng/20081217/1229475900
        • 特定のクラスに偏りがある場合、 Naive Bayes よりも精度が向上
      • 動的な学習により精度向上
        • ユーザーによるカテゴリ修正で ... 過学習防止のため対象は特定ユーザーに限定
  • 39. Complement Naive Bayes
  • 40. そのほか
    • ブックマークスパム判定機能
      • 複数のルールベースを組合わせた判定エンジン
        • 例: 同一順で同一エントリをブックマークし続ける複数アカウントによるブックマーク
    • 特徴語抽出
      • はてなキーワード
      • TF-IDF
      • 関連広告表示などにも利用
  • 41. 各所で TheSchwartz を活用
    • TheSchwartz
      • Six Apart 社開発のジョブキューフレームワーク
      • CPAN
    • 検索、スパム判定などブックマーク追加後に各種更新処理が発生
      • 同期処理だとユーザーを待たせる
      • TheSchwartz で非同期化
        • HTML を取得し本文抽出 / スパム判定 / カテゴリ判定 / Sedue への更新要求 / マイブックマーク検索エンジンへの更新要求 / はてなキーワード抽出 / リンク抽出 / favicon を取得 / AccountDiscovery / スクリーンショット撮影 ...
  • 42. はてなブックマーク Firefox 拡張
  • 43. Firefox 拡張
    • Firefox Add-ons
      • XUL
        • http://subtech.g.hatena.ne.jp/secondlife/20090402/1238661633
      • id:secondlife, id:nanto_vi が中心に開発
      • オープンソース
        • http://github.com/hatena/hatena-bookmark-xul
    • はてなブックマークの各種機能を JSON API にして、 Firefox から利用
      • 拡張用に追加した API の一部は公開 API としてもリリース
  • 44. 雑感
    • Web + DB システムの一歩外の開発をここ一年ぐらいで色々した
      • 検索、レコメンド、Firefox拡張 ...
      • なかなか楽しい
      • 新しい体験をエンドユーザーに提供できる
  • 45. パフォーマンスに関する話
  • 46. バックエンドのシステム構成
    • 定番の三層構造
      • LVS + KeepAlived で分散
      • lighttpd or Apache -> (Squid ->) mod_perl -> MySQL
  • 47. バックエンドシステムの三層構造 proxy proxy LB LB app server app server app server app server LB DB DB LB LB LB
  • 48. ハードウェア : 自作サーバー
  • 49. データベースの構成
    • オーソドックスな構成でスケーリング
      • MySQL (MyISAM)
        • メモリ 16GB
        • 一部で SSD を試験
      • マスタ・スレーブ構成
      • データのサイズ、用途に合わせてテーブル単位で分割
        • メイン (ユーザ情報、エントリ、ブックマーク)
        • タグ、キーワード
        • HTMLデータ etc.
  • 50. 島分け proxy AP bot / feed 通常のリクエスト DB 画像 API etc. proxy
  • 51. Squid によるキャッシュ
    • Squid Reverse Proxy でキャッシュ
      • ゲスト向けコンテンツ
      • bot 向けコンテンツ
      • 一部の API
        • ○○ users 画像のバックエンドの API など
  • 52. memcached によるキャッシュ
    • アプリケーションフレームワークに memcached キャッシュ機能
      • ページを丸ごと memcached にキャッシュする機能
      • ユーザー毎の設定パラメータをまとめて SHA1 キーを作り、同じ設定のユーザーには同じキャッシュを返す機能
    • Template::Plugin::Cache
    • longtail はキャッシュしない
      • ○○ users を閾値に
  • 53. クライアント表示に関する工夫
    • 昨今では定番の手法を実施
      • gzip 圧縮
      • 静的ファイルの Expires を 1年に
        • 更新される可能性のあるものは別ディレクトリで管理
        • CSS, JavaScript ファイルは git の commit + path の SHA1 をクエリパラメータに
          • 例: /js/foo.js?sha1hogehoge
      • 静的ファイルを別ドメイン -> Cookie 分の転送を削減
  • 54. クライアント表示に関する工夫 ( 続き )
    • JavaScript による遅延ロード
      • 広告の遅延ロード
        • 広告表示でページ表示が待たされない
        • Google の広告、自社広告
  • 55. クライアント表示に関する工夫 ( 続き )
    • ユーザー毎に出し分ける部分を JS で遅延
      • 残った共通部分 (HTML) をキャッシュできる
  • 56. 雑感
    • 一般的な Web + DB システムの運用は苦労が減った
      • ハードウェアの進歩、特にメモリ容量
      • 各種ノウハウがウェブや書籍等で公開されている
    • JavaScript の遅延ロードをうまく使うと高速化に寄与できる箇所が多い
    • RDBMS だけでは難しい規模 / 要件をどうするかが面白い
      • 検索エンジンを作る、レコメンドエンジンを作る、文書分類エンジンを作る ... etc.
  • 57. WEB+DB PRESS Vol.49
  • 58. まとめ
    • はてなブックマークのシステムの裏側を紹介した
    • オーソドックスな Web + DB システムと幾つかのサブシステムを開発した
      • 検索、レコメンド、文書分類 etc
    • RDBMS では難しい/面倒なことをどう解決していくかが今後もテーマに
  • 59. Thank You !