ポストモーテムとは
基本的にSRE本を自分で実施する際に理解しやすい形にまとめたもの。
前提
この文章はインシデント(障害や緊急対応など)発生時の対応関するポストモーテムに関して記述する。
プロジェクト終了時などその他のタイミングで行うポストモーテムとは異なる。
用語
- ポストモーテム
- この文章ないではインシデント時に作成するドキュメントをポストモーテムと呼ぶ
- ドキュメント作成とそれにまつわるレビューやなど一連の流れ、仕組みを指すときはポストモーテムのプロセスと呼称する
- インシデント
- 障害・緊急対応などサービスに何かが起きた時の呼称
- トイル(SRE本 p51)
- プロダクションサービスを動作させることに関係する作業で以下のような傾向を持つもの
- 手作業で繰り返し行われる
- 自動化することが可能である
- 戦術的で長期的な価値を持たない
- 作業量がサービスの成長に比例する
- プロダクションサービスを動作させることに関係する作業で以下のような傾向を持つもの
まとめ
目的・文化・準備
- 目的
- インシデントから学習し再発防止のために行われる
- 文化
- 準備
- 作成のための準備
- 書く/書かないの基準
- 情報収集ができる仕組み
- レビューの仕組み
- 共有方法
- 文化の導入
- (大変である)
- 積極的な発信・トレーニング
- よいポストモーテム書く事を推奨・称賛する
- プロセス自体の改善
- 作成のための準備
プロセス
ポストモーテムのプロセスは以下のようになる
- インシデントが発生する
- インシデントの対応が完了する
- ポストモーテムを書く条件に当てはまるかを判定
- 必要な情報を収集する
- 原因の分析と対策を検討する
- ポストモーテムを書く
- レビューを行う
- 共有する
参考: https://postmortems.pagerduty.com/what_is/
ポストモーテムの目的
過去のインシデントから学習し、再発の可能性や影響を削減するために行われる。
具体的には以下のような事を目的となる。
- 根本原因、教訓が十分(具体的・広範囲に)に理解されること
- 効果的な予防策が確実に導入される事
参考: - https://postmortems.pagerduty.com/what_is/ - SRE本 p175
ポストモーテムの準備
- ポストモーテムを書くルール
- ポストモーテムを作成する条件を用意
- テンプレート
- チェックリスト
- インシデン時の情報収集
- 何の情報を収集するか
- 収集する仕組みが存在するか
- レビューのルール
- 共有方法
- 方法(メーリングリスト、チャットなど)
- 誰に範囲に共有するか
- ポストモーテムの保存先
- ポストモーテムを書くプロセスを回すためのツール選定
ツールの選定
- ポストモーテムを書くためには以下の機能を備えているツールが望ましい
- リアルタイムコラボレーション
- オープンなコメント/アノテーションシステム
- メール、チャットによる自動通知
- 管理システム
- リポジトリ
- ステータスの管理が可能
- SRE本では以下のようなツールが載っている
- https://github.com/etsy/morgue (最近は更新されていない)
- リポジトリ
参考: SRE本 p177
ポストモーテムの作成
まずポストモーテムを書く前にポストモーテムを作成する必要があるかを判断する。
書く場合は
を行い上記を十分に吟味し(もしくは行いながら)、ポストモーテムの作成する。
ポストモーテムは事前に用意したテンプレートに従い記述し、どのようにな書き方がよいポストモーテムかを理解しておく必要がある
いつポストモーテムを作成するか
- 事前に決めた条件に則り、条件を満たす場合に作成する
- ユーザー影響あるダウンタイムの発生
- エンジニアが介入が必要だったとき
- 解決までの時間
- データの損失が発生した場合
- 支払い、請求などお金に関わる問題発生時
- モニタリングシステム自体の障害
- など
- 上記の決まった条件以外で問題となったイベントのステークホルダーは条件に以外で求める事ができる
参考: SRE本 p176~p178
ポストモーテムのテンプレート
例としてポストモーテムには以下のような項目を記述する。
- 担当者 - ポストモーテム担当者 - 対応担当者 - 概要 - 原因分析 - 根本原因(e.g. ○○のバグのため) - 発生原因(e.g. △△の操作を行ったため) - 対応内容 - 対応自体の分析 - 教訓 - 今後のアクションリスト - 事後対応内容 - 現在のステータス - 担当者 - 優先度
よいポストモーテムの書き方
TODO
参考: サイトリライアビリティワークブック―SREの実践方法/10章 ポストモーテムの文化:失敗からの学び
レビュー
レビューが行われていないポストモーテムは適切さを証明できないため、無いも同然と考える必要がある。
実際の流れとしては - チームに下書きを内部共有してレビューを行う - この時、上位の役職者は下書きが完全かを評価する
となる。場合によっては広範囲に意見を求める事もある。
レビューの観点
レビューでは事前にある程度観点を定めておく。
以下は一例
- 不要な非難が含まれていないか
- 個人に対する指摘
- インシデントの主要なデータが収集されているか
- インパクトの分析が十分か
- 根本原因の分析が十分か
- アクションプランは適切か
- 担当者が決まっているか
- 優先度が与えられているか
- 結果はステークホルダーと共有されているか
など
レビューを必ず行う仕組み
レビューが行われなければポストモーテムは無意味といっていい。
必ず行うために、何時、どのように行うかをあらかじめ考えておくとよい。
- どんなタイミングでレビューをするか
- 下書きの段階でチーム内や直属の上位者がレビューするのが望ましい
- レビューされていないポストモーテムが存在しない仕組みづくり
参考: SRE本 p178
共有
ポストモーテムを広く共有し、知識や教訓を広い範囲で役立てる事を目標とする。
より広範囲なチーム、内部メーリングリスト、チャットチャンネルなどへ共有する。
ポストモーテム文化の導入
参考: SRE本 p179
非難なく行う
ポストモーテムの記述・レビューなど全てのプロセスを通して、非難なく行うことが重要である - 避難的な雰囲気は問題の隠蔽へつながる - ポストモーテムを頻繁に作成している事を非難しない - ポストモーテムはサービス改善のための提案である - ポストモーテムの作成を称賛する文化を作る事が望ましい
参考: SRE本 P176~P177
継続的な育成と強化
継続にはポストモーテム文化の育成と強化が必要となる。 - 上位管理職の積極的な参加 - 積極的な情報の発信 - よいポストモーテムの選出・定期的な発信 - 公開されたポストモーテム議論の場 - チャットチャンネル、メールグループなど - ポストモーテムの読書会 - 過去の興味深いポストモーテムの振り返り - 新旧を問わず - ディザスターロールプレイング - ポストモーテムに書かれている役割をエンジニアたちが演じ、過去のポストモーテムの再現する
ポストモーテムプロセスのフィードバック
ポストモーテムのプロセス自体に無駄がないかを見直し、改善を行う。 - ポストモーテムは業務の支援となっているか? - トイルが発生しすぎていないか? - ツールは適切か?新しい開発が必要か?
参考: SRE本 p180
将来的な価値を考える
参考: SRE本 P181
準備コストと価値に対する理解
ポストモーテム文化を組織に導入する上での最大の課題は、準備コストよりも価値があるのか?と考える人が多いかもしれないこと。
これを解決するには以下のような対策が考えられる - ワークフローに落とし込む - よいポストモーテムを書くことは評価されるように - ピアボーナスを与える - 上位のリーダーたちの承認と参加を奨励する
理解に関しては - ポストモーテムプロセスのフィードバックを行う - 継続的な育成と強化 - 将来的な価値を考える
などと合わせて考えることが理解を得る助けとなる
参考: SRE本 P179
ポストモーテムの例
SRE本 p507
参考
fluent-plugin-s3 設定と IAMロール アクションの関係と注意
環境 fluent-plugin-s3 1.6.0
関係性のまとめ
アクション | 関係ある設定 | 説明 |
---|---|---|
s3:ListBucket | check_bucket true | true であればfluent起動時にbucket存在をチェック。存在しなければ起動をリトライするfalse だと起動はするが書き込み時に失敗する |
s3:GetObject | check_object true | true であれば同じobjectがあると上書きせずエラーになるfalse だと同名objectは上書きされる |
s3:PutObject | 書き込み全般 |
つまり check_bucket
check_object
が false
ならアクションは最小限の PutObject
のみでよい
check_object false
の注意
check_object false
の時も s3_object_key_format
が同名にしない事で不用意な上書きを防ぐ事ができる。
s3_object_key_format
を設定していなければ、デフォルト値自体が上書きされにくいフォーマットに自動で変更される。
(s3_object_key_format "%{path}/%{date_slice}_%{hms_slice}.%{file_extension}"
になる)
さらに uuid_flush
hex_random
index
hostname
などを使えばより重複を防止し安全に扱える。
uuid_flush
- bufferがフラッシュされる際、常にUUIDに置き換えられる
- 書き込み失敗のリトライ時も新しいUUIDに置き換えられる
hostname
- ホストネームに置き換えられるので、
%s
や%{hms_slice}
などと組み合わせると重複を防止できる
- ホストネームに置き換えられるので、
hex_random
:- bufferに使われるhashで置き換えられる
- 例えば同名エラーでリトライしたときも同じ値が使われる
%{index}
を組み合わせればリトライ時は%{index}
が更新される
fluent-plugin-s3 v0.12
の注意
正確には fluent-plugin-s3 < 1.0.0rc7
のとき。
この時 check_object false
だと s3_object_key_format
が固定されるので注意
check_bucket true
と APIリクエストにかかる料金の注意
check_bucket
は起動時のチェックなので、 true
でもほとんどAPIリクエストはしない。
しかし check_object
は true
だと書き込みの度にAPI GetObject
を発行する。
そのため、特に書き込み頻度が高い場合は、APIリクエストが常に GetObject
-> PutObject
と二重に発生し料金が嵩むので注意。
Scalaでもtry-catchを使う方がよい事もある
環境 Scala 2.13.6
Scalaだと例外を常にTry
で処理しがちなので、反省メモ。
もちろん単純に例外出す可能性ある個所をTry
で包むのは問題ない。
困るのはTry[Either[L, R]]
みたいなネストを避けたい時。
refinedとかでよくある。
例えば以下は単純にString
をEither[String, PosInt]
に変換している。
import cats.implicits._ import eu.timepit.refined.api.RefType import eu.timepit.refined.types.numeric.PosInt import scala.util.Try def s2pi(s: String): Either[String, PosInt] = Try(s.toInt).toEither .leftMap(_.getMessage) .flatMap(RefType.applyRef[PosInt](_)) val etPiR = s2pi("1") // Right(1) val etPiL = s2pi("a") // Left(For input string: "a")
読みずらい!
まあ正直言うと、このくらいならまだマシで、実際コード書いているともっと複雑になる事も多々ある。
こういうTryとEitherのネストを避けようとするなら、以下のように書くのが断然読みやすい。
import eu.timepit.refined.api.RefType import eu.timepit.refined.types.numeric.PosInt import scala.util.Try def s2piVer2(s: String): Either[String, PosInt] = try RefType.applyRef[PosInt](s.toInt) catch { case t: Throwable => Left(t.getMessage) } val etPiV2R = s2piVer2("1") // Right(1) val etPiV2L = s2piVer2("a") // Left(For input string: "a")
ドメイン駆動開発(DDD)とCleanArchitectureのエンティティはどう違うか?
双方と共にビジネスモデル定義のためのオブジェクトという点では共通だが、実際には意味は大幅に異なる。
DDDでは
以下のように定義される
主として同一性によって定義されるオブジェクトはエンティティと呼ばれる。
としている。
つまりDDDではビジネスモデルの中でも、常に同一である事を保証できるオブジェクトととして定義されるものがエンティティである。
CleanArchitectureでは
「クリーンアーキテクチャ(The Clean Architecture翻訳)」から
エンティティーは、大規模プロジェクトレベルのビジネスルールをカプセル化する。エンティティは、メソッドを持ったオブジェクトかもしれない、あるいは、データ構造と関数の集合かもしれない。
とある。
これはDDDで言うところの、エンティティ、値オブジェクト、ドメインサービス、リポジトリ(の仕様)、ファクトリ, 集約などのドメインレイヤー全体を指している。
まとめ
回答としては「DDDにおけるエンティティ」と「CleanArchitectureにおけるエンティティ」は全く異なる定義なので、使うアーキテクチャに合わせてコードを書こう。
もっと言えば - 書いているコードのアーキテクチャが、何を採用しているか? - 各用語はどういう定義なのか?
をきちんと理解して書こうという事になる。
プロジェクトによってはCleanArchtectureだけどentityをdomainというpackage名にしたりで、一見DDD風に見える事もあったり、そもそも全く異なる意味で使っている場合もある。
プロジェクトに参加したときはビジネス的な言葉、DDDでいうユビキタス言語だけではなく、こういったコード上の意味合いも慎重に確認する事が大切。
aws sam (Serverless Application Model)に入門する
Infrastructure as Code入門としてaws samでLambdaを作るところからはじめてみる
sample templateから基本的なアプリケーションをビルト
仕組み的には以下のような順序で作成される
- ローカルでsamコマンドでアプリケーションを作成
- ローカルから
sam deploy
でcloudformationを呼び出しアプリケーションをデプロイする - S3へテンプレートが保存される
- API GatewayとLambdaが作成される
aws samのアプリケーションを作成
$ sam init # まずはawsのtemplateを選択して使う # template一覧は以下 Which template source would you like to use? 1 - AWS Quick Start Templates 2 - Custom Template Location Choice: 1 # パッケージはシンプルに # lambda用のファイルはzipで固め # cloudformationでS3にアップロードされる # # 2のイメージはECR周りの知識が必要なのでそのうち試す What package type would you like to use? 1 - Zip (artifact is a zip uploaded to S3) 2 - Image (artifact is an image uploaded to an ECR image repository) Package type: 1 # go1.xで作っていく Which runtime would you like to use? 1 - nodejs14.x 2 - python3.8 3 - ruby2.7 4 - go1.x 5 - java11 6 - dotnetcore3.1 7 - nodejs12.x 8 - nodejs10.x 9 - python3.7 10 - python3.6 11 - python2.7 12 - ruby2.5 13 - java8.al2 14 - java8 15 - dotnetcore2.1 Runtime: 4 # cloudformation, API Gatewayの名前 # S3, Lambdaのprefixとして使われる Project name [sam-app]: Cloning from https://github.com/aws/aws-sam-cli-app-templates # まずは単独のLambdaで作るので1を選択 AWS quick start application templates: 1 - Hello World Example 2 - Step Functions Sample App (Stock Trader) Template selection: 1 ----------------------- Generating application: ----------------------- Name: sam-app Runtime: go1.x Dependency Manager: mod Application Template: hello-world Output Directory: . Next steps can be found in the README file at ./sam-app/README.md
この段階でgolangのLambdaに適した構成が作成される
template.yamlはcloudformationと共通フォーマット
将来的にaws samの範囲より拡張された場合はcloudformationで使う事もできる
$ tree sam-app sam-app ├── Makefile ├── README.md ├── hello-world │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── main_test.go └── template.yaml 1 directory, 7 files
main.goは以下のようにLambdaでGetリクエストを受ける基本的な構成になっている
package main import ( "errors" "fmt" "io/ioutil" "net/http" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) var ( // DefaultHTTPGetAddress Default Address DefaultHTTPGetAddress = "https://checkip.amazonaws.com" // ErrNoIP No IP found in response ErrNoIP = errors.New("No IP in HTTP response") // ErrNon200Response non 200 status code in response ErrNon200Response = errors.New("Non 200 Response found") ) func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { resp, err := http.Get(DefaultHTTPGetAddress) if err != nil { return events.APIGatewayProxyResponse{}, err } if resp.StatusCode != 200 { return events.APIGatewayProxyResponse{}, ErrNon200Response } ip, err := ioutil.ReadAll(resp.Body) if err != nil { return events.APIGatewayProxyResponse{}, err } if len(ip) == 0 { return events.APIGatewayProxyResponse{}, ErrNoIP } return events.APIGatewayProxyResponse{ Body: fmt.Sprintf("Hello, %v", string(ip)), StatusCode: 200, }, nil } func main() { lambda.Start(handler) }
アプリケーションをbuild
$ sam build Building codeuri: ./sam-app/hello-world runtime: go1.x metadata: {} functions: ['HelloWorldFunction'] Running GoModulesBuilder:Build Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided
ローカルでアプリケーションを実行
sam local start-api
と実行する事で、ローカルでsamでbuildしたAPIを実行できる
$ sam local start-api Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET] You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template 2021-08-08 23:37:49 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
この状態でリクエストを投げると、dockerイメージが作成&実行され、レスポンスを返す
$ curl http://127.0.0.1:3000/hello Hello, 11.111.111.111
sam local start-apiのログ
Invoking hello-world (go1.x) Image was not found. Building image...................................................................................................... Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-go1.x:rapid-1.27.2. Mounting ./sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container START RequestId: fa806430-6835-4b88-acd6-4e1b857bcd4a Version: $LATEST END RequestId: fa806430-6835-4b88-acd6-4e1b857bcd4a REPORT RequestId: fa806430-6835-4b88-acd6-4e1b857bcd4a Init Duration: 0.07 ms Duration: 1010.38 ms Billed Duration: 1100 ms Memory Size: 128 MB Max Memory Used: 128 MB No Content-Type given. Defaulting to 'application/json'. 2021-08-08 23:43:07 127.0.0.1 - - [08/Aug/2021 23:43:07] "GET /hello HTTP/1.1" 200 -
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fa8dda6a0f15 amazon/aws-sam-cli-emulation-image-go1.x:rapid-1.27.2 "/var/rapid/aws-lamb…" 2 seconds ago Up 1 second 127.0.0.1:6436->8080/tcp vigorous_allen
アプリケーションをawsへデプロイする
--guided
をつけると会話形式で設定できる
$ sam deploy --guided Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [y/N]: #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y Save arguments to configuration file [Y/n]: SAM configuration file [samconfig.toml]: SAM configuration environment [default]: Looking for resources needed for deployment: Not found. Creating the required resources... Successfully created! Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xarl3ki5fc62 A different default S3 bucket can be set in samconfig.toml Saved arguments to config file Running 'sam deploy' for future deployments will use the parameters saved above. The above parameters can be changed by modifying samconfig.toml Learn more about samconfig.toml syntax at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html Uploading to sam-app/7ad10cf1c8bd04b9d2c1ad18dd4297c0 4328737 / 4328737 (100.00%) Deploying with following values =============================== Stack name : sam-app Region : ap-northeast-1 Confirm changeset : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-xarl3ki5fc62 Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Uploading to sam-app/17fb0b7caff4b6a85cdca466c28c1236.template 1154 / 1154 (100.00%) Waiting for changeset to be created.. CloudFormation stack changeset ---------------------------------------------------------------------------------------------------- Operation LogicalResourceId ResourceType Replacement ---------------------------------------------------------------------------------------------------- + Add HelloWorldFunctionCatchAllPermissionProd AWS::Lambda::Permission N/A + Add HelloWorldFunctionRole AWS::IAM::Role N/A + Add HelloWorldFunction AWS::Lambda::Function N/A + Add ServerlessRestApiDeployment47fc2d5f9d AWS::ApiGateway::Deployment N/A + Add ServerlessRestApiProdStage AWS::ApiGateway::Stage N/A + Add ServerlessRestApi AWS::ApiGateway::RestApi N/A ---------------------------------------------------------------------------------------------------- Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:111111111111:changeSet/samcli-deploy1628426562/db1f0927-131d-4bf1-9b12-aacf949eacda 2021-08-08 21:42:54 - Waiting for stack create/update to complete CloudFormation events from changeset ------------------------------------------------------------------------------------------------------------------------------ ResourceStatus ResourceType LogicalResourceId ResourceStatusReason ------------------------------------------------------------------------------------------------------------------------------ CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role HelloWorldFunctionRole Resource creation Initiated CREATE_COMPLETE AWS::IAM::Role HelloWorldFunctionRole - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction Resource creation Initiated CREATE_COMPLETE AWS::Lambda::Function HelloWorldFunction - CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi - CREATE_IN_PROGRESS AWS::ApiGateway::RestApi ServerlessRestApi Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::RestApi ServerlessRestApi - CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionCatchAllPermissionProd - CREATE_IN_PROGRESS AWS::Lambda::Permission HelloWorldFunctionCatchAllPermissionProd Resource creation Initiated CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d - CREATE_COMPLETE AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d - CREATE_IN_PROGRESS AWS::ApiGateway::Deployment ServerlessRestApiDeployment47fc2d5f9d Resource creation Initiated CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage - CREATE_IN_PROGRESS AWS::ApiGateway::Stage ServerlessRestApiProdStage Resource creation Initiated CREATE_COMPLETE AWS::ApiGateway::Stage ServerlessRestApiProdStage - CREATE_COMPLETE AWS::Lambda::Permission HelloWorldFunctionCatchAllPermissionProd - CREATE_COMPLETE AWS::CloudFormation::Stack sam-app - ------------------------------------------------------------------------------------------------------------------------------ CloudFormation outputs from deployed stack ----------------------------------------------------------------------------------------------------------- Outputs ----------------------------------------------------------------------------------------------------------- Key HelloWorldFunctionIamRole Description Implicit IAM Role created for Hello World function Value arn:aws:iam::111111111111:role/sam-app-HelloWorldFunctionRole-MGSTGE9WCIMR Key HelloWorldAPI Description API Gateway endpoint URL for Prod environment for First Function Value https://aaaaaaaaaa.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/ Key HelloWorldFunction Description First Lambda Function ARN Value arn:aws:lambda:ap-northeast-1:111111111111:function:sam-app-HelloWorldFunction-pMOSVaxRjbuN ----------------------------------------------------------------------------------------------------------- Successfully created/updated stack - sam-app in ap-northeast-1
これにより API Gateway経由でLambdaを呼び出せるようところまで作成される
デプロイ結果の確認
Outputs
にあるHelloWorldAPI
へアクセスしてみると、レスポンスが返ってくる
$ curl - 'https://aaaaaaaaaa.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/' HTTP/2 200 content-type: application/json content-length: 22 date: Sun, 08 Aug 2021 13:41:16 GMT Hello, 11.111.111.111
参考
awsデータストレージまとめ(インスタンスストア・EBS・EFS・S3)
各ストレージ
インスタンス ストア
Elastic Block Store (EBS)
- ブロックレベルストレージ
- インスタンスから独立してデータを永続化する
- インスタンスが終了してもデータは残る
- 起動しているインスタンスにアタッチ(追加)できる
- 稼働中にサイズ変更、ボリュームタイプの変更など可能
- インスタンスとEBSは同じAZにある必要がある
Elastic File System (EFS)
- マネージドなサーバーレスなファイルレベルストレージ
- 最大サイズ16TiB(=tebibyte=1024GB)
- EC2でNFSとしてマウント可能
- オートスケール
- リージョン内のAZを跨いでマウント可能
- ただし複数のVPCに接続はできない
Simple Storage Service (S3)
- オブジェクトレベルストレージ
- インターネットストレージとしてURLでアクセス可能
- 無制限のストレージ容量
- 各オブジェクトは最大5TB
- バケットはリージョン単位で保存される
- 各オブジェクトのバージョニングによる変更追跡
- 少なくとも3つのAZにデータが保存(バックアップ)される
- 複数のストレージクラスによる料金プラン
- 各オブジェクトにURLがあり静的webページとしても使える
ストレージ形式について
ファイルレベルストレージ
- ファイルストレージ
- ファイルベース・ストレージ
ファイルによるデータ管理。
階層構造化が容易で、一意のデータパスによりファイルにアクセスする。
データにはファイル名、作成日時などの最低限のメタデータが付与される。
ブロックレべルストレージ
- ブロックストレージ
ディスクを論理ボリュームへ分割し、論理ボリュームをさらにブロックへ分割。
データをブロック単位で保存する(ブロックより大きなデータは複数ブロックへ保存される。連続性はない)
ボリューム、ブロック両方にIDが振られボリュームID+ブロックIDでデータを特定する事で高速なデータアクセスが可能。
ブロック単位での差分更新が可能なため、巨大なデータの更新が高速で行える。
メタデータは基本的にはない、もしくは非常に限定的。
オブジェクトレベルストレージ
- オブジェクトストレージ
- オブジェクトベース・ストレージ
一つのデータを一つのオブジェクトとして保存する。
オブジェクトは一意のIDを持ち、インデックス化され高速にアクセスできる。
多彩なメタ情報が付与され、セキュリティポリシーやアクセス権限に至るまで様々な情報を持つ事ができる。
通常はフラットな構造になるが、S3のようにバケットを入れ子構造にできるサービスもある。
一度書き込まれたオブジェクトは変更できず、オブジェクトは全体を一度で書き込む必要がある。
そのため巨大なデータを更新する場合などは、巨大なデータを再度全て書き込み、過去データを削除(もしくは履歴として残す)ような運用になる。