家計簿サービス
株式会社 Zaim
西本 航
500万ユーザに向けて
Aurora編
© 2016 Zaim Inc. All rights reserved.
自己紹介
2
エンジニア
iOS Web インフラ
株式会社 Zaim 西本航 (@watura)
© 2016 Zaim Inc. All rights reserved.
家計簿サービス 「Zaim」
3
クチコミで普及した国内最大級のオンライン家計簿
もうすぐ500万ダウンロード!!
info@zaim.net
一緒に働く仲間を募集中!
https://www.wantedly.com/companies/Zaim
© 2016 Zaim Inc. All rights reserved.
目次
5
•DB構成
•パーティション?
•危機到来
•DB分割
•Aurora移行
•発生した障害
しっかりとしたログがあったらよかったんですが,今回はそこまで気が回らなかった
のでありません
© 2016 Zaim Inc. All rights reserved.
DB構成
6
•おもに Amazon RDS for MySQL を利用
•user_id の Range でパーティションを設定
•家計簿情報はユーザごとで,他ユーザと交わらない
•対象DB:
•XXX億のレコード数
•膨大なI/O
•日々増大するレコード
© 2016 Zaim Inc. All rights reserved.
パーティション?
7
•データを特定のルールに従って格納すること
•userごとのデータを取得するとき早くなる
0から10
11から20
21から30
31から40
41から50
user_idが
user_id が 10 のデータ
user_id が 15 のデータ
user_id が 44のデータ
© 2016 Zaim Inc. All rights reserved.
パーティション?
8
•データを特定のルールに従って格納すること
•userごとのデータを取得するとき早くなる
→ user_id = 51のデータは???
0から10
11から20
21から30
31から40
41から50
user_idが
user_id が 10 のデータ
user_id が 15 のデータ
user_id が 44のデータ
© 2016 Zaim Inc. All rights reserved.
パーティション?
9
•データを特定のルールに従って格納すること
•userごとのデータを取得するとき早くなる
→ user_id = 51のデータは??? → エラー!
0から10
11から20
21から30
31から40
41から50
user_idが
user_id が 10 のデータ
user_id が 15 のデータ
user_id が 44のデータ
© 2016 Zaim Inc. All rights reserved.
最大ユーザ数危機
10
ダウンロード数が400万を超えている
パーティションの最大値を500万としている
© 2016 Zaim Inc. All rights reserved.
最大ユーザ数危機
11
ダウンロード数が400万を超えている
パーティションの最大値を500万としている
Zaimを使えないユーザが出てきてしまう危機
過負荷,容量不足などとは違う洒落にならない危機
まさかこれほどユーザが増えるとは
© 2016 Zaim Inc. All rights reserved.
alter tableすればいいじゃない
12
目的:パーティションを1000万ユーザまでにする
利用:pt-online-schema-change
テスト環境:(他にI/Oがない環境)
•何の問題もなく成功
テスト環境その2:(本番さながらなI/Oを用意)
•すごい勢いでデッドロックが発生
•失敗した
少ない知恵を絞って色々試したが全て失敗した
© 2016 Zaim Inc. All rights reserved.
迫り来る危機
13
一回の試行に数時間はかかる
レコード数は刻一刻と増える
© 2016 Zaim Inc. All rights reserved.
迫り来る危機
14
一回の試行に数時間はかかる
レコード数は刻一刻と増える
負荷は時間が経てば経つほど増える!
本当はやりたくないけど,
サービス停止メンテナンスをするしかない
© 2016 Zaim Inc. All rights reserved.
DB分割 開き直って!
15
•せっかく停止するんだから普段できないことを!
•DBが大きすぎるのが悪い → シャーディング
•シャーディング: DBの分割
今回やることは
•1つのDBを5つに分割 (mod(user_id, 5))
•auto_increment_offset
auto_increment_increment,
•サービス側が適切に接続するように設定
簡単だ!
© 2016 Zaim Inc. All rights reserved.
長い長い前置きが終わってAurora
16
•10月頭 試行錯誤してメンテするか!
•そういえば re: Invent がある.ちょっと待とう
© 2016 Zaim Inc. All rights reserved.
長い長い前置きが終わってAurora
17
•10月頭 試行錯誤してメンテするか!
•そういえば re: Invent がある.ちょっと待とう
•10月7日http://aws.typepad.com/aws_japan/2015/10/amazon-aurora-is-available-in-tokyo.html
•AuroraがTokyo Regionでも使えるだと!!
© 2016 Zaim Inc. All rights reserved.
Auroraいっちゃう?
18
•せっかく停止するんだから普段できないことを!
•部分的にAuroraにしてみる?
•ストレージが勝手にスケールするの嬉しい
•性能いいんだ?
•やるしかない!
•調査
•国内で大きなところが移行してないかなぁ
•安定動作するの?
→Tokyoリージョン出た当初,あんまり情報がなかった
•テーブルにアクセスできなくなることがあった
•alter tableを途中でキャンセルした時?
© 2016 Zaim Inc. All rights reserved.
移行手順
19
• 調査もそこそこに時間もないのでAuroraにする
•シャーディング 5台 → やっぱりしない
•やりたいことはパーティションを1000万にすること!
•手順はほとんど↓を参考に
「わずかなダウンタイムでの Amazon RDS MySQL または MariaDB
DB インスタンスへのデータのインポート」
• http://amzn.to/1PwbLoa
•いきなりはAurora信用しきれない
•MySQL+Auroraとして動かしてみる
© 2016 Zaim Inc. All rights reserved.
やったこと - 登場DB -
20
•元DB(A)
•(A)のMySQLレプリカ(B)
•(B)をもとに作ったMySQLインスタンス(C)
•(C)のSnapshotで作ったAuroraレプリカ(D)
(A)
(B)
(C) (D)
レプリカ
レプリカ
Aurora
アイコンサイズに意味はありません
© 2016 Zaim Inc. All rights reserved.
やったこと(1)
21
•(A)のRead Replica(B)を作る
•同期できたら(B)のReplicationをストップする
•(B)からデータをdumpする
•元DB(A)
•(A)のmysqlレプリカ(B)
•(B)をもとに作ったmysqlインスタンス(C)
•(C)のSnapshotで作ったAuroraレプリカ(D)
(A)
(B)
Dump
Replicate dump
© 2016 Zaim Inc. All rights reserved.
やったこと(2)
22
•(C)を作成する
•(C)にパーティションを1000万までにしたス
キーマを適用する
•(B)からdumpしたデータを(C)にinsertする
(C)
•元DB(A)
•(A)のmysqlレプリカ(B)
•(B)をもとに作ったmysqlインスタンス(C)
•(C)のSnapshotで作ったAuroraレプリカ(D)
Dump
Schema
replicaをalter partitionするよりこちらの方が早かった
© 2016 Zaim Inc. All rights reserved.
やったこと(3)
23
•(C)のSnapshotからAuroraDB(D)を作る
•(D)に不要なテーブルをBlackholeEngineにする
•(D)をCのRead Replicaにする
(C)
•元DB(A)
•(A)のmysqlレプリカ(B)
•(B)をもとに作ったmysqlインスタンス(C)
•(C)のSnapshotで作ったAuroraレプリカ(D)
(D)
Aurora
Read
Replica
© 2016 Zaim Inc. All rights reserved.
やったこと(4)
24
•(C)を(A)のRead Replicaにする
(C)
•元DB(A)
•(A)のmysqlレプリカ(B)
•(B)をもとに作ったmysqlインスタンス(C)
•(C)のSnapshotで作ったAuroraレプリカ(D)
(D)
Aurora
Read
Replica
(A)
Read
Replica
Access
© 2016 Zaim Inc. All rights reserved.
やったこと(5)
25
•サービス停止メンテ
•アプリ, サービスが(C)に接続するようにする
•(C)のReplicationをストップする
•一回目メンテ終了
(C)
•元DB(A)
•(A)のmysqlレプリカ(B)
•(B)をもとに作ったmysqlインスタンス(C)
•(C)のSnapshotで作ったAuroraレプリカ(D)
(D)
Aurora
Read
Replica
Access
(A)
© 2016 Zaim Inc. All rights reserved.
やったこと(6)
26
•停止メンテ2回目
•(D)のReplicationをやめる
•条件によって接続先を変更する
(C) (D)
Aurora
Access
•元DB(A)
•(A)のmysqlレプリカ(B)
•(B)をもとに作ったmysqlインスタンス(C)
•(C)のSnapshotで作ったAuroraレプリカ(D)
© 2016 Zaim Inc. All rights reserved.
使用感
27
•一つ小さいインスタンスにしてみた
•CPU利用率60-80%
•レスポンス,メモリ使用量は問題なし
•突発的な高負荷が怖いのでインスタンスサイズUP
→それでもCPU利用率はMySQL時より高い
•Failover早い およそ1minで切り替わる
•ほぼ障害に気付かれることなく切り替えられた
•インスタンスサイズの変更がやりやすかった
•テレビ露出にも耐えられた
•CPU利用率80%以上まで上がったが問題なし
© 2016 Zaim Inc. All rights reserved.
CPUの利用率
28
•リソースを最大限利用するように設計されている
•MySQLと比較すると利用率が高い傾向がある
•高い状態でもMySQLよりも性能が出る
•もしくは,性能劣化が緩やかである
•利用率が高い == あっぷあっぷ状態 ではない!
•モニタを眺めた時に高利用率は心臓に良くない気
がするので大きめなインスタンスに
© 2016 Zaim Inc. All rights reserved.
発生した障害
29
•突然Auroraが劇重になる
•Free Local Storageが枯渇
詳細にログを残しておいたらよかったんですが……
© 2016 Zaim Inc. All rights reserved.
突然Auroraが劇重になる
30
突然
•CPU使用率 100%
•show processlist → unauthenticated user 大量発生
•クエリが詰まる
•再起動すれば復活(特定のプロセスをkill すれば?)
みたいな状態に移行直後からちょくちょくなった
原因調査
•general log, slow queryをDBに出力させた
原因
•重い (全探索に近い) Selectクエリ
対策
•クエリの最適化
© 2016 Zaim Inc. All rights reserved.
Free Local Storageが枯渇
31
•突然Auroraが言う事を聞いてくれなくなる
•SQLコマンドが効かない
•show processlistも動かない
•前ページのように再起動したら復活する??
→Auroraが再起動しない. 失敗している
•原因解明よりも動くようにすることが先決
•リードレプリカを作成してみる
•最新のデータを諦めてBackupから復元
•Backupに接続する準備している間に再起動完了
© 2016 Zaim Inc. All rights reserved.
Free Local Storageが枯渇
32
•時間
•再起動: 40分
•レプリカ作成: 27分(再起動と同時?)
•バックアップから復元 20分
•原因
•モニタを眺めているとFree Local Storageが枯渇
•「突然Auroraが劇重になる」の時にログをtable
に書き出すようにしたままだったのが原因?
•対策
•ログをtableに書き出すのをやめた
•Free Local Storageを監視するようにした
© 2016 Zaim Inc. All rights reserved.
Free Local Storage??
33
•CloudWatchにある一要素
•モニタリングを表示した時には下の方にいる
•各インスタンスサイズで固定?
知らない子, 誰なんでしょう??
© 2016 Zaim Inc. All rights reserved.
補足 Free Local Storage
34
•各インスタンス付属のインスタンスストレージ
•tmpテーブル等一時的なテーブルデータを保存
•disk fullになると動作が不安定になってしまう
•この問題をAurora開発チームは認識しており、
修正を行っている最中だそうです
•「Aurora劇重」もこれが原因と考えられる
教えてもらいました
© 2016 Zaim Inc. All rights reserved.
まとめ
35
•パーティションを1000万にしようと思っていた
•最初はMySQLでシャーディング予定だった
•実施直前にTokyo RegionにAurora登場
•やっぱりAuroraにする!
•概ね問題なかったけど,ちょくちょく障害発生
•クエリの最適化不足
•人為的ミスによる障害
•以降は重大なエラーに遭遇していない気がする
info@zaim.net
一緒に働く仲間を募集中!
https://www.wantedly.com/companies/Zaim
info@zaim.net
ご静聴ありがとうございました
info@zaim.net
© 2016 Zaim Inc. All rights reserved.39

