SlideShare a Scribd company logo
1 of 31
Download to read offline
トレタのMySQL
MySQL casual #8 (小規模限定回)
2015/11/20
Hiroaki Sano
me
• Name:
• 佐野裕章(Hiroaki Sano)
• Personal info:
• https://hiroakis.com/blog/
• https://twitter.com/la_luna_azul
• https://github.com/hiroakis
• Company:
• SIer(2006/4-)
• CyberAgent, Inc(2011/3-)
• Toreta, Inc (2014/11-)
トレタ
• 飲食店向け予約管理アプリケーション、一般ユーザ向けにウェブ予約も提供
• 顧客:レストラン、居酒屋などの飲食店
• 例えば…
• 俺の株式会社様(俺のイタリアン、俺のフレンチ…etc)
• 株式会社大庄様(庄や、やるき茶屋…etc)
• ローストホース様
• etc
• ローンチは2013年12月
• 導入店舗数:3700店舗∼
• 店舗あたりの月額課金
• オフィスは五反田
これを
こうじゃ
トレタのコンセプト
• 飲食店の予約管理、顧客管理をIT化
• 予約事故を防ぐ
トレタ
• アクセスのピーク
• 時刻:夕方6 pm JSTあたり
• 曜日:金曜日 > 他 > 土曜日 > 日曜日
• 夜の営業開始直後くらいに当日の予約確認をしていると思われる
トレタのMySQL
話すこと
• 経験上、大規模から小規模に変わった時に感じたこ
とか、小規模ならでは(?)のことをば…
トレタ
MySQL

Master
Engineyard
ブラウザiPad
MySQL

Slave
MySQL

Slave
Users
App
• サーバ側のコア機能はEngineyardで稼働
• 一部機能はAWS(S3, Route53..etc)やHerokuにも存在
• モニタリング、分析などはSaaSを利用

Mackerel, NewRelic, BigQuery…etc
トレタのMySQL
MySQL

Master
Appサーバ
MySQL

Slave
MySQL

Slave
Rails
HAProxy
Write
Read
Replication
TCP 127.0.0.1:3306
• MySQL on Engineyard
• MySQL5.6
• InnoDB
• m3.largeが3台(Master:Slave=1:2)
• ほとんどがRead
• スレーブは主にバッチの参照用、調査用、昇格
用
• 小規模(だと思う)。
worker
小規模ならではのことってなんだろう
• トレタの場合…
• Likeフィルタによる全文検索が割と動く
• キューっぽい使い方をしても割と動く
• 大規模に比べると運用が楽(シンプルなので)
全文検索
全文検索
SELECT DISTINCT `reservations`.`id`
FROM `reservations`
LEFT OUTER JOIN `customers`
ON `customers`.`id` = `reservations`.`customer_id`
LEFT OUTER JOIN `customer_phones`
ON `customer_phones`.`customer_id` = `customers`.`id`
LEFT OUTER JOIN `customer_emails`
ON `customer_emails`.`customer_id` = `customers`.`id`
WHERE `reservations`.`restaurant_id` = XXXX AND (
concat(customers.last_name, customers.first_name) like '%さの%' OR
concat(customers.last_name_reading,customers.first_name_reading) like '%さの%' OR
customers.company_name like '%さの%' OR
customers.note like '%さの%' OR
reservations.note like '%さの%' OR
customer_emails.email like '%さの%' OR
) ORDER BY `reservations`.`start_at` DESC LIMIT 10 OFFSET 0;
• Likeの部分一致検索
全文検索
• InnoDBのフルテキストインデックスは使っていない
• Mroongaも使っていない
• WHERE `reservations`.`restaurant_id` = XXXXでの
絞り込み
• (レコード数が少なければ)案外なんとかなる
カジュアルな話:なぜ部分一致検索は遅くなりがちか
• ここで試しに本当にカジュアルな話も挟んでみます…
• select * from t where col like ‘%word%’
• 理由:インデックスが効かないから
• Indexing LIKE Filters
• http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-
tuning
• インデックスとは索引。つまりそのままの意味。
• 前方一致のみインデックスが効く。
Likeフィルタで発生した事案
• select * from t where col like ’{POST_DATA}%’
• 空のPOST_DATA
• select * from t where col like ’%’
• DBマスタのCPUが100%になってしまった
• バリデーション漏れ
MySQLでキューのようなことをする
MySQLでキューのようなことをする
MySQL

