Google Cloud Platform Japan Blog
最新情報や使い方、チュートリアル、国内外の事例やイベントについてお伝えします。
信頼性の高いリリースとロールバック : CRE が現場で学んだこと
2017年4月10日月曜日
編集部注 :
サービス停止の原因としてよくあることの 1 つに、サービス バイナリの新リリースが挙げられます。どれだけテストや QA をきちんと行っていても、一部のバグは、その影響を受けるコードが稼働するまで表面に出てこないものなのです。
Google の Site Reliability Engineering
(SRE)チームは、リリースに起因するサービス停止を長きにわたって数多く見てきており、今ではすべての新リリースに 1 つ以上のバグが含まれていると考えています。
ソフトウェア開発者は皆、自分のサービスに新しい機能を追加したいと思うものです。とはいえ、すべてのリリースには不具合のリスクがつきものです。変更個所をカバーするユニット テストや機能テストを追加し、システムのパフォーマンスに何か重大な影響が出ないか把握するために負荷テストを実施したとしても、本番環境でのトラフィックに驚かされることがあるのです。そのときの驚きは、通常あまり気持ちのいいものではありません。
新しいバイナリのリリースによってサービスが停止するというのは、よくあることです。システムの信頼性を担当するエンジニアの観点から見ると、このときの対応には次の 3 つの基本的なタスクが必要となります。
新しいリリースが実際にいつ壊れたのかを把握する
壊れたリリースから、修正された「であろう」リリースへとユーザーを安全に移行させる
最初の段階で壊れたリリースの影響を受けるクライアントの数を抑えるようにする(「カナリア リリース」を実施する)
今回の分析では、
nginx
などのロード バランサの背後にあるマシンや VM で多くのサービス インスタンスを稼働させるとともに、新しいバイナリのためにサービスをアップグレードするときは各サービス インスタンスを一度停めてからスタートする必要があると仮定します。
また、Stackdriver のようなツールを使用してシステムを監視し、内部のトラフィックやエラー率を計測することも前提としています。このようなモニタリング ツールがない場合は、信頼性について意味のある議論をすることが困難なのです。
SRE の書籍
に書かれている “
Hierarchy of Reliability
”(信頼性の階層)によると、モニタリングは信頼性の高いシステムにとって最も基本的な要件です。
検知
不具合のあるリリースにとっていちばん好都合なケースは、そのリリースによってサービス インスタンスが再スタートすることです。そうすると、不適切に処理されたリクエストの大半は HTTP 502 などのエラーを出すか、レスポンスのレイテンシが非常に高くなります。この場合、サービス インスタンスのロールアウトが進むにつれて全体のサービス エラー率が高まるので、リリースに問題があると気づくのです。
もっと微妙なのは、新しいバイナリが比較的少ない一部のクエリに対してエラーを返すケースです。たとえば、ユーザー設定の変更リクエストや、正当な理由が
ある
にしろ
ない
にしろ、名前にアポストロフィーが付いているユーザーだけがエラーになったとしましょう。こうした不具合は、サービス インスタンスの大半がアップグレードされ、総合的なモニタリングを実施して初めてわかることです。そのため、サービス インスタンスのエラーやレイテンシのサマリーをバイナリ リリースのバージョンごとに分類しておくと便利です。
ロールバック
新しいバイナリやイメージをサービスにロールアウトする前に、自分自身に問いかけてみてください。「このリリースに致命的なバグや気が滅入るようなバグ、迷惑なバグがあったらどうするべきか」と。このようなことが起こる可能性があるから考えるのではなく、早かれ遅かれこのような事態は避けられないことだとして、サービスが炎上する前に綿密な計画を立てておいたほうがよいのです。
バグが見つかっても特にそれが致命的ではないときは、すぐにパッチを作成し前に進みたいと思うものです。つまり、バグを修正するための最小限のコードを元のリリースに追加し、そこから新しいリリースを作るということです(修正の「選り好み」)。
ただし、この方法は一般的にあまりお勧めしません。特に、そのバグがユーザーにも見えるようなものだったり、(たとえばクエリのリソース コストが 2 倍になるなど)内部的に重大な問題を起こしていたりする場合は推奨できません。
なぜ前に進んではいけないのでしょうか。それは、ソフトウェア開発者の身になって考えてみると理解できるはずです。
あなたの机の横で飛び跳ねている上司の血圧が見るからに上がっていき、修正版がリリースされるのはいつだと聞いてきます。会社のプロダクト ディレクターがその上司に対し、ユーザーから苦情が来ているとうるさく言っているためです。このままでは毎分 1,000 人単位のユーザーがサービス エラーに遭遇することになるので、あなたには修正版に向けたコーディングを最速で行うことが求められます。このようなプレッシャーの中では、コーディングやテスト、デプロイにおいて間違いが発生することはほとんど避けられないでしょう。
このような状況を Google で何度も見てきました。前に進むべく急いでデプロイした修正版が元の問題を修正できなかったり、さらに状況を悪化させたりといったことがありました。
万が一、その修正版で問題が解決しても、システム内に潜んだ別のバグが後になって見つかることもあります。つまり、よくわかっている状態から、定期的に QA テストを実施する対象となっていない、いわば野生の世界へと引きずり込まれていくのです。
Google には「ロールバックは普通だ」という哲学があります。新しいリリースにエラーが見つかったりエラーが疑われたりすると、リリースを担当したチームは最初にロールバックを行い、次に問題を調査します。
ロールバックをお願いすることが、リリース担当チームや、バグを含んだコードを書いた開発者への攻撃だと見なされることはありません。むしろ、ユーザーにとってシステムをできるだけ信頼できるものにするための正しい行為だと考えられているのです。発見された問題がロールバックの変更リストに記述されている限り、「なぜこの変更をロールバックしたんだ?」などと言う人は誰もいません。
そこで、ロールバックを成功させるには、次のような点を暗黙の了解としておくべきでしょう。
簡単に実行できる
低リスクであると確信できる
この 2 つ目の項目を実現するにはどうすればよいのでしょうか。
ロールバックのテスト
もし数週間にわたってロールバックしていないのであれば、とにかくロールバックしてみましょう。互換性のないバージョンや、故障した自動化 / テストなどの落とし穴をすべて見つけられるようにするのです。
ロールバックがうまくいけば、すべてのログやモニタリングを確認したうえで再度前に進みましょう。ロールバックがうまくいかない場合は、前に進んで不具合を取り除き、ロールバックが失敗した原因を突き止めることに全力を尽くします。新しいリリースが火を噴いてサービスが強制的に停止したからといって、よくわかっている元のリリースに戻ろうとするのはいただけません。それよりも、新しいリリースがきちんと動いている間に不具合を見つけるほうが、ずっといいのです。
互換性のない変更
ロールバックが簡単にいかないことも必ずあります。たとえば、新しいリリースにてアプリのデータベース内に(新しいコラムといった)スキーマの変更が必要となるケースです。ここで危険なのは、新しいバイナリをリリースし、データベースのスキーマをアップグレードした後で、ロールバックが必要となるようなバイナリの問題が見つかることです。こうなると、新しいスキーマを受け付けず、テストもされていないバイナリが存在しているだけとなります。
このとき推奨される方法としては、機能なしのリリースを出すことです。バイナリのバージョン v から開始し、新しいデータベースのスキーマを安全に扱えること以外は v とまったく同じである新しいバージョン v+1 を構築しましょう。新しいスキーマを活用する新機能はバージョン v+2 に入ります。これにより、ロールアウトの計画は以下のようになります。
バイナリ v+1 をリリースする
データベースのスキーマをアップグレードする
バイナリ v+2 をリリースする
これで、新しいバイナリのいずれかに問題があった場合、スキーマをロールバックすることなく前のバージョンにロールバックできるようになります。
ここで、より一般的な問題での特別なケースについて話しましょう。サービスの依存関係をグラフ化し、直接的な依存関係をすべて特定するときには、依存関係のいずれかが突然オーナーによってロールバックされた場合にどうするか計画を立てる必要があります。依存関係にあるサービス S のバージョンが r から r+1 になってからリリースしようとしているのであれば、S がバージョン r+1 でずっと「とどまる」ことを確認しておかなくてはなりません。
考えられる方法としては、どんなサービスもひとつ前のバージョンにロールバックする可能性があるといったエコシステムを想定することです。つまり、この場合は自分のサービスが r+1 の機能に依存するバージョンへと移る前に、S がバージョン r+2 になるのを待つということです。
まとめ
今回わかったことは、リリースに対応するロールバックの準備ができていない限り、優れたリリースにはならないということです。とはいえ、不具合のあるリリースによってサービス全体が影響を受けるのを回避しつつ、その中でロールバックするタイミングを見極めるにはどうすればよいのでしょうか。
この投稿のパート 2 では、カナリア リリース戦略を紹介します。これは、新しいリリースにおける稼働トラフィックのほとんどを危険にさらすことなく、実際の稼働段階での問題を検知する方法です。
* この投稿は米国時間 3 月 24 日、Customer Reliability Engineer である Adrian Hilton によって投稿されたもの(投稿は
こちら
)の抄訳です。
- By Adrian Hilton, Customer Reliability Engineer
0 件のコメント :
コメントを投稿
12 か月間のトライアル
300 ドル相当が無料になるトライアルで、あらゆる GCP プロダクトをお試しいただけます。
Labels
.NET
.NET Core
.NET Core ランタイム
.NET Foundation
Access Management
AlphaGo
Anvato
Apache Beam
Apache Maven
API
Apigee
APIs Explore
App Engine
App Engine Flex
App Engine flexible
AppArmor
AppScale
AR
Artifactory
ASP.NET
ASP.NET Core
Attunity
AWS
Big Data
BigQuery
Billing Alerts
Bime by Zendesk
Bitbucket
Borg
BOSH Google CPI
Bower
BreezoMeter
BYOSL
Capacitor
Client Libraries
Cloud API
Cloud Audit Logging
Cloud Bigtable
Cloud CDN
Cloud Client Libraries
Cloud Console
Cloud Consoleアプリ
Cloud Dataflow
Cloud Dataflow SDK
Cloud Datalab
Cloud Dataprep
Cloud Dataproc
Cloud Datastore
Cloud Debugger
Cloud Deployment Manager
Cloud Endpoints
Cloud Foundry
Cloud Foundry Foundation
Cloud Functions
Cloud Identity
Cloud Jobs API
Cloud KMS
Cloud Load Balancing
Cloud Machine Learning
Cloud monitoring
Cloud Natural Language API
Cloud Networking
cloud Pub/Sub
Cloud Resource Manager
Cloud Resource Manager API
Cloud SDK
Cloud SDK for Windows
Cloud Source Repositories
Cloud Spanner
Cloud Speech API
Cloud SQL
Cloud Storage
Cloud Storage FUSE
Cloud Tools for PowerShell
Cloud Tools PowerShell
Cloud Translation
Cloud Translation API
Cloud Virtual Network
Cloud Vision
CloudBerry Backup
CloudBerry Lab
CloudEndure
Cloudian
CloudML
Cluster Federation
Codelabs
Cohesity
Coldline
Colossus
Compute Engine
Compute user Accounts
Container Engine
Container Registry
Container-VM Image
CRE
CSEK
Customer Reliability Engineering
Dbvisit
DDoS
Debugger
deep learning
Deployment Manager
Developer Console
Developers
DevOps
Disney
Docker
Dockerfile
Drain
Dreamel
Eclipse
Eclipse Orion
Education Grants
Elasticsearch
Energy Sciences Network
Error Reporting
ESNet
Evernote
FASTER
Fastly
Firebase
Firebase Analytics
Firebase Authentication
Flexible Environment
G Suite
gcloud
GCP 移行ガイド
gcsfuse
GitHub
Go
Go 言語
Google App Engine
Google Apps
Google Certified Professional - Data Engineer
Google Cloud Certification Program
Google Cloud Console
Google Cloud Dataflow
Google Cloud Datalab
Google Cloud Datastore
Google Cloud Endpoints
Google Cloud Explorer
Google Cloud Identity and Access Management
Google Cloud Launcher
Google Cloud Logging
Google Cloud Platform
Google Cloud Resource Manager
Google Cloud Security Scanner
Google Cloud Shell
Google Cloud SQL
Google Cloud Storage
Google Cloud Storage Nearline
Google Cloud Tools for IntelliJ
Google Code
Google Compute Engine
Google Container Engine
Google Data Analytics
Google Data Studio
Google Date Studio
Google Deployment Manager
Google Drive
Google Earth Engine
Google Genomics
Google SafeSearch
Google Service Control
Google Sheets
Google Slides
Google Translate
Google 公認プロフェッショナル
GPU
Gradle
GroupBy
gRPC
HA / DR
Haskell
HEPCloud
HIPAA
Horizon
HTCondor
IaaS
IAM
IBM
IBM POWER9
icon
IERS
Improbable
InShorts
Intel
IntelliJ
Internal Load Balancing
Internet2
IoT
Issue Tracker
Java
JFrog
JFrog Artifactory SaaS
Jupiter
Jupyter
Khan Academy
Komprise
kubefed
Kubernetes
KVM
Landsat
load shedding
Logging
Looker
Magenta
Managed Instance Group
Maps API
Maven
Maxon Cinema 4D
MightyTV
Mission Control
MongoDB
MQTT
MySQL
Nearline
Network Time Protocol
neural networks
Next
Node
NoSQL
NTP
NuGet パッケージ
OCP
OLDISM
Open Compute Project
OpenCAPI
OpenCAPI Consortium
OpenShift Dedicated
Orbitera
Organization
Orion
Panda
Particle
Percona
Pete's Dragon
Pivotal
Pivotal Cloud Foundry
PLCN
Pokemon GO
Pokémon GO
Poseidon
Postgre
PowerPoint
PowerShell
Protocol Buffers
Puppet
Pythian
Python
Raspberry Pi
Red Hat
Regional Managed Instance Groups
Rust
SC16
ScaleArc
Security & Identity
Sentinel-2
Serving Websites
SideFX Houdini
SIGOPS Hall of Fame Award
Site Reliability Engineering
SLA
Slack
SLI
SLO
Snap
Spaceknow
SpatialOS
Spinnaker
Spring
SQL Server
SRE
Stack Overflow
Stackdriver
Stackdriver Debugger
Stackdriver Diagnostics
Stackdriver Error Reporting
Stackdriver Logging
Stackdriver Monitoring
Stackdriver Trace
Stanford
Startups
StatefulSets
Storage & Databases
StorReduce
Streak
Sureline
Sysbench
Tableau
Talend
Tensor Flow
Tensor Processing Unit
TensorFlow
The Carousel
TPU
Trace
Transfer Service
Translate API
Uber
Veritas
Video Intelligence API
Vision API
Visual Studio
Visualization
Vitess
VM
VM Image
VSS
Waze
Webyog
Wide and Deep
Windows Server
Windows ワークロード
Wix
Worlds Adrift
Xplenty
Yellowfin
YouTube
Zaius
Zaius P9 Server
Zipkin
ZYNC Render
アーキテクチャ図
イベント
エンティティ
オンライン教育
クラウド アーキテクト
コードラボ
コンピューティング
サポート
ジッター
ショート動画シリーズ
スタートガイド
ストレージ
セミナー
ソリューション: メディア
データ エンジニア
データセンター
ビッグデータ
ファジング
プリエンプティブル VM
フルマネージド
マイクロサービス
マルチクラウド
ロード シェディング
運用管理
可用性
海底ケーブル
機械学習
月刊ニュース
資格、認定
新機能、アップデート
人気記事ランキング
導入事例
内部負荷分散
認定試験
料金
Archive
2017
4
3
2
1
2016
12
11
10
9
8
7
6
5
4
3
2
1
2015
12
11
10
9
8
7
6
5
4
3
2
1
2014
12
11
10
9
8
6
5
4
3
2
Feed
月刊ニュースレターに
登録
新着ポストをメールで受け取る
Google
on
Follow @GoogleCloud_jp
0 件のコメント :
コメントを投稿