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

blogサービスの 
全文検索の話 
全文検索エンジンGroongaを囲む夕べ5 
長野雅広 (kazeburo)
Me 
•長野雅広 (Masahiro Nagano) 
•@kazeburo / github:kazeburo 
•Operations Engineer / Site 
Reliability 
•LINE corp. 
•ISUCON 2013,2014 連覇
今日のお題
blogサービスの全文検索の話 - #groonga を囲む夕べ
livedoor Blog 
•サービス開始11周年 
•国内最大級 
•blog開設数 570万件 
•総記事数 3億件 
•約100億PV/month
livedoor Blogを支える技術 
•Reverse Proxy - Apache, Nginx 
•Application - Perl, Go 
•Cache - Memcached 
•RDBMS - MySQL 4.0, 5.5 
•Search Engine - Mroonga
どこで Mroonga が 
使われているか
blogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べ
blog内の記事検索 
blog横断の検索はありませんが、 
3億件の記事が対象
Mroongaを 
採用した理由
競合 
• MySQLのLIKE検索 
➡ 検索機能不足 
➡ カテゴリやタグなどの絞り込みが面倒 
• MySQL組み込みの全文検索 
➡ 日本語非対応 
• Elasticsearch 
➡ Java/JVMの経験不足 
➡ 大規模環境でのトラブルシューティングに不安
Mroonga 
•MySQL! MySQL! MySQL! 
➡レプリケーションやバックアップな 
どMySQLの知見が活かせる 
•日本語で作者とコミュニケーション
検索サーバの構成
microservices 
マイクロサービスっぽく作ってます
記事表示 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
記事表示 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
記事表示 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
記事表示 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
記事表示 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!
記事表示 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
記事表示 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
記事表示 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
記事表示 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
Mroonga サーバの構成 
shard1 shard2 shard3 
この中身
Shardの構成 
master 
slave slave 
Shard N
Shardの構成 
master 
slave slave 
Shard N 
参照・更新は 
全てMaster 
Slaveは 
バックアップ
ハードウェア 
•Intel Xeon 6core/12thread * 2 
•Memory 96GB 
•PCI-E SSD
テーブルとスキーマ
スキーマ 
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
スキーマ 
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
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)
Table 分散 
Search 
API 
Index 
Worker 
blog_idで分散 
0001 0002 0003 0004 0005 0006 
0007 ... ... ... ... 0144 
0145 0146 0147 0148 0149 0150
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
Table分散を行う理由 
•Mroonga/Groongaの制限を超えるため 
•「最大インデックスサイズ: 256GByte」 
•並列性能の向上 
•障害時の影響範囲を最小化
運用ノウハウ
Kernel Tuning 
$ cat /etc/sysctl.conf 
# NUMAを無効に 
vm.zone_reclaim_mode = 0 
# 物理メモリ以上のメモリ確保を許可 
vm.overcommit_memory = 1 
# mmapで確保できる最大マッピング数 
vm.max_map_count = 5000000
Linux Tuning (2) 
# 透過的hugepageを切る 
$ echo 'never' > /sys/kernel/mm/ 
transparent_hugepage/enabled
my.cnf 
[mysqld] 
table_open_cache = 多め! 
MySQL 5.6では 
デフォルト2000
その他の工夫
Splog/巨大記事対策 
•Mroongaにいれる1記事あたりの最大文 
字数の設定 
➡ Splog(spam + blog) の記事は大量の 
リンクを貼っていたり、自動生成した記 
事が多いため、1記事あたりの容量が増 
えがち 
•` ` やHTMLの終了タグの削除
参照クエリの 
並列数制限
並列度を上げると性能劣化 
参照クエリの並列度と処理時間 
処理時間並列度 
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
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”)
困っている事
更新集中時の負荷 
•記事の更新が集中した場合にロードア 
ベレージが上がりやすい 
•記事更新にもGET_LOCKが必要?
たまに落ちる 
•masterだけじゃなくて参照が行われて 
いないslaveもMySQLが落ちる 
•落ちた時に一部のテーブルのindexが 
壊れるのか更新ができない状態にな 
り、mysqldump && restoreが必要 
となる 
まだ落ちるパターンが分かれば 
バグレポートあげたい
以上です。
1 of 48

More Related Content