Master
Appサーバ
MySQL

Slave
MySQL

Slave
Rails
HAProxy
Write
Read
Replication
TCP 127.0.0.1:3306
• 現地時間の午後3時に一部の顧客にメールを送る機能
• 定期的に各appサーバのworkerが一斉に動き出して
MySQLに参照/更新を行う
• あるworkerが処理中のレコードは他のworkerに処理
させたくない
• workerはsidekiq(非同期処理を行うgem)で実装
• 基本的には非同期的な処理を行っているがこのよう
なバッチ処理ぽいこともworkerにやらせている
worker
MySQLでキューのようなことをする
MySQL
WorkerWorkerWorkerWorker
CREATE TABLE `queues` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`reservation_id` int(11) NOT NULL,
`status` tinyint(4) NOT NULL DEFAULT '0',
`reminded_at` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_reservation_remind_emails_on_reservation_id` (`reservation_id`),
KEY `index_reservation_remind_emails_on_status_and_reminded_at` (`status`,`reminded_at`)
) ENGINE=InnoDB AUTO_INCREMENT=343046 DEFAULT CHARSET=utf8
select * from queues where status = 0 and reminded_at < now()
=> レコードが未処理(status=0)

かつ現地時間午後3:00を過ぎているもの(reminded_at < now())を取得
update queues set status = 1 where id = ? and status = 0

=> レコードを処理中としてマーキング(status=1)

=> ここでaffected_rowsが1なら自分が処理する

0だと他のworkerが処理するので何もしない
=> 処理に成功したらレコードを消す
• 参考
• http://qiita.com/masuyama/items/645b25f03dc9e321cb96
MySQLでキューのようなことをする
• 下記の記事で指摘があるように、正直、悪手ではある
• http://www.engineyard.co.jp/blog/2013/5-subtle-ways-
youre-using-mysql-as-a-queue-and-why-itll-bite-you/
• が、レコードが大量でなければ問題なく動く。
大規模に比べると運用が楽
大規模と小規模の構成の違い(経験上)
大規模時代 今
バージョン 4.1, 5.0, 5.1, 5.5, 5.6 5.6
ストレージエンジン MyISAM, InnoDB, Blackhole InnoDB
インフラ
大量のハイエンド物理サーバ

Write Heavyな箇所にはフラッシュを活用
クラウドに3台

特徴
種々の課題に対応するためにインフラ、MySQL側
やることが多くなりがち(だった)。

シャーディング、レプリケーションフィルタによる
テーブルの分散、InnoDBの圧縮の活用、カスケー
ド構成…etc
業務アプリケーションのバックエンドなの
でトラフィックはある程度予測できる。ウ
ェブ予約で多少のスパイクあり。
コンフィグとしては基本的な設定をケアす
れば良い。
大規模に比べるとシンプルなので運用が楽
• 小規模だから楽、というよりは構成がシンプルだか
ら楽。
• 大規模になってもシンプルなアーキテクチャを保つ
べき。
• Railsのmigrationで運用が回る
まとめ
• 小規模だと…
• 多少の悪手でも大丈夫
• Likeフィルタの部分一致検索
• キューもどき
• かといってインデックスが全く効かないのは危険
• ちゃんとインデックスを張る。インデックスを使うようなSQL投げる。
• ちゃんとモニタリングする
• 大規模よりは運用は楽
• 構成がシンプル
• 大規模になってもシンプルな構成を維持すべき
• ある程度の規模まではMySQL+著名なフルスタックフレームワークでビジネス
要件が満たせるシステムが構築できている
迫り来る課題
• 悪手からの脱却
• その用途に最適化されたミドルウェアの導入etc
• Railsのmigrationに依存した運用からの脱却
• 生のalterがだんだんキツくなってくる
最後にサラリーマンとして言わせてください
We are hiring!
https://toreta.in/recruit
おわり

More Related Content

Similar to トレタのMySQL MySQL casual #8

Webシステムとちょっと便利なツール
Webシステムとちょっと便利なツールWebシステムとちょっと便利なツール
Webシステムとちょっと便利なツールMasashi Shinbara
 
a-blogcsm な寺子屋 2 in Okazaki
a-blogcsm な寺子屋 2 in Okazakia-blogcsm な寺子屋 2 in Okazaki
a-blogcsm な寺子屋 2 in OkazakiEtsushi Ishii
 
Robotium を使った UI テスト
Robotium を使った UI テストRobotium を使った UI テスト
Robotium を使った UI テスト健一 辰濱
 
Rdbms起点で考えると見えない世界 okuyama勉強会
Rdbms起点で考えると見えない世界 okuyama勉強会Rdbms起点で考えると見えない世界 okuyama勉強会
Rdbms起点で考えると見えない世界 okuyama勉強会Masakazu Muraoka
 
松本克彦 ピグにおけるリアルタイムランキングの導入
松本克彦 ピグにおけるリアルタイムランキングの導入松本克彦 ピグにおけるリアルタイムランキングの導入
松本克彦 ピグにおけるリアルタイムランキングの導入matsumoto_katsuhiko
 
サンタクロースを支えるIT技術 @M_Ishikawa #yapcasia
サンタクロースを支えるIT技術 @M_Ishikawa #yapcasiaサンタクロースを支えるIT技術 @M_Ishikawa #yapcasia
サンタクロースを支えるIT技術 @M_Ishikawa #yapcasiaMasayuki Ishikawa
 
AWS Lambda with Java/Scala #渋谷Java 第十二回
AWS Lambda with Java/Scala #渋谷Java 第十二回AWS Lambda with Java/Scala #渋谷Java 第十二回
AWS Lambda with Java/Scala #渋谷Java 第十二回hajime ni
 
Firebase & BigQuery で Android アプリの成⻑を支える
Firebase & BigQuery で Android アプリの成⻑を支えるFirebase & BigQuery で Android アプリの成⻑を支える
Firebase & BigQuery で Android アプリの成⻑を支える健一 辰濱
 
スマートニュースの世界展開を支えるログ解析基盤
スマートニュースの世界展開を支えるログ解析基盤スマートニュースの世界展開を支えるログ解析基盤
スマートニュースの世界展開を支えるログ解析基盤Takumi Sakamoto
 
20121103 #odstudy できる! VBAマクロ
20121103 #odstudy できる! VBAマクロ20121103 #odstudy できる! VBAマクロ
20121103 #odstudy できる! VBAマクロHiyou Shinnonome
 
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015Masahiro Nagano
 
We Should Know About in this SocialNetwork Era 2011_1112
We Should Know About in this SocialNetwork Era 2011_1112We Should Know About in this SocialNetwork Era 2011_1112
We Should Know About in this SocialNetwork Era 2011_1112Masahito Zembutsu
 
MTCafe sapporo#4
MTCafe sapporo#4MTCafe sapporo#4
MTCafe sapporo#4bitpart
 
Parseでちゃんとアプリを作るコツ
Parseでちゃんとアプリを作るコツParseでちゃんとアプリを作るコツ
Parseでちゃんとアプリを作るコツTakuya Tejima
 
Lineにおけるspring frameworkの活用
Lineにおけるspring frameworkの活用Lineにおけるspring frameworkの活用
Lineにおけるspring frameworkの活用Tokuhiro Matsuno
 
高速処理と高信頼性を両立し、ペタバイト級の多種大量データを蓄積する、ビッグデータ/ IoT時代のデータベースとは??
高速処理と高信頼性を両立し、ペタバイト級の多種大量データを蓄積する、ビッグデータ/ IoT時代のデータベースとは??高速処理と高信頼性を両立し、ペタバイト級の多種大量データを蓄積する、ビッグデータ/ IoT時代のデータベースとは??
高速処理と高信頼性を両立し、ペタバイト級の多種大量データを蓄積する、ビッグデータ/ IoT時代のデータベースとは??griddb
 
ElasticSearch勉強会 第6回
ElasticSearch勉強会 第6回ElasticSearch勉強会 第6回
ElasticSearch勉強会 第6回Naoyuki Yamada
 

Similar to トレタのMySQL MySQL casual #8 (20)

Webシステムとちょっと便利なツール
Webシステムとちょっと便利なツールWebシステムとちょっと便利なツール
Webシステムとちょっと便利なツール
 
a-blogcsm な寺子屋 2 in Okazaki
a-blogcsm な寺子屋 2 in Okazakia-blogcsm な寺子屋 2 in Okazaki
a-blogcsm な寺子屋 2 in Okazaki
 
Robotium を使った UI テスト
Robotium を使った UI テストRobotium を使った UI テスト
Robotium を使った UI テスト
 
Rdbms起点で考えると見えない世界 okuyama勉強会
Rdbms起点で考えると見えない世界 okuyama勉強会Rdbms起点で考えると見えない世界 okuyama勉強会
Rdbms起点で考えると見えない世界 okuyama勉強会
 
松本克彦 ピグにおけるリアルタイムランキングの導入
松本克彦 ピグにおけるリアルタイムランキングの導入松本克彦 ピグにおけるリアルタイムランキングの導入
松本克彦 ピグにおけるリアルタイムランキングの導入
 
Mobile Web
Mobile WebMobile Web
Mobile Web
 
Devlove mackerel
Devlove mackerelDevlove mackerel
Devlove mackerel
 
サンタクロースを支えるIT技術 @M_Ishikawa #yapcasia
サンタクロースを支えるIT技術 @M_Ishikawa #yapcasiaサンタクロースを支えるIT技術 @M_Ishikawa #yapcasia
サンタクロースを支えるIT技術 @M_Ishikawa #yapcasia
 
AWS Lambda with Java/Scala #渋谷Java 第十二回
AWS Lambda with Java/Scala #渋谷Java 第十二回AWS Lambda with Java/Scala #渋谷Java 第十二回
AWS Lambda with Java/Scala #渋谷Java 第十二回
 
Firebase & BigQuery で Android アプリの成⻑を支える
Firebase & BigQuery で Android アプリの成⻑を支えるFirebase & BigQuery で Android アプリの成⻑を支える
Firebase & BigQuery で Android アプリの成⻑を支える
 
スマートニュースの世界展開を支えるログ解析基盤
スマートニュースの世界展開を支えるログ解析基盤スマートニュースの世界展開を支えるログ解析基盤
スマートニュースの世界展開を支えるログ解析基盤
 
20121103 #odstudy できる! VBAマクロ
20121103 #odstudy できる! VBAマクロ20121103 #odstudy できる! VBAマクロ
20121103 #odstudy できる! VBAマクロ
 
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
 
We Should Know About in this SocialNetwork Era 2011_1112
We Should Know About in this SocialNetwork Era 2011_1112We Should Know About in this SocialNetwork Era 2011_1112
We Should Know About in this SocialNetwork Era 2011_1112
 
全文検索入門
全文検索入門全文検索入門
全文検索入門
 
MTCafe sapporo#4
MTCafe sapporo#4MTCafe sapporo#4
MTCafe sapporo#4
 
Parseでちゃんとアプリを作るコツ
Parseでちゃんとアプリを作るコツParseでちゃんとアプリを作るコツ
Parseでちゃんとアプリを作るコツ
 
Lineにおけるspring frameworkの活用
Lineにおけるspring frameworkの活用Lineにおけるspring frameworkの活用
Lineにおけるspring frameworkの活用
 
高速処理と高信頼性を両立し、ペタバイト級の多種大量データを蓄積する、ビッグデータ/ IoT時代のデータベースとは??
高速処理と高信頼性を両立し、ペタバイト級の多種大量データを蓄積する、ビッグデータ/ IoT時代のデータベースとは??高速処理と高信頼性を両立し、ペタバイト級の多種大量データを蓄積する、ビッグデータ/ IoT時代のデータベースとは??
高速処理と高信頼性を両立し、ペタバイト級の多種大量データを蓄積する、ビッグデータ/ IoT時代のデータベースとは??
 
ElasticSearch勉強会 第6回
ElasticSearch勉強会 第6回ElasticSearch勉強会 第6回
ElasticSearch勉強会 第6回
 

トレタのMySQL MySQL casual #8