Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ISUCON入門

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →
Avatar for てとらぽ てとらぽ
August 29, 2024
180

 ISUCON入門

Avatar for てとらぽ

てとらぽ

August 29, 2024

Transcript

  1. 3. ベンチマークを動かしてみる[3/3] 内容を確認 { "pass":true, →ステータス:合格 "score":626, →点数:626点 "success":582, "fail":3,

    "messages":[ "リクエストがタイム アウトしました (POST /login)", "リクエストがタイムアウトしました (POST /register)" ] }
  2. 2. MySQLを早くする[1/8] • MySQLのログ出力を有効化 ◦ MySQLの設定ファイル(/etc/mysql/mysql.conf.d/mysqld.cnf)に追記 slow_query_log = 1 #

    ログ出力を有効化 slow_query_log_file = /var/log/mysql/mysql-slow.log # ログの保存場所を指定 long_query_time = 0 # 0秒以上かかる処理(=全部)を出力
  3. 2. MySQLを早くする[2/8] 処理に時間がかかった順にログを簡略に表示 isucon@main:/var/log/mysql$ sudo mysqldumpslow /var/log/mysql/mysql-slow.log Reading mysql slow

    query log from /var/log/mysql/mysql-slow.log Count: 1315 Time=0.04s (53s) Lock=0.00s (0s) Rows=2.7 (3576), isuconp[isuconp]@localhost SELECT * FROM `comments` WHERE `post_id` = N ORDER BY `created_at` DESC LIMIT N →この処理が重いとわかる Count: 17 Time=0.04s (0s) Lock=0.00s (0s) Rows=7.1 (121), isuconp[isuconp]@localhost SELECT * FROM `comments` WHERE `post_id` = N ORDER BY `created_at` DESC Count: 1 Time=0.02s (0s) Lock=0.00s (0s) Rows=0.0 (0), isuconp[isuconp]@localhost DELETE FROM posts WHERE id > N Count: 2 Time=0.02s (0s) Lock=0.00s (0s) Rows=9982.0 (19964), isuconp[isuconp]@localhost SELECT `id`, `user_id`, `body`, `mime`, `created_at` FROM `posts` WHERE `created_at` <= 'S' ORDER BY `created_at` DESC ~以下略~
  4. 2. MySQLを早くする[3/8] さっきの簡略版で見つけた重い処理を詳細に表示 ↓ 3行の結果を得るために100003回も処理をしてる # Time: 2024-08-25T14:23:36.761267Z # User@Host:

    isuconp[isuconp] @ localhost [] Id: 9 # Query_time: 0.040491 Lock_time: 0.000002 Rows_sent: 3 Rows_examined: 100003 SET timestamp=1724595816; SELECT * FROM `comments` WHERE `post_id` = 9998 ORDER BY `created_at` DESC LIMIT 3;
  5. 2. MySQLを早くする[4/8] 処理(DBのクエリ)がどのように実行されるのか見る ↓ 本(commentテーブル)に目次(key)が無いから、 全ページ(99666)見て、目的のページ(`post_id` = 9998)を探してる mysql> explain

    SELECT * FROM `comments` WHERE `post_id` = 9998 ORDER BY `created_at` DESC LIMIT 3; | id | select_type | table | partitions | type | possible_keys | key | rows | —-------------------------------------------------------------------------------------------------------- | 1 | SIMPLE | comments | NULL | ALL | NULL | NULL | 99666|
  6. 2. MySQLを早くする[5/8] commentテーブルの作りを見る ↓ 目次(KEY)がidしか設定されてない 目次(KEY)にpost_idも必要 mysql> show create table

    comments¥G *************************** 1. row *************************** Create Table: CREATE TABLE `comments` ( ~略~ PRIMARY KEY (`id`) )
  7. 2. MySQLを早くする[7/8] 改めて、commentテーブルの作りを見る mysql> show create table comments¥G ▪前 ***************************

    1. row *************************** Create Table: CREATE TABLE `comments` ( PRIMARY KEY (`id`) ) ▪後 *************************** 1. row *************************** Create Table: CREATE TABLE `comments` ( PRIMARY KEY (`id`), KEY `index_post_id` (`post_id`) ) ↓ 目次(KEY)が追加された
  8. 2. MySQLを早くする[8/8] 改めて、処理(DBのクエリ)がどのように実行されるのか見る mysql> explain SELECT * FROM `comments` WHERE

    `post_id` = 9998 ORDER BY `created_at` DESC LIMIT 3; ▪前 | id | table | possible_keys | key | rows | —--------------------------------------------------------------------- | 1 | comments | NULL | NULL | 99666| ▪後 | id | table | possible_keys | key | rows | —---------------------------------------------------------------------- | 1 | comments |index_post_id | index_post_id | 4 | ↓ 99666ページみてたのが4ページになった
  9. 3. 再度ベンチマークを回す[5/5] Iscogram、まだ出来ることが沢山ある • 初期状態(約650点) • commentテーブルにインデックスを追加する(約7000点) • unicorn workerプロセスを4にする(約15,000点)

    • 静的ファイルをnginxで配信する(約17,000点) • アップロード画像を静的ファイル化する(約22,000点) • GET / を解析する(約点) • postとuserをJOINして必要な行数だけ取得する(約90,000点) • ベンチマーカーが使用するファイルディスクリプタ上限を増加させる • プリペア度ステートメントを改善する(約110,000点) • commentテーブルにインデックスを追加する(約115,000点) • postからのN+1クエリ結果をキャッシュする(約180,000点) • 適切なインデックスが使えないクエリを解決する(約200,000点) • 外部コマンドの呼び出しをやめる(約240,000点) • MySQLの設定を調整する(約255,000点) • memcachedへのN+1を解消する(約300,000点) • RubyのYJITを有効にする(約320,000点) ※今日やったのはココ ※ISUCON本参照