More Related Content Similar to MySQLの運用でありがちなこと (20) MySQLの運用でありがちなこと2. 自己紹介
• NEC soft: 2006/04〜2011/02
– Java, WebLogic, Apache, Oracle, HP-UX, RHEL
• CyberAgent: 2011/03〜
– Apache, MySQL, Some NoSQLs, Intra Automation,
Hardware Provisioning, CentOS
• WebSite:https://hiroakis.com/
5. 負荷とはなんなのか?
Application
MySQL
Query
MySQL
OS
Hardware(CPU, memory,
disk, NW)
Network
• 負荷とは、システムのどこかに存在するボトルネックのこと
– アプリケーションロジック, クエリ, MySQL, OS, CPU, Memory, Disk, Network…などなど
• ボトルネックを特定して、それを解消するのが負荷対策の基本。
6. ボトルネックを特定する
• Tools
– slow log、explain、show engine innodb status, pt-query-digest, innotop…etc
– munin, cacti, newrelic…etc
– top, sar, dstat, vmstat, mpstat, iostat…etc
8. SQL
• 最も重要
• ダメなSQLを治したら負荷が劇的に改善されたとかよくある
• ダメなSQLの特定
– スロークエリログを見る
– innotop, pt-query-digest, newrelicなどのツールを活用する
– Explainで実行計画を見る
• 対応
– インデックスを貼りなおす
– SQLの修正を行う
– テーブル構造を変える
– そもそも無駄なクエリは発行しない
9. SQL
• SQL自体は問題ないが突然ストールする場合がある
• ロックの確認
– show engine innodb status
– Innotop
– ロック競合の解析手順
• 参考:http://d.hatena.ne.jp/sh2/20090618
• Information_schema.innodb_trx,
Information_schema.innodb_locks,
Information_schema.innodb_lock_waits
• 対応
– アプリケーションロジックの変更も考慮する
– ストレージが遅くて待たされている可能性もある
10. ちょっと寄り道:JOINは遅いのか?
• Nested loop joinアルゴリズム
– http://dev.mysql.com/doc/refman/5.6/en/nested-loop-joins.html
for each row in t1 matching range {
for each row in t2 matching reference key {
for each row in t3 {
if row satisfies join conditions,
send to client
}
}
}
• t1でフェッチされるレコード数×t2でフェッチされるレコード数×t3でフェッチされ
るレコード数のループになる
• 逆に言えばそれぞれのテーブルでフェッチされるレコード数が少なければJOINは
遅くはない
• JOINは適切に使えば有用
• DB分割に対応しにくくなる、つまりスケーラビリティの確保の面からWeb業界では
JOIN禁止というところもある
11. MySQLの設定
• MySQLの設定そのもので劇的に性能が良くなる
事はほとんどない(強いて言うなら
innodb_buffer_pool_size)。
• たとえばinnodb_io_capacityを10000, 20000,
40000…と大きくしていっても性能が倍々になる
わけではない。
• SQLやハードウェアリソース(後述)の方が負荷の
原因として支配的になりやすい。
• 設定の勘所を抑えて、my.cnfが整備されている
前提でチューニングを行うと良い。
12. MySQLの設定
• 性能に効いてくる箇所は下記の表のあたり
• システム要件に応じて適切に設定する(信頼性を犠牲にして性能を向上させるもの
もあるので注意)
• MyISAMは別の設定が効いてくるが今回は割愛
• ★マークをつけたinnodb_buffer_pool_sizeとinnodb_flush_methodは最も重要
• innodb_buffer_pool_sizeは物理メモリの7〜8割にする
• innodb_flush_methodはO_DIRECTにする
max_connections
table_open_cache
sort_buffer_size
join_buffer_size
thread_cache_size
thread_concurrency
sync_binlog
innodb_buffer_pool_size(★)
innodb_log_file_size
innodb_flush_method(★)
innodb_thread_concurrency
innodb_flush_log_at_trx_commit
innodb_doublewrite
innodb_support_xa
innodb_read_io_threads
innodb_write_io_threads
innodb_io_capacity
13. OS
• 次の箇所を抑える
– ファイルシステム
– IOスケジューラ
– カーネルパラメータ
• vm.swappiness
14. OS
• ファイルシステム/IOスケジューラ
– ファイルシステム
• xfs or ext4
– ファイルシステムのオプション
• nobarrier, noatime
– IOスケジューラ(/sys/block/xxx/queue/scheduler)
• deadline or noop
– キューサイズ(/sys/block/xxx/queue/nr_requests)
• MyISAMでは効いてくる
15. OS
• IOスケジューラの違いによる性能評価の例
• 接続数が増えると、IOスケジューラのデフォルトであるcfqでは性能が劣化する
– ツール:sysbench
– CPU: Intel(R) Xeon(R) CPU E5620 2.40GHz
– memory: 8G
– SAS×4(RAID10)
– MySQL 5.5.24 InnoDB
ext4(noatime, nobarrier) xfs(noatime, nobarrier)
16. OS
• カーネルパラメータ
– vm.swappinessを適切にセットしてswapを防ぐ。
– vm.swappiness=0をセットする事でswapの発生を
抑えられる。
– 新しいカーネル(2.6.32-303〜)ではvm.swappiness
の挙動が変わっているので0 はやめる。
– 1〜10あたりの、0以外の小さい値にしとくと良い。
– 参考:
http://www.percona.com/blog/2014/04/28/oom-relation-
vm-swappiness0-new-kernel/
17. ハードウェア
• CPU, メモリ, Disk IO, Network IOに注目する
– 一昔前はDisk IOが問題になりがちだった
– 最近は大容量RAMの低価格化とFlashストレージ
のコモディティ化(AWSなどはデフォルトでSSDが選
択される)により、CPUが詰まることもしばしば。
– HDDを使う場合はライトキャッシュ付きのRAIDコン
トローラを用いる。
– sar, vmstat, mpstat, dstat, top, iostatなどよく知ら
れたLinux系コマンドでプロファイリングできる。
18. ハードウェア
• 負荷の箇所とアクセスパターンに応じて対策を行う。
• 参照系の対策はハードウェアの増設/増強で対応できるので比較的楽。
• 更新系の対策はマスタ分割が必要。メモリ増設やフラッシュの活用で
なんとかなる場合もあるが、分割しないとレプリケーション遅延の原因
にもなる。
• マスタ分割は参照系負荷の改善にも寄与する。
• マスタ分割する場合はトランザクション境界や、管理台数が増加する
ことなどを考慮する必要がある。
参照系負荷が支配的更新系負荷が支配的
CPU(user) ・スレーブを増設する・マスタ分割
Disk IO ・メモリを増やす->
innodb_buffer_pool_sizeを増やす
・フラッシュの活用
・マスタ分割
・参照分割
・メモリを増やす->
innodb_buffer_pool_sizeを増やす
・フラッシュの活用
・マスタ分割
Network ・Application <-> MySQL間で巨大すぎるデータのやりとりをしていないか?
・高速な回線の利用
19. キャッシュの活用
• キャッシュの有効活用は負荷対策として非常に効果がある
• 更新系が多い場合はキャッシュは効きづらい
• キャッシュを使用した時点で一貫性は崩れるので、アプリケーショ
ン側で整合性を意識する
Application
cache
MySQL
Reverse Proxy
Varnish,
apache(mod_cache),
nginx(proxy_cache)…etc
Application
cache
Memcached,
Redis…etc
25. トランザクションが巨大すぎる
• 巨大テーブルにalter tableしたとき
– オンラインスキーマチェンジの活用
– MySQL5.6〜ではオンラインでのalterが可能
• 大量のレコードを一度に更新したとき
– バッチなどでたまに見かける
– トランザクションをこまめに分割する
• たとえば…
• ×: 100000レコードを更新-> コミット
• ○: 1000レコードを更新-> コミットを100回繰り返す
26. スレーブのDisk IO
• スレーブのストレージのDisk IOがボトルネック
• フラッシュストレージを活用してIO待ちを減ら
す。
• それでもダメならマスタ分割して更新系クエリ
を散らす
28. Master – Slave間のネットワーク
• あまり発生しないが原因にはなりうる
• 日本– 海外でレプリケーションを組んでいる
場合など
• スレーブが多すぎてbinlogの転送がNW帯域
を圧迫してしまっている場合は孫スレーブを
作る事を検討する。