What's hot(20)

Using Windows AzureUsing Windows Azure
Using Windows Azure
Shinji Tanaka2.2K views
ニコニコニュースと全文検索ニコニコニュースと全文検索
ニコニコニュースと全文検索
techtalkdwango3.5K views
ZabbixによるAWS監視のコツZabbixによるAWS監視のコツ
ZabbixによるAWS監視のコツ
ShinsukeYokota38.1K views
WebサーバのチューニングWebサーバのチューニング
Webサーバのチューニング
Yu Komiya9.6K views
ansible 社内お勉強会資料ansible 社内お勉強会資料
ansible 社内お勉強会資料
Makoto Uehara4K views
Ansible 入門 #01 (初心者向け)Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)
Taro Hirose6.2K views
081108huge_data.ppt081108huge_data.ppt
081108huge_data.ppt
Naoya Ito2.8K views
mysqlcasual6-fabricmysqlcasual6-fabric
mysqlcasual6-fabric
doublemarket12.9K views
Ansible入門Ansible入門
Ansible入門
Daiki Hayakawa936 views
Zabbixを2分でインストールZabbixを2分でインストール
Zabbixを2分でインストール
真乙 九龍1.9K views

Viewers also liked(20)

How To Become A RubyistHow To Become A Rubyist
How To Become A Rubyist
masayoshi takahashi13.1K views
全文検索エンジンMroonga_エンジニア勉強会20140418全文検索エンジンMroonga_エンジニア勉強会20140418
全文検索エンジンMroonga_エンジニア勉強会20140418
エンジニア勉強会 エスキュービズム3.5K views
new Objctive-C literal syntaxnew Objctive-C literal syntax
new Objctive-C literal syntax
Wataru Kimura1.8K views
SinatraのススメSinatraのススメ
Sinatraのススメ
@odailly_jp Odai6K views
Rubyはとても「人間的」Rubyはとても「人間的」
Rubyはとても「人間的」
Kazuhiro Serizawa5.7K views
本格的に始めるzsh本格的に始めるzsh
本格的に始めるzsh
Hideaki Miyake1.9K views
Ruby1.9のfiberのかっこいい使い方Ruby1.9のfiberのかっこいい使い方
Ruby1.9のfiberのかっこいい使い方
Kindai University2.7K views
Project Lambdaの基礎Project Lambdaの基礎
Project Lambdaの基礎
Yuichi Sakuraba7.3K views
Code as data as code.Code as data as code.
Code as data as code.
Mike Fogus6.8K views
ES6 at PayPalES6 at PayPal
ES6 at PayPal
Jamund Ferguson3.4K views
Eclipse活用術Eclipse活用術
Eclipse活用術
Masahiro Wakame9.1K views
Storm AnatomyStorm Anatomy
Storm Anatomy
Eiichiro Uchiumi14.2K views

Similar to blogサービスの全文検索の話 - #groonga を囲む夕べ(20)

MySQL日本語全文検索エンジンMySQL日本語全文検索エンジン
MySQL日本語全文検索エンジン
Yutaka Hoshino2.8K views
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14
Masahiro Nagano2.1K views
POWER8サーバでMariaDBベンチマークPOWER8サーバでMariaDBベンチマーク
POWER8サーバでMariaDBベンチマーク
NHN テコラス株式会社1.6K views
20110519 okuyama tokyo_linuxstudy20110519 okuyama tokyo_linuxstudy
20110519 okuyama tokyo_linuxstudy
Takahiro Iwase519 views

More from Masahiro Nagano(20)

Big Master Data PHP BLT #1Big Master Data PHP BLT #1
Big Master Data PHP BLT #1
Masahiro Nagano39.3K views
Mackerel & Norikra mackerel meetup #4 LTMackerel & Norikra mackerel meetup #4 LT
Mackerel & Norikra mackerel meetup #4 LT
Masahiro Nagano36.6K views
Isucon makers casual talksIsucon makers casual talks
Isucon makers casual talks
Masahiro Nagano3K views
WebアプリケーションとメモリWebアプリケーションとメモリ
Webアプリケーションとメモリ
Masahiro Nagano13.9K views
MHA for MySQL の話MHA for MySQL の話
MHA for MySQL の話
Masahiro Nagano6.7K views

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