Zaim 500万ユーザに向けて〜Aurora 編〜

  • 1.
  • 2.
    © 2016 ZaimInc. All rights reserved. 自己紹介 2 エンジニア iOS Web インフラ 株式会社 Zaim 西本航 (@watura)
  • 3.
    © 2016 ZaimInc. All rights reserved. 家計簿サービス 「Zaim」 3 クチコミで普及した国内最大級のオンライン家計簿 もうすぐ500万ダウンロード!!
  • 4.
  • 5.
    © 2016 ZaimInc. All rights reserved. 目次 5 •DB構成 •パーティション? •危機到来 •DB分割 •Aurora移行 •発生した障害 しっかりとしたログがあったらよかったんですが,今回はそこまで気が回らなかった のでありません
  • 6.
    © 2016 ZaimInc. All rights reserved. DB構成 6 •おもに Amazon RDS for MySQL を利用 •user_id の Range でパーティションを設定 •家計簿情報はユーザごとで,他ユーザと交わらない •対象DB: •XXX億のレコード数 •膨大なI/O •日々増大するレコード
  • 7.
    © 2016 ZaimInc. All rights reserved. パーティション? 7 •データを特定のルールに従って格納すること •userごとのデータを取得するとき早くなる 0から10 11から20 21から30 31から40 41から50 user_idが user_id が 10 のデータ user_id が 15 のデータ user_id が 44のデータ
  • 8.
    © 2016 ZaimInc. All rights reserved. パーティション? 8 •データを特定のルールに従って格納すること •userごとのデータを取得するとき早くなる → user_id = 51のデータは??? 0から10 11から20 21から30 31から40 41から50 user_idが user_id が 10 のデータ user_id が 15 のデータ user_id が 44のデータ
  • 9.
    © 2016 ZaimInc. All rights reserved. パーティション? 9 •データを特定のルールに従って格納すること •userごとのデータを取得するとき早くなる → user_id = 51のデータは??? → エラー! 0から10 11から20 21から30 31から40 41から50 user_idが user_id が 10 のデータ user_id が 15 のデータ user_id が 44のデータ
  • 10.
    © 2016 ZaimInc. All rights reserved. 最大ユーザ数危機 10 ダウンロード数が400万を超えている パーティションの最大値を500万としている
  • 11.
    © 2016 ZaimInc. All rights reserved. 最大ユーザ数危機 11 ダウンロード数が400万を超えている パーティションの最大値を500万としている Zaimを使えないユーザが出てきてしまう危機 過負荷,容量不足などとは違う洒落にならない危機 まさかこれほどユーザが増えるとは
  • 12.
    © 2016 ZaimInc. All rights reserved. alter tableすればいいじゃない 12 目的:パーティションを1000万ユーザまでにする 利用:pt-online-schema-change テスト環境:(他にI/Oがない環境) •何の問題もなく成功 テスト環境その2:(本番さながらなI/Oを用意) •すごい勢いでデッドロックが発生 •失敗した 少ない知恵を絞って色々試したが全て失敗した
  • 13.
    © 2016 ZaimInc. All rights reserved. 迫り来る危機 13 一回の試行に数時間はかかる レコード数は刻一刻と増える
  • 14.
    © 2016 ZaimInc. All rights reserved. 迫り来る危機 14 一回の試行に数時間はかかる レコード数は刻一刻と増える 負荷は時間が経てば経つほど増える! 本当はやりたくないけど, サービス停止メンテナンスをするしかない
  • 15.
    © 2016 ZaimInc. All rights reserved. DB分割 開き直って! 15 •せっかく停止するんだから普段できないことを! •DBが大きすぎるのが悪い → シャーディング •シャーディング: DBの分割 今回やることは •1つのDBを5つに分割 (mod(user_id, 5)) •auto_increment_offset auto_increment_increment, •サービス側が適切に接続するように設定 簡単だ!
  • 16.
    © 2016 ZaimInc. All rights reserved. 長い長い前置きが終わってAurora 16 •10月頭 試行錯誤してメンテするか! •そういえば re: Invent がある.ちょっと待とう
  • 17.
    © 2016 ZaimInc. All rights reserved. 長い長い前置きが終わってAurora 17 •10月頭 試行錯誤してメンテするか! •そういえば re: Invent がある.ちょっと待とう •10月7日http://aws.typepad.com/aws_japan/2015/10/amazon-aurora-is-available-in-tokyo.html •AuroraがTokyo Regionでも使えるだと!!
  • 18.
    © 2016 ZaimInc. All rights reserved. Auroraいっちゃう? 18 •せっかく停止するんだから普段できないことを! •部分的にAuroraにしてみる? •ストレージが勝手にスケールするの嬉しい •性能いいんだ? •やるしかない! •調査 •国内で大きなところが移行してないかなぁ •安定動作するの? →Tokyoリージョン出た当初,あんまり情報がなかった •テーブルにアクセスできなくなることがあった •alter tableを途中でキャンセルした時?
  • 19.
    © 2016 ZaimInc. All rights reserved. 移行手順 19 • 調査もそこそこに時間もないのでAuroraにする •シャーディング 5台 → やっぱりしない •やりたいことはパーティションを1000万にすること! •手順はほとんど↓を参考に 「わずかなダウンタイムでの Amazon RDS MySQL または MariaDB DB インスタンスへのデータのインポート」 • http://amzn.to/1PwbLoa •いきなりはAurora信用しきれない •MySQL+Auroraとして動かしてみる
  • 20.
    © 2016 ZaimInc. All rights reserved. やったこと - 登場DB - 20 •元DB(A) •(A)のMySQLレプリカ(B) •(B)をもとに作ったMySQLインスタンス(C) •(C)のSnapshotで作ったAuroraレプリカ(D) (A) (B) (C) (D) レプリカ レプリカ Aurora アイコンサイズに意味はありません
  • 21.
    © 2016 ZaimInc. All rights reserved. やったこと(1) 21 •(A)のRead Replica(B)を作る •同期できたら(B)のReplicationをストップする •(B)からデータをdumpする •元DB(A) •(A)のmysqlレプリカ(B) •(B)をもとに作ったmysqlインスタンス(C) •(C)のSnapshotで作ったAuroraレプリカ(D) (A) (B) Dump Replicate dump
  • 22.
    © 2016 ZaimInc. All rights reserved. やったこと(2) 22 •(C)を作成する •(C)にパーティションを1000万までにしたス キーマを適用する •(B)からdumpしたデータを(C)にinsertする (C) •元DB(A) •(A)のmysqlレプリカ(B) •(B)をもとに作ったmysqlインスタンス(C) •(C)のSnapshotで作ったAuroraレプリカ(D) Dump Schema replicaをalter partitionするよりこちらの方が早かった
  • 23.
    © 2016 ZaimInc. All rights reserved. やったこと(3) 23 •(C)のSnapshotからAuroraDB(D)を作る •(D)に不要なテーブルをBlackholeEngineにする •(D)をCのRead Replicaにする (C) •元DB(A) •(A)のmysqlレプリカ(B) •(B)をもとに作ったmysqlインスタンス(C) •(C)のSnapshotで作ったAuroraレプリカ(D) (D) Aurora Read Replica
  • 24.
    © 2016 ZaimInc. All rights reserved. やったこと(4) 24 •(C)を(A)のRead Replicaにする (C) •元DB(A) •(A)のmysqlレプリカ(B) •(B)をもとに作ったmysqlインスタンス(C) •(C)のSnapshotで作ったAuroraレプリカ(D) (D) Aurora Read Replica (A) Read Replica Access
  • 25.
    © 2016 ZaimInc. All rights reserved. やったこと(5) 25 •サービス停止メンテ •アプリ, サービスが(C)に接続するようにする •(C)のReplicationをストップする •一回目メンテ終了 (C) •元DB(A) •(A)のmysqlレプリカ(B) •(B)をもとに作ったmysqlインスタンス(C) •(C)のSnapshotで作ったAuroraレプリカ(D) (D) Aurora Read Replica Access (A)
  • 26.
    © 2016 ZaimInc. All rights reserved. やったこと(6) 26 •停止メンテ2回目 •(D)のReplicationをやめる •条件によって接続先を変更する (C) (D) Aurora Access •元DB(A) •(A)のmysqlレプリカ(B) •(B)をもとに作ったmysqlインスタンス(C) •(C)のSnapshotで作ったAuroraレプリカ(D)
  • 27.
    © 2016 ZaimInc. All rights reserved. 使用感 27 •一つ小さいインスタンスにしてみた •CPU利用率60-80% •レスポンス,メモリ使用量は問題なし •突発的な高負荷が怖いのでインスタンスサイズUP →それでもCPU利用率はMySQL時より高い •Failover早い およそ1minで切り替わる •ほぼ障害に気付かれることなく切り替えられた •インスタンスサイズの変更がやりやすかった •テレビ露出にも耐えられた •CPU利用率80%以上まで上がったが問題なし
  • 28.
    © 2016 ZaimInc. All rights reserved. CPUの利用率 28 •リソースを最大限利用するように設計されている •MySQLと比較すると利用率が高い傾向がある •高い状態でもMySQLよりも性能が出る •もしくは,性能劣化が緩やかである •利用率が高い == あっぷあっぷ状態 ではない! •モニタを眺めた時に高利用率は心臓に良くない気 がするので大きめなインスタンスに
  • 29.
    © 2016 ZaimInc. All rights reserved. 発生した障害 29 •突然Auroraが劇重になる •Free Local Storageが枯渇 詳細にログを残しておいたらよかったんですが……
  • 30.
    © 2016 ZaimInc. All rights reserved. 突然Auroraが劇重になる 30 突然 •CPU使用率 100% •show processlist → unauthenticated user 大量発生 •クエリが詰まる •再起動すれば復活(特定のプロセスをkill すれば?) みたいな状態に移行直後からちょくちょくなった 原因調査 •general log, slow queryをDBに出力させた 原因 •重い (全探索に近い) Selectクエリ 対策 •クエリの最適化
  • 31.
    © 2016 ZaimInc. All rights reserved. Free Local Storageが枯渇 31 •突然Auroraが言う事を聞いてくれなくなる •SQLコマンドが効かない •show processlistも動かない •前ページのように再起動したら復活する?? →Auroraが再起動しない. 失敗している •原因解明よりも動くようにすることが先決 •リードレプリカを作成してみる •最新のデータを諦めてBackupから復元 •Backupに接続する準備している間に再起動完了
  • 32.
    © 2016 ZaimInc. All rights reserved. Free Local Storageが枯渇 32 •時間 •再起動: 40分 •レプリカ作成: 27分(再起動と同時?) •バックアップから復元 20分 •原因 •モニタを眺めているとFree Local Storageが枯渇 •「突然Auroraが劇重になる」の時にログをtable に書き出すようにしたままだったのが原因? •対策 •ログをtableに書き出すのをやめた •Free Local Storageを監視するようにした
  • 33.
    © 2016 ZaimInc. All rights reserved. Free Local Storage?? 33 •CloudWatchにある一要素 •モニタリングを表示した時には下の方にいる •各インスタンスサイズで固定? 知らない子, 誰なんでしょう??
  • 34.
    © 2016 ZaimInc. All rights reserved. 補足 Free Local Storage 34 •各インスタンス付属のインスタンスストレージ •tmpテーブル等一時的なテーブルデータを保存 •disk fullになると動作が不安定になってしまう •この問題をAurora開発チームは認識しており、 修正を行っている最中だそうです •「Aurora劇重」もこれが原因と考えられる 教えてもらいました
  • 35.
    © 2016 ZaimInc. All rights reserved. まとめ 35 •パーティションを1000万にしようと思っていた •最初はMySQLでシャーディング予定だった •実施直前にTokyo RegionにAurora登場 •やっぱりAuroraにする! •概ね問題なかったけど,ちょくちょく障害発生 •クエリの最適化不足 •人為的ミスによる障害 •以降は重大なエラーに遭遇していない気がする
  • 36.
  • 37.
  • 38.
  • 39.
    © 2016 ZaimInc. All rights reserved.39