エンジニア勉強会 in PIXIV DEV MEETUP ( https://conference.pixiv.co.jp/2021/dev-meetup )で喋ったLT資料です。
Sentry GKEに リプレイス1年間の 知見見せます2021/05/12 エンジニア勉強会@PIXIV DEV MEETUPpixiv Inc.sue4452021.5.12
View Slide
2自己紹介● sue445● 2018年7月入社○ もうすぐ4年目● インフラ部所属● #z-アニメ, #z-precure, #z-pretty-seriessue445
3● AWS, GCP, CI, GitLab, Sentry etc…● 最近は各チームがやりたいことに対してAWS, GCP, オンプレでいくつか案を出してアドバイスしたり、実際に自分でシステムを構築● 例)オンプレで動いてたSentryをGKEに移行、Herokuで動いてたアプリをECSに移行● publicな業務内容: https://inside.pixiv.blog/search?q=sue445業務内容
4● AWS, GCP, CI, GitLab, Sentry etc…● 最近は各チームがやりたいことに対してAWS, GCP, オンプレでいくつか案を出してアドバイスしたり、実際に自分でシステムを構築● 例)オンプレで動いてたSentryをGKEに移行、Herokuで動いてたアプリをECSに移行● publicな業務内容: https://inside.pixiv.blog/search?q=sue445業務内容
5● Sentryとは?● 劇的Before/After● リプレイスについて● Datadogで見る1年間● Sentryをリプレイスしたことによるメリット● 今後の課題Agenda
6● アプリケーションのエラーを収集するウェブアプリ○ https://docs.sentry.io/● クライアントライブラリが充実しててメジャーどころの言語は全部対応してる● SaaS(https://sentry.io/)が有名だが、Sentry自体もOSSなので自分でホスティングすることもできる○ https://develop.sentry.dev/self-hosted/○ https://github.com/getsentry/onpremise○ https://hub.docker.com/r/getsentry/sentry● 似たようなアプリとしてAirbrake, Errbit, RollberなどがあるがSentryが一番メジャーだと思うSentryとは?
7● Before : オンプレのサーバ1台○ そんなにスペックは高くない○ アプリとミドルウェア一式がdocker-composeで雑に実行● After : 全てGCP○ GKE○ Cloud SQL for PostgreSQL○ Cloud Memorystore for Redis○ 業務でGCPやkubernetesを使ったのはこれが初めて劇的Before/After
8● オンプレのSentryのスペックがそんなに高くないので、どこかのアプリでエラーが大量に発生すると高負荷で他アプリにも通知遅延などの影響が出る問題があった● ストレージの容量が逼迫してた○ 試算したらこのまま行くと3ヶ月くらいでdisk fullになりそうだったので「100日後に死ぬサーバです(なので早く新Sentryに移行してください)」って全社アナウンスした● 2019年末にインフラ部内で来期(FY2020)の予算計画を立てることになって、そのタイミングでリプレイスすることにしたリプレイスの理由
9● リプレイスの際に下記の3つで検討した○ SaaS○ Self hosting (オンプレ)○ Self hosting (クラウド)● 最終的には「Self hosting (クラウド)」を選択したのだが、そこに至るまでの変遷を紹介実装&選択方針
10● オンプレ単一サーバ構成○ 構成が同じだとスペックだけ上げてもいずれは頭打ちになるのでスケールアウトをしたい● オンプレ複数サーバ構成○ SentryがDockerイメージ利用を推奨してるのだが、オンプレでDockerのクラスタを自前で管理しようとすると実行環境以外にもサーバが必要で台数がかさむ○ kubernetesだとクラスタの管理で最低3台必要になる● オンプレだとアプリで急激にエラーが増えた場合に増設しづらい【ボツ案】Self hosting (オンプレ)
11● SaaS案だと旧Sentryのイベント数(2019年末時点で1,500万イベント)で月1万ドルの試算になったので費用感が合わなかった● 問い合わせたらディスカウントでも月2,800ドルくらいだった○ 費用面だけならGKE案と割といい線いってた● アプリからパスワードなどの機微情報を含むエラーが送られた場合にsentry.ioに機微情報が保存されてしまうので、(オンプレ使うにしろクラウド使うにしろ)SaaSよりも自前のサーバで管理するのがよいと判断【ボツ案】SaaS
12● クラウドのフルマネージドのDockerクラスタで作るのが前述の問題を解決でき、アーキテクチャ的にも筋が良さそうだった○ SentryのHelm chartがあったのが一番大きい(後述)● この時点でEKS(AWSのKubernetes)かGKE(GCPのKubernetes)の二択になったが、自分自身とインフラ部内でのGCPの運用経験値を貯めるためにGKEを選択した○ 「知らないからやらなかったら一生新しいことはできない」 が持論なので、敢えてやったことないものを使いたかった○ EKSとGKEで費用的にはそんなに変わらなかった【採用】Self hosting (クラウド)
13GKE版Sentryの構成Cloud SQL(PostgreSQL)Cloud Memorystore(redis)GCSGKEnode x 20台以上pod x 60〜100台くらい
14● ウェブアプリケーションが動く環境を全部作った○ 新sentryのドメイン取得○ GCPのプロジェクトを作成してインフラを全て作った○ Sentry本体のデプロイsue445がやったこと
15● 2020年1月:新Sentryの開発開始● 2020年2月:本番環境が完成し、一部のアプリのみ新Sentryを開放○ 自分がメンテしてたアプリと旧Sentryで一番エラーの多かったアプリ● 2020年3月:新Sentryを全社に開放リリースノート
16● GCPもkubernetesも全く分からない状態● Google App Engineは趣味で多少使ったことはあったけど、GCPのプロジェクト全体をガッツリ触ったのは今回が初めて● 1ヶ月でブラウザで一通り動く状態の開発環境を作りきった開発当初のsue445の経験値
17https://www.credential.net/9643f19d-5584-40b6-a330-5b966a26f310【余談】GCP赤ちゃんの状態から1年で認定資格をとった
18● Terraformリポジトリ:GCPのインフラ全般○ Deployment Manager(GCP公式の構成管理ツール)を使うという選択肢もあったが、TerraformだとAWSとGCPの両方に対応していて運用コストや学習コストが抑えられた○ ピクシブではAWSとGCPの両方運用してるので同じツールでやりたい● Dockerイメージ:アプリケーション本体○ 公式のDockerイメージだとGCS対応に必要なライブラリがなくて自分でビルドした● デプロイ用リポジトリ:アプリケーションの実行環境○ KubernetesにはHelmという公式パッケージマネージャがあり、そこで配布されてるHelm chartをCIでデプロイしてる作ったもの
19● 開発環境:masterブランチが自動デプロイ、必要に応じてトピックブランチを手動デプロイ● 本番環境:必要に応じてmasterブランチを手動デプロイするデプロイフロー
201. 最初はdevelopブランチを開発環境に自動デプロイ、masterブランチをproductionに自動デプロイにしてたのだが、git-flowが社内ではあまり浸透してなくて自分以外がブランチ運用できる気がしないので途中でやめた2. 次は開発環境と本番両方手動デプロイにしてたのが、開発環境デプロイするのに毎回デプロイボタンをポチるのが面倒なのでやめた3. そして今の構成(開発環境は自動or手動デプロイ、本番環境は手動デプロイ)に落ち着いたデプロイフローの歴史
21● 1年間運用してどのように成長したのかを紹介Datadogで見る1年間
22● オートスケールによって常時20〜30台くらい稼働してる● VMが増えすぎるとDatadogのコストになるため台数が増えすぎないようにVMをスペックアップしてる● 例)「n1-standard-1のVM2台」と「n1-standard-2のVM1台」とではGCEの金額は同じなのだが、Datadog agentは監視する台数によって変わるので後者の方が安くなるGKE: node(VM)
23● GKEのnode全体で初期は20コアくらい、 今は200コアくらい● 去年6月に増えてるのはpodが自動で増えずに無理やり増やしたためGKE: vCPU
24● GKEのnode全体で200〜400GBくらい● 4月にガクッと減ってるのは、nodeのスペックを調整したため(後述)GKE: Memory
25● Sentryのpodのスペックを細かく調整していった結果、CPUに対してメモリが無駄になってたので調整した● Before: n1-highmem-8 (メモリ52GB)● After: n1-custom-16-30720 (n1-standard-16の半分のメモリ)GKE: Memory
26● web(httpのリクエストを受けるpod)が50〜60個、worker(エラーをバックグラウンドで処理するpod)が20〜30個くらいGKE: pods
27● 1年間で約100GBくらい● 上の線がCloud SQLに割り当てられたストレージサイズで、下の線が実際に使用してるストレージサイズ。(容量逼迫すると自動でストレージが増えて便利)Cloud SQL(PostgreSQL): ストレージ
28● 100〜200万くらいのkey● 一気にKeyが0になってるのはSentryのqueueが詰まってRedisのメモリが溢れて死んだ時や、メモリが溢れる直前にflushallした時Memorystore (Redis): Keyの数
29● 今はだいたい200万くらいのオブジェクト数● Datadogだとバケット全体のサイズが取れないのでGCPのコンソールで確認したら66GiBくらいだったGCS: オブジェクト数
30● リプレイス前はオンプレサーバのストレージサイズを逼迫してたが、リプレイス後はCloudSQLやGCSにデータが保存されるので容量問題が完全に解決した● 全てをクラウドに移したことによりSentry全体のスペック変更がしやすくなった● GKEのオートスケールにより社内の利用状況やエラーの量によって自動でサーバが増減するようになった● インフラ部内でのGCPやKubernetesの運用経験値が上がったSentryをリプレイスしたことによるメリット
31● GKEのオートスケールで無限にサーバを増やせると思ったが、サーバを増やしすぎるとDBやRedisが高負荷になってSentryの挙動がおかしくなるのであまり増やせない○ 特にSentryはRedisをヘビーに使ってる○ DBやRedisのスペックを上げるとお金がかかる● pgbouncerを入れてPostgreSQLのコネクションをプールしてるのだが、INSERT時には効かないのでエラーが大量に飛んできた時にPostgreSQLのコネクションが枯渇するSentryを1年間運用しての学び
32● サーバサイドのエラーよりもフロントエンドのエラーの方がSentryに飛んでくる圧倒的にエラーが多い○ サーバサイドのエラーは送信元がピクシブのサーバだけだが、フロントエンドのエラーはユーザのブラウザからSentryにリクエストが飛んでくるため○ アプリだけじゃなく広告系のjsがエラーになってもSentryにエラーが飛んでくるのでつらい○ jsのエラーが大量発生した時にSentryが死ぬことがしょっちゅうあったのでReteLimitを設定するようにしてるSentryを1年間運用しての学び
33● Sentryのメジャーバージョンアップ○ 今ピクシブで使ってるのは9系なので最新まで上げたいのだが、今使ってるhelm chart( https://github.com/helm/charts/tree/master/stable/sentry )だと最新版に対応していないのでhttps://github.com/sentry-kubernetes/charts に移行する必要があって大変今後の課題