Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

blogサービスの全文検索の話 - #groonga を囲む夕べ

10,361 views

Published on

Published in: Internet
  • Hey guys! Who wants to chat with me? More photos with me here 👉 http://www.bit.ly/katekoxx
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

blogサービスの全文検索の話 - #groonga を囲む夕べ

  1. 1. blogサービスの 全文検索の話 全文検索エンジンGroongaを囲む夕べ5 長野雅広 (kazeburo)
  2. 2. Me •長野雅広 (Masahiro Nagano) •@kazeburo / github:kazeburo •Operations Engineer / Site Reliability •LINE corp. •ISUCON 2013,2014 連覇
  3. 3. 今日のお題
  4. 4. livedoor Blog •サービス開始11周年 •国内最大級 •blog開設数 570万件 •総記事数 3億件 •約100億PV/month
  5. 5. livedoor Blogを支える技術 •Reverse Proxy - Apache, Nginx •Application - Perl, Go •Cache - Memcached •RDBMS - MySQL 4.0, 5.5 •Search Engine - Mroonga
  6. 6. どこで Mroonga が 使われているか
  7. 7. blog内の記事検索 blog横断の検索はありませんが、 3億件の記事が対象
  8. 8. Mroongaを 採用した理由
  9. 9. 競合 • MySQLのLIKE検索 ➡ 検索機能不足 ➡ カテゴリやタグなどの絞り込みが面倒 • MySQL組み込みの全文検索 ➡ 日本語非対応 • Elasticsearch ➡ Java/JVMの経験不足 ➡ 大規模環境でのトラブルシューティングに不安
  10. 10. Mroonga •MySQL! MySQL! MySQL! ➡レプリケーションやバックアップな どMySQLの知見が活かせる •日本語で作者とコミュニケーション
  11. 11. 検索サーバの構成
  12. 12. microservices マイクロサービスっぽく作ってます
  13. 13. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker Q4M MappingDB shard1 shard2 shard3 検索 Service
  14. 14. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker Q4M MappingDB 検索 Service 記事追加 shard1 shard2 shard3
  15. 15. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker Q4M MappingDB 検索 Service 記事追加 shard1 shard2 shard3 Queueing
  16. 16. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker Q4M MappingDB 検索 Service 記事追加 shard1 shard2 shard3 Queueing blog_idと shardの mapping
  17. 17. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker Q4M MappingDB 検索 Service 記事追加 shard1 shard2 shard3 Queueing blog_idと shardの mapping INSERT!
  18. 18. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker Q4M MappingDB shard1 shard2 shard3 検索 Service
  19. 19. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker 検索 Q4M MappingDB shard1 shard2 shard3 検索 Service
  20. 20. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker 検索 Q4M MappingDB shard1 shard2 shard3 検索 Service blog_idと shardの mapping
  21. 21. 記事表示 Service 記事編集 Service blog App blog App blog App cms App cms App cms App Search API Search API Index Worker Index Worker 検索 Q4M MappingDB shard1 shard2 shard3 検索 Service blog_idと shardの mapping SELECT
  22. 22. Mroonga サーバの構成 shard1 shard2 shard3 この中身
  23. 23. Shardの構成 master slave slave Shard N
  24. 24. Shardの構成 master slave slave Shard N 参照・更新は 全てMaster Slaveは バックアップ
  25. 25. ハードウェア •Intel Xeon 6core/12thread * 2 •Memory 96GB •PCI-E SSD
  26. 26. テーブルとスキーマ
  27. 27. スキーマ CREATE TABLE article_index_0001 ( id bigint unsigned NOT NULL AUTO_INCREMENT, blog_id int unsigned NOT NULL, article_id int unsigned NOT NULL, status tinyint NOT NULL, public_terms mediumtext, private_terms mediumtext, article_datetime datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY unique_entry (blog_id,article_id), FULLTEXT KEY for_public (public_terms), FULLTEXT KEY for_cms (public_terms,private_terms) ) ENGINE=mroonga; storage mode
  28. 28. スキーマ CREATE TABLE article_index_0001 ( id bigint unsigned NOT NULL AUTO_INCREMENT, blog_id int unsigned NOT NULL, article_id int unsigned NOT NULL, status tinyint NOT NULL, public_terms mediumtext, private_terms mediumtext, article_datetime datetime NOT NULL, PRIMARY KEY (id), UNIQUE KEY unique_entry (blog_id,article_id), FULLTEXT KEY for_public (public_terms), FULLTEXT KEY for_cms (public_terms,private_terms) ) ENGINE=mroonga; x150 storage mode
  29. 29. mysql>show tables; +--------------------+ | Tables_in_hermes | +--------------------+ | article_index_0001 | | article_index_0002 | | article_index_0003 | | article_index_0004 | | article_index_0005 | | article_index_0006 | | article_index_0007 | ... ... | article_index_0142 | | article_index_0143 | | article_index_0144 | | article_index_0145 | | article_index_0146 | | article_index_0147 | | article_index_0148 | | article_index_0149 | | article_index_0150 | +--------------------+ 150 rows in set (0.00 sec)
  30. 30. Table 分散 Search API Index Worker blog_idで分散 0001 0002 0003 0004 0005 0006 0007 ... ... ... ... 0144 0145 0146 0147 0148 0149 0150
  31. 31. Table 分散 Search API Index Worker blog_idで分散 (murmur_hash(blog_id) % 150) + 1 0001 0002 0003 0004 0005 0006 0007 ... ... ... ... 0144 0145 0146 0147 0148 0149 0150
  32. 32. Table分散を行う理由 •Mroonga/Groongaの制限を超えるため •「最大インデックスサイズ: 256GByte」 •並列性能の向上 •障害時の影響範囲を最小化
  33. 33. 運用ノウハウ
  34. 34. Kernel Tuning $ cat /etc/sysctl.conf # NUMAを無効に vm.zone_reclaim_mode = 0 # 物理メモリ以上のメモリ確保を許可 vm.overcommit_memory = 1 # mmapで確保できる最大マッピング数 vm.max_map_count = 5000000
  35. 35. Linux Tuning (2) # 透過的hugepageを切る $ echo 'never' > /sys/kernel/mm/ transparent_hugepage/enabled
  36. 36. my.cnf [mysqld] table_open_cache = 多め! MySQL 5.6では デフォルト2000
  37. 37. その他の工夫
  38. 38. Splog/巨大記事対策 •Mroongaにいれる1記事あたりの最大文 字数の設定 ➡ Splog(spam + blog) の記事は大量の リンクを貼っていたり、自動生成した記 事が多いため、1記事あたりの容量が増 えがち •` ` やHTMLの終了タグの削除
  39. 39. 参照クエリの 並列数制限
  40. 40. 並列度を上げると性能劣化 参照クエリの並列度と処理時間 処理時間並列度 https://gist.github.com/kazeburo/9014939 150 112.5 75 37.5 0 1 2 3 4 5 6 7 8 16 http://redmine.groonga.org/issues/2335
  41. 41. GET_LOCKで並列度制限 # table名でlock mysql> SELECT GET_LOCK(“article_index_0099”,30); # 検索 mysql> SELECT article_id FROM article_index_0099 WHERE blog_id=30 AND status=1 AND MATCH(public_terms) AGAINST(? IN BOOLEAN MODE) ORDER BY article_datetime DESC LIMIT 10 OFFSET 0; # 終わったらlockを解放 mysql> SELECT RELEASE_LOCK(“article_index_0099”)
  42. 42. 困っている事
  43. 43. 更新集中時の負荷 •記事の更新が集中した場合にロードア ベレージが上がりやすい •記事更新にもGET_LOCKが必要?
  44. 44. たまに落ちる •masterだけじゃなくて参照が行われて いないslaveもMySQLが落ちる •落ちた時に一部のテーブルのindexが 壊れるのか更新ができない状態にな り、mysqldump && restoreが必要 となる まだ落ちるパターンが分かれば バグレポートあげたい
  45. 45. 以上です。

×