継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

運用の改善事例を聴ける『Jira / Confluence × Mackerel で実践! 運用しながら改善していくDevOpsのはじめかた』参加レポート

タダです.

Mackerel との運用の中で DevOps や障害対応から改善につなげる活動を今後もつなげていきたいと思い,事例をきける「Jira / Confluence × Mackerel で実践! 運用しながら改善していくDevOpsのはじめかた」のウェビナーに参加したのでレポートとしてまとめます.

zoom.us

ウェビナー概要

本ウェビナーは Zoom にて以下のアジェンダで行われました.

  • ご挨拶・講師紹介

  • アトラシアンの調査から見るDevOpsの現状と課題(アトラシアン)

  • 障害対応から改善につなげるDevOpsへの取り組み方(はてな

  • Q&A

聴講の目的

本ウェビナーを聴講しようとした目的は冒頭で記載したように DevOps や障害対応から改善(ポストモーテム)の事例を聞きたいと思ったためです.今回は Atlassian 社とはてな社の事例を聴けるというところで2社の取組みを参考に自身の業務の中に取り込めるものは取り込んでいきたいと考え参加しました.

アトラシアンのセッションでは、運用チーム視点のDevOpsについて、アトラシアンが開発者やIT部門の意思決定者を対象にしたアンケート結果を基に、現状と課題、そしてアトラシアン流の解決策をご紹介します。

はてなのセッションでは、より具体的なDevOpsへの取り組みのポイントを「障害対応から改善」を軸にしたストーリーでご紹介します。チーム内の情報格差をなくして、全員で同じ情報を共有しながら運用・改善を実践するためのMackerelとOpsgenie、そしてConfluenceの使い方をご案内します。

セミナーに参加して、SaaSを使ってDevOpsを実践し、継続的に改善していけるチーム作りをはじめましょう。

ウェビナーメモ

アトラシアンの調査から見るDevOpsの現状と課題

DevOps が話題に上がっている経緯や下記の Atlassian 社による DevOps に関する調査からの考察,Atlassian 社のツールを DevOps の実践で取り入れた場合どのツールを使うかといったお話が聴けました.個人的には OpsGenie が Mackerel と連携ができるのでアラート管理が必要なほどシステムもチームもスケールしてきたときに有効活用していきたいと感じました.

www.atlassian.com

調査の中で DevOps に必要なのはコラボレーションであると出ていたのは納得でした.やはり Dev と Ops のチームが別々の方向を見て仕事をするのではなく,共通の方向性を見て仕事をしていくことでソフトウェアの価値を顧客に届けることにフォーカスできると思います.Atlassian 社では Team Playbook というのを無償公開してチームのコラボレーションを強くするためのツールを提供しています.これを使ってコラボレーションの文化醸成を図るのに活用してみるといいかもしれないと感じました.

www.atlassian.com

また,調査には DevOps の成功指標をアンケートした結果があり,次のような指標が上がっていて興味深かったです.アジャイルやスピード感を持ったソフトウェアの提供を反映した結果として出ているなと感じます.

  • デプロイ頻度
  • 平均復旧時間
  • リードタイム
  • 変更失敗率

障害対応から改善につなげるDevOpsへの取り組み方

はてな社の障害対応から改善につなげていくための事例が気になり,聴講しました.はてな社で Mackerel のアラートが Slack などに通知されたことで障害発生を感知 -> チームで共同で障害対応 -> 振り返り-> 改善というサイクルで取り組みを行っています.特に障害対応時は障害対応テンプレートを用意しており,そのテンプレートを使ってリアルタイムで状況をアップデートしていくことを大事であるとおっしゃっていました.それはメンバーがリアルタイムで状況を把握し,同じドキュメントを見て目線を揃えて障害対応をあたる必要があるためです.自分の業務でも Mackerel 導入と合わせて障害対応テンプレートを用意して共通のフォーマットでリアルタイムで編集可能なツールを使ってフローを作ろうとしているので参考になる情報でした.

また,本発表では触れられませんでしたが Mackerel の開発チームでは障害対応演習を行っていることが「WEB+DB PRESS Vol.119」で特集されていました.今年になってリモートや在宅勤務も多くなった人も多いと思いますが,社員のロケーションを気にせず業務を行えるように配慮した事例が紹介されていて開発チームとの関わりでやっていきたいと思っており,開発チームからも障害対応のリハーサルやることを賛同を得られているので計画して行っていきたいです.

WEB+DB PRESS Vol.119

WEB+DB PRESS Vol.119

  • 発売日: 2020/10/24
  • メディア: Kindle

まとめ

ウェビナーを聞いての所感を中心にまとめていきました.業務上開発チームとのやり取りがあるし,運用上協力をし合ってメンテナンスをしているので今回のウェビナーで聞いたコラボレーションのツールや事例を参考に運用フローを作っていけたらと思います.

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

SAM で Step Functions と Lambda のワークフローを管理する

タダです.

Serveless Applicaiton Model(SAM) で Lambda の開発とデプロイを行い,Step Functions が Lambda 関数処理のワークフローを管理しています.ただ,Step Functions のコード管理ができていない課題があって どの Step Functions が どの Lambda を管理しているかとか不明瞭だったのですが,調べていたら SAM が Step Functions をサポートしたというアップデートがありました.この波に乗って SAM で Step Functions と Lambda を管理する場合どう対応が必要なのかをサンプルアプリケーションを動かしてさらってきます.

aws.amazon.com

サンプルアプリケーションの作成

sam init で作っていきます(バージョンは 1.6.2 で確認してます).Lambda は Python で作り,Step Functions Sample App (Stock Trader) のサンプルアプリケーションを選択しました.

$ sam init
Which template source would you like to use?
    1 - AWS Quick Start Templates
    2 - Custom Template Location
Choice: 1

Which runtime would you like to use?
    1 - nodejs12.x
    2 - python3.8
    3 - ruby2.7
    4 - go1.x
    5 - java11
    6 - dotnetcore3.1
    7 - nodejs10.x
    8 - python3.7
    9 - python3.6
    10 - python2.7
    11 - ruby2.5
    12 - java8.al2
    13 - java8
    14 - dotnetcore2.1
Runtime: 9

Project name [sam-app]: sfn-lambda-app

Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git

AWS quick start application templates:
    1 - Hello World Example
    2 - EventBridge Hello World
    3 - EventBridge App from scratch (100+ Event Schemas)
    4 - Step Functions Sample App (Stock Trader)
Template selection: 4

-----------------------
Generating application:
-----------------------
Name: sfn-lambda-app
Runtime: python3.6
Dependency Manager: pip
Application Template: step-functions-sample-app
Output Directory: .

Next steps can be found in the README file at ./sfn-lambda-app/README.md

出来上がったサンプルアプリケーションのディレクトリ構造とディレクトリの役割は次の通りです.

functions - 株式の値をチェックしたり,購入したり,売却したりするためのアプリケーションの Lambda 関数のコード

statemachines - 株式取引のワークフローをオーケストレーションするステートマシンの定義

tests - Lambda 関数のアプリケーションコードのユニットテスト

template.yaml - アプリケーションの AWS リソースを定義するテンプレート

ディレクトリ構造

$ tree
.
├── README.md
├── functions
│   ├── __init__.py
│   ├── stock_buyer
│   │   ├── __init__.py
│   │   ├── app.py
│   │   └── requirements.txt
│   ├── stock_checker
│   │   ├── __init__.py
│   │   ├── app.py
│   │   └── requirements.txt
│   └── stock_seller
│       ├── __init__.py
│       ├── app.py
│       └── requirements.txt
├── statemachine
│   └── stock_trader.asl.json
├── template.yaml
└── tests
    └── unit
        ├── __init__.py
        ├── test_buyer.py
        ├── test_checker.py
        └── test_seller.py

7 directories, 17 files

Step Functions の ASL の中身は次のようになっています.

{
    "Comment": "A state machine that does mock stock trading.",
    "StartAt": "Check Stock Value",
    "States": {
        "Check Stock Value": {
            "Type": "Task",
            "Resource": "${StockCheckerFunctionArn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "States.TaskFailed"
                    ],
                    "IntervalSeconds": 15,
                    "MaxAttempts": 5,
                    "BackoffRate": 1.5
                }
            ],
            "Next": "Buy or Sell?"
        },
        "Buy or Sell?": {
            "Type": "Choice",
            "Choices": [
                {
                    "Variable": "$.stock_price",
                    "NumericLessThanEquals": 50,
                    "Next": "Buy Stock"
                }
            ],
            "Default": "Sell Stock"
        },
        "Sell Stock": {
            "Type": "Task",
            "Resource": "${StockSellerFunctionArn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "States.TaskFailed"
                    ],
                    "IntervalSeconds": 2,
                    "MaxAttempts": 3,
                    "BackoffRate": 1
                }
            ],
            "Next": "Record Transaction"
        },
        "Buy Stock": {
            "Type": "Task",
            "Resource": "${StockBuyerFunctionArn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "States.TaskFailed"
                    ],
                    "IntervalSeconds": 2,
                    "MaxAttempts": 3,
                    "BackoffRate": 1
                }
            ],
            "Next": "Record Transaction"
        },
        "Record Transaction": {
            "Type": "Task",
            "Resource": "${DDBPutItem}",
            "Parameters": {
                "TableName": "${DDBTable}",
                "Item": {
                    "Id": {
                        "S.$": "$.id"
                    },
                    "Type": {
                        "S.$": "$.type"
                    },
                    "Price": {
                        "N.$": "$.price"
                    },
                    "Quantity": {
                        "N.$": "$.qty"
                    },
                    "Timestamp": {
                        "S.$": "$.timestamp"
                    }
                }
            },
            "Retry": [
                {
                    "ErrorEquals": [
                        "States.TaskFailed"
                    ],
                    "IntervalSeconds": 20,
                    "MaxAttempts": 5,
                    "BackoffRate": 10
                }
            ],
            "End": true
        }
    }
}

templates.yaml の中身で Lambda と Step Functions の管理は次のコードで定義していました.DefinitionUri が ASL の定義場所,DefinitionSubstitutionsがステートマシンの定義に変数のマッピングする場所,Events' がステートマシンのトリガーになるイベント,Policies` がステートマシンの IAM ロールを指定する場所です.

docs.aws.amazon.com

~中略~
Resources:
  StockTradingStateMachine:
    Type: AWS::Serverless::StateMachine # More info about State Machine Resource: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html
    Properties:
      DefinitionUri: statemachine/stock_trader.asl.json
      DefinitionSubstitutions:
        StockCheckerFunctionArn: !GetAtt StockCheckerFunction.Arn
        StockSellerFunctionArn: !GetAtt StockSellerFunction.Arn
        StockBuyerFunctionArn: !GetAtt StockBuyerFunction.Arn
        DDBPutItem: !Sub arn:${AWS::Partition}:states:::dynamodb:putItem
        DDBTable: !Ref TransactionTable
      Events:
        HourlyTradingSchedule:
          Type: Schedule # More info about Schedule Event Source: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-statemachine-schedule.html
          Properties:
            Description: Schedule to run the stock trading state machine every hour
            Enabled: False # This schedule is disabled by default to avoid incurring charges.
            Schedule: "rate(1 hour)"
      Policies: # Find out more about SAM policy templates: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html
        - LambdaInvokePolicy:
            FunctionName: !Ref StockCheckerFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref StockSellerFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref StockBuyerFunction
        - DynamoDBWritePolicy:
            TableName: !Ref TransactionTable
~中略~

サンプルアプリケーションのビルドとデプロイ

サンプルアプリケーションのビルドとデプロイをしてみます.

$ sam build --use-container
~中略~
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
    
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
$ sam deploy --guided
~中略~
Successfully created/updated stack - sfn-lambda-app in ap-northeast-1

Step Functions の定義もデプロイできていたので,ステートマシンの手動実行もできました.

f:id:sadayoshi_tada:20201108234053p:plain f:id:sadayoshi_tada:20201108234216p:plain

SAM のデプロイとステートマシンの実行確認できたので,クリーンアップします.

aws cloudformation delete-stack --stack-name sfn-lambda-app

まとめ

SAM で Lambda と Step Functions を管理するコードのプロジェクト作成とデプロイの確認ができました.SAM の Step Functions の扱いをさらえたので実務でも適用を検討していけたらと思います!

SSM Automation を使ったオペレーションの省力化!

タダです.

運用において System Manager Automation(SSM Automation) を使い始めたのですが,これまで Lambda などで仕組み化していたものが AWS が機能として提供されていて感動したのでこの記事で SSM Automation の概要と今取り入れている機能を書きます.

SSM Automation の概要

SSM Automation は EC2 やその他の AWS サービス,運用でのオペレーションを簡素化されたものです.以下の操作が可能です.

自動化ワークフローを構築して、インスタンスおよび AWS リソースを設定し、管理します。

独自のカスタムワークフローを作成するか、または AWS によって管理された定義済みのワークフローを使用します。

Amazon EventBridge を使用してオートメーションタスクおよびワークフローに関する通知を受信します。

Amazon EC2 または AWS Systems Manager コンソールを使用して、自動化の進捗状況および実行の詳細を監視します

docs.aws.amazon.com

SSM Automation ではオペレーションタスクを簡素化されたものをドキュメントと呼ぶのですが,ドキュメントは独自のものも AWS で事前定義されたドキュメントがあります.

事前定義されたドキュメント

AWS によって事前定義されたドキュメントもあり,以下にドキュメント名と概要を一覧にまとめました.たくさんありますよね。。皆さんの普段オペレーションの中でも関連するものがあるのではないでしょうか?

ドキュメント名 ドキュメントの概要
AWSSupport-ActivateWindowsWithAmazonLicense Amazon によって提供されるライセンスで Windows Server の EC2 インスタンスをアクティベートする
AWS-ASGEnterStandby Auto Scaling グループでの EC2 インスタンスのスタンバイ状態を変更
AWS-ASGExitStandby Auto Scaling グループでの EC2 インスタンスのスタンバイ状態を変更
AWS-AttachEBSVolume EC2 インスタンスに EBS ボリュームをアタッチする
AWS-AttachIAMToInstance マネージドインスタンスに IAM ロールをアタッチする
AWSEC2-CloneInstanceAndUpgradeWindows Windows Server 2008 R2,2012 R2,2016 の EC2 から AMI を作成後,その AMI を Windows Server 2012 R2,2012,2016,2019 にアップグレードする
サポートされているアップグレードパスは次のとおり
- Windows Server 2008 R2->Windows Server 2012 R2
- Windows Server 2012 R2-> Windows Server 2016
- Windows Server 2012 R2->Windows Server 2019
- Windows Server 2016->Windows Server 2019
AWSEC2-CloneInstanceAndUpgradeSQLServer SQL Server 2008 もしくはそれ以降で実行している Windows Server の EC2 から AMI を作成後,AMI を SQL Server 2016 にアップグレードする
AWSSupport-CollectEKSInstanceLogs EC2 からOSと EKS 関連のログファイルを収集する
AWS-ConfigureCloudWatchOnEC2Instance マネージドインスタンスの CloudWatch モニタリングを有効または無効に変更する
AWS-ConfigureS3BucketLogging S3 バケットでログを有効にする
AWS-ConfigureS3BucketVersioning S3 バケットのバージョニングを設定する
AWSEC2-ConfigureSTIG STIG(セキュリティ技術実装ガイド)標準に準拠したイメージを迅速に構築できるようインスタンスに STIG を適用する
AWSSupport-ConnectivityTroubleshooter 次の接続性の問題を診断する
- VPC リソース
- VPC ピアリングを使用して接続されている同じリージョン内の異なる VPC リソース
- VPC リソースとインターネットゲートウェイを使用したインターネットリソース
- VPC リソースと NAT ゲートウェイを使用したインターネットリソース
AWS-CopySnapshot EBS のポイントインタイムスナップショットをコピーする
AWS-CreateDynamoDBBackup DynamoDB テーブルのバックアップを作成する
AWS-CreateImage EC2 から AMI を作る
AWS-CreateJiraIssue Jira サーバーに Issue を作る
AWS-CreateManagedLinuxInstance Systems Manager が設定された Linux インスタンスを作成する
AWS-CreateManagedWindowsInstance Systems Manager が設定された Windows インスタンスを作成する
AWS-CreateRdsSnapshot RDS インスタンスのスナップショットを作成する
AWS-CreateServiceNowIncident ServiceNow インシデントテーブルにインシデントを作成する
AWS-CreateSnapshot EBS ボリュームのスナップショットの作成する
AWS-DeleteCloudFormationStack CloudFormation スタックを削除する
AWS-DeleteDynamoDbBackup DynamoDB テーブルのバックアップの削除する
AWS-DeleteDynamoDbTableBackups 保持日数またはカウントに基づいて DynamoDB テーブルのバックアップを削除する
AWS-DeleteEbsVolumeSnapshots EBS スナップショットを削除する
AWS-DeleteImage AMI および関連するすべてのスナップショットを削除する
AWSConfigRemediation-DeleteUnusedIAMGroup IAM ユーザーを含まない IAM グループを削除する
AWS-DeleteSnapshot EBS スナップショットを削除する
AWS-DetachEBSVolume EC2 インスタンスから EBS ボリュームをデタッチする
AWS-DisablePublicAccessForSecurityGroup すべての IP アドレスに対して開かれているデフォルトの SSH および RDP ポートを無効にする
AWS-DisableS3BucketPublicReadWrite パブリック S3 バケットの読み取りと書き込みアクセスを無効にする
AWS-EnableCloudTrail CloudTrail のログ記録を有効化する
AWSConfigRemediation-EnableEnhancedMonitoringOnRDSInstance 指定し RDS インスタンスで拡張モニタリングが有効になる
AWS-EnableS3BucketEncryption S3 バケットの暗号化を有効にする
AWSSupport-ExecuteEC2Rescue EC2Rescue ツールを使用してトラブルシューティングを行い,指定された EC2 インスタンス接続の問題を修復する
AWS-ExportOpsDataToS3 Systems Manager Explorer で OpsData サマリーの一覧を取得し指定した S3 バケットにエクスポートする
AWSSupport-GrantPermissionsToIAMUser 指定されたアクセス権限を IAM グループ に付与し既存の IAM ユーザーを追加する
AWSSupport-ListEC2Resources 指定した AWS リージョンの EC2 インスタンスおよび関連リソース(EBS ボリューム,EIP,Auto Scaling グループなど)に関する情報を返す
AWSSupport-ManageRDPSettings RDP ポートおよびネットワークレイヤー認証などのRDP 設定を管理する
AWSSupport-ManageWindowsService ターゲットインスタンス上の Windows サービスを停止,開始,再起動,一時停止,無効にする
AWS-PatchAsgInstance Auto Scaling グループ内の EC2 インスタンスにパッチを適用する
AWS-PatchInstanceWithRollback EC2 インスタンスをスタンディングベースラインに準拠させる
失敗するとルートボリュームをロールバックする
AWS-PublishSNSNotification SNS に通知を発行する
AWS-RebootRdsInstance RDS インスタンスを再起動する
AWS-ReleaseElasticIP 指定された EIP をリリースする
AWSSupport-ResetAccess 指定された EC2 インスタンスの EC2Rescue ツールを使用してEC2 コンソール (Windows) を通じてパスワードの復号を再度有効にするか,新しい SSH キーペア (Linux) を生成して追加する
AWS-ResizeInstance EC2 インスタンスタイプを変更する
AWS-RestartEC2Instance EC2 インスタンスを再起動する
AWS-RunCfnLint cfn-python-lint を使用して YAML および JSON テンプレートを CloudFormation リソース仕様と照合して検証する
AWS-RunPacker Packer を使ってマシンイメージの作成に使用するテンプレートを検証,修正,構築する
AWSSupport-SendLogBundleToS3Bucket EC2Rescue ツールによって生成されたログバンドルを対象のインスタンスから指定された S3 バケットにアップロードする
AWS-SetupInventory
AWSSupport-SetupIPMonitoringFromVPC 指定されたサブネットに EC2 インスタンスを作成し,ping/MTR/traceroute/tracetcp テストを継続的に実行することによって選択したターゲット IP を監視する
AWS-SetupManagedInstance Systems Manager アクセスの IAM ロールを設定する
AWS-SetupManagedRoleOnEC2Instance SSMRoleForManagedInstance マネージド IAM ロールでインスタンスを設定する
AWSSupport-ShareRDSSnapshot 暗号化された RDS スナップショットを共有する
AWSEC2-SQLServerDBRestore S3 に保存されている Microsoft SQL Server データベースのバックアップを Linux インスタンスで実行されている SQL Server 2017 に復元する
AWS-StartEC2Instance 1つ以上の EC2 インスタンスを起動する
AWSSupport-StartEC2RescueWorkflow EC2Rescue 用で作成されたヘルパーインスタンス上で指定された base64 エンコードスクリプト (Bash または Powershell) を実行する
AWS-StartRdsInstance RDS インスタンスを起動する
AWS-StopEC2Instance 1つ以上の EC2 インスタンスを停止する
AWS-StopRdsInstance RDS インスタンスを停止する
AWS-TerminateEC2Instance 1 つまたは複数の EC2 インスタンスを削除する
AWSSupport-TerminateIPMonitoringFromVPC AWSSupport-SetupIPMonitoringFromVPC によって以前に開始された IP モニタリングテストを終了する
AWSSupport-TroubleshootConnectivityToRDS EC2 インスタンスとRDS インスタンスの間の接続の問題を診断する
AWSSupport-TroubleshootDirectoryTrust AWS Managed Microsoft AD と Microsoft Active Directory の間の信頼関係の作成の問題を診断する
AWSSupport-TroubleshootRDP RDP 接続に影響する可能性があるターゲットインスタンスの一般設定 (RDP ポート/ネットワークレイヤー認証/ファイアウォールプロファイルなど) を確認または変更できる
AWSSupport-TroubleshootS3PublicRead 指定したパブリック S3バケットからオブジェクトを読み取る際の問題を診断する
AWSSupport-TroubleshootSSH Linux 用の EC2Rescue ツールをインストールし,EC2Rescue ツールを使用して Linux マシンへのリモート接続を妨げる一般的な問題を SSH 経由で確認する
AWS-UpdateCloudFormationStack S3 バケットに格納されている CloudFormation テンプレートを使用して CloudFormation スタックを更新する
AWS-UpdateLinuxAmi Linux の AMI を更新する
AWS-UpdateWindowsAmi Windows の AMI を更新する
AWSSupport-UpgradeWindowsAWSDrivers 指定された EC2 インスタンスでストレージおよびネットワークドライバーをアップグレードまたは修復する

活用しているドキュメント

自分が活用しているのは AWS-StartEC2InstanceAWS-StopEC2Instance です.コスト削減目的で常時起動する必要がないサーバーの起動/停止に使っています.2つのドキュメントは CloudWatch Events を使って設定します.

f:id:sadayoshi_tada:20201106233637p:plain f:id:sadayoshi_tada:20201106234031p:plain

また,CloudWatch Events から SSM Automation を呼び出すための IAM ロールを設定する必要があります.IAM ロールには AWS 管理ポリシーとして AmazonSSMAutomationRole を設定することで利用可能になります.

まとめ

SSM Automation の概要と実際に使っている EC2 の起動と停止の設定についてまとめました.今までコードを作って管理していたりしましたが,そのコードのメンテナンスや管理をするコストを考えると SSM Automation は事前定義されたドキュメントであればそのコストから解放されて良いなと感じました.まだまだ使いたてなのでもっと活用していきたいです.

関連ドキュメント

docs.aws.amazon.com

FastAPI と Falcon を Docker イメージにした時のサイズとレスポンスのスピードを計測した

タダです.

業務で API で使用する言語を置き換える検討をしていたりするんですが, FastAPI と Falcon を比較した際Docker イメージにした時の軽量さとベンチマークしてみてどれくらいレスポンスが速いかを計測した機会があったので,この記事に検証した内容をまとめておきます.

FastAPI と Falcon の特徴

2つの Web フレームワークがどのような特徴を持っているかをさらっておきます.FastAPI は Python 3.6 以上の速い Web フレームワークであると謳ってます.また,ASGI を使います.

FastAPI fastapi.tiangolo.com

特徴としては次のようなものがあります.

・ 速い。非常に高性能で、NodeJSやGoと同等のパフォーマンスを発揮します(StarletteとPydanticのおかげです)。利用可能なPythonフレームワークの中で最も高速なものの一つです。

・コード化が速い。機能開発のスピードを約200%~300%向上させます。

・バグが少ない。人間(開発者)によるエラーを約40%削減。

・ 直感的。素晴らしいエディタサポート。デバッグ時間を短縮。

・ 簡単。使いやすく、学習しやすいように設計されています。ドキュメントを読む時間を短縮。

・ 短い。コードの重複を最小限に抑えます。各パラメータ宣言から複数の機能を利用できるようになっています。

・ 堅牢。すぐに使えるコードを取得できます。自動でインタラクティブなドキュメントを提供します。

・ 標準ベース。APIのオープンスタンダードに基づいています(完全に互換性があります)。OpenAPI(以前はSwaggerとして知られていた)とJSON Schema。

Falcon も速く,軽量な Web フレームワークです. WSGI を使います.

Falcon falcon.readthedocs.io

特徴としては次のようなものがあります.

URIテンプレートRFCに基づくルート

・リソースへのURIのRESTに触発されたマッピング

・グローバル、リソース、およびメソッドのフック

・慣用的なHTTPエラー応答

Unicodeの完全サポート

・直感的なリクエストオブジェクトとレスポンスオブジェクト

・geventのような非同期ライブラリでうまく機能します

・安全なAPIを作成するための最小限の攻撃対象領域

・包括的なテストスイートで100%のコードカバレッジ

・他のPythonパッケージへの依存関係はありません

Python 2.7、3.5以降をサポート

・PyPyと互換性があります

Docker イメージ化した時のサイズ

Alphine Linux ベースの Docker イメージでビルドした場合のサイズですが,2つとも同じくらいのサイズ感でした.

# Falcon
$ docker images | grep falcon
falcon                                     latest              c74c32855823        About a minute ago   49.2MB
# FastAPI
$ docker images | grep fastapi
fastapi                      latest              88fd7ac8fa13        3 hours ago          50.1MB

どれくらい早くレスポンスがされるかのベンチマーク

wrk2 を使って以下の条件でベンチマークしてみました.

  • プログラムは Hello World を返すもの
  • 30 秒間で固定してベンチマークをする
  • 秒間100,500,1000,5000,10000 リクエストを投げてその結果を確認する

10のコネクションを維持して、秒間 100 リクエスト投げた時の計測

FastAPI,Falcon ともに大きな差異はない.

# FastAPI
wrk2 -t2 -c10 -d30s -R100 http://localhost:8000/
Running 30s test @ http://localhost:8000/
  2 threads and 10 connections
  Thread calibration: mean lat.: 7.524ms, rate sampling interval: 25ms
  Thread calibration: mean lat.: 7.752ms, rate sampling interval: 26ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     6.06ms    3.00ms  22.78ms   79.35%
    Req/Sec    53.01     71.93   208.00     80.30%
  3002 requests in 30.01s, 416.29KB read
Requests/sec:    100.02
Transfer/sec:     13.87KB

# Falcon
wrk2 -t2 -c10 -d30s -R100 http://localhost:8080/
Running 30s test @ http://localhost:8080/
  2 threads and 10 connections
  Thread calibration: mean lat.: 32.647ms, rate sampling interval: 209ms
  Thread calibration: mean lat.: 20.032ms, rate sampling interval: 185ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     6.24ms    4.06ms  29.98ms   82.81%
    Req/Sec    49.44      5.69    62.00     84.00%
  3002 requests in 30.01s, 483.72KB read
Requests/sec:    100.03
Transfer/sec:     16.12KB

50のコネクションを維持して、秒間 500 リクエスト投げた時の計測

Latency で FastAPI と Falcon の間に差がでてきた.

# FastAPI
wrk2 -t2 -c50 -d30s -R500 http://localhost:8000/
Running 30s test @ http://localhost:8000/
  2 threads and 50 connections
  Thread calibration: mean lat.: 7.982ms, rate sampling interval: 28ms
  Thread calibration: mean lat.: 7.915ms, rate sampling interval: 27ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     5.11ms    2.25ms  19.73ms   81.05%
    Req/Sec   254.29     63.28   423.00     61.43%
  14991 requests in 30.00s, 2.03MB read
Requests/sec:    499.66
Transfer/sec:     69.29KB

# Falcon
wrk2 -t2 -c50 -d30s -R500 http://localhost:8080/
Running 30s test @ http://localhost:8080/
  2 threads and 50 connections
  Thread calibration: mean lat.: 46.716ms, rate sampling interval: 204ms
  Thread calibration: mean lat.: 45.854ms, rate sampling interval: 200ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    14.29ms   20.81ms 135.04ms   88.48%
    Req/Sec   250.44      6.95   280.00     80.10%
  14991 requests in 30.00s, 2.36MB read
Requests/sec:    499.63
Transfer/sec:     80.51KB

100のコネクションを維持して、秒間 1000 リクエスト投げた時の計測

1000リクエストになったら Requests を捌く量も Latency と同じくひらいてきた.

# FastAPI
 wrk2 -t2 -c100 -d30s -R1000 http://localhost:8000/
Running 30s test @ http://localhost:8000/
  2 threads and 100 connections
  Thread calibration: mean lat.: 241.727ms, rate sampling interval: 819ms
  Thread calibration: mean lat.: 240.797ms, rate sampling interval: 815ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   241.60ms  260.77ms 777.22ms   75.42%
    Req/Sec   481.31     47.68   583.00     79.17%
  29201 requests in 30.01s, 3.96MB read
Requests/sec:    973.16
Transfer/sec:    135.12KB

# Falcon
wrk2 -t2 -c100 -d30s -R1000 http://localhost:8080/
Running 30s test @ http://localhost:8080/
  2 threads and 100 connections
  Thread calibration: mean lat.: 124.110ms, rate sampling interval: 383ms
  Thread calibration: mean lat.: 124.684ms, rate sampling interval: 393ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   527.57ms  528.20ms   1.86s    73.48%
    Req/Sec   161.29    255.12     0.99k    71.57%
  16458 requests in 30.27s, 2.59MB read
  Socket errors: connect 0, read 0, write 0, timeout 600
Requests/sec:    543.71
Transfer/sec:     87.61KB

500のコネクションを維持して、秒間 5000 リクエスト投げた時の計測

# FastAPI
wrk2 -t2 -c500 -d30s -R5000 http://localhost:8000/
Running 30s test @ http://localhost:8000/
  2 threads and 500 connections
  Thread calibration: mean lat.: 3006.903ms, rate sampling interval: 11796ms
  Thread calibration: mean lat.: 3028.214ms, rate sampling interval: 11796ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    12.31s     3.42s   18.87s    58.52%
    Req/Sec   456.00     68.00   524.00    100.00%
  26269 requests in 30.01s, 3.56MB read
  Socket errors: connect 251, read 64, write 0, timeout 3514
Requests/sec:    875.44
Transfer/sec:    121.59KB

# Falcon
wrk2 -t2 -c500 -d30s -R5000 http://localhost:8080/
Running 30s test @ http://localhost:8080/
  2 threads and 500 connections
  Thread calibration: mean lat.: 2613.849ms, rate sampling interval: 10739ms
  Thread calibration: mean lat.: 2724.868ms, rate sampling interval: 10936ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     8.13s     2.36s   15.61s    65.29%
    Req/Sec   275.50     29.50   305.00    100.00%
  16381 requests in 31.28s, 2.58MB read
  Socket errors: connect 251, read 153, write 0, timeout 5439
Requests/sec:    523.76
Transfer/sec:     84.39KB

1000のコネクションを維持して、秒間 10000 リクエスト投げた時の計測

# FastAPI
wrk2 -t2 -c1000 -d30s -R10000 http://localhost:8000/
Running 30s test @ http://localhost:8000/
  2 threads and 1000 connections
  Thread calibration: mean lat.: 3875.593ms, rate sampling interval: 13352ms
  Thread calibration: mean lat.: 3795.580ms, rate sampling interval: 13303ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    12.20s     3.03s   18.14s    57.44%
    Req/Sec   514.50     39.50   554.00    100.00%
  27956 requests in 30.00s, 3.79MB read
  Socket errors: connect 751, read 0, write 0, timeout 9763
Requests/sec:    931.79
Transfer/sec:    129.26KB

# Falcon
wrk2 -t2 -c1000 -d30s -R10000 http://localhost:8080/
Running 30s test @ http://localhost:8080/
  2 threads and 1000 connections
  Thread calibration: mean lat.: 3676.434ms, rate sampling interval: 14540ms
  Thread calibration: mean lat.: 3547.812ms, rate sampling interval: 14319ms
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     7.69s     2.42s   17.81s    67.25%
    Req/Sec   155.50      5.50   161.00    100.00%
  16445 requests in 30.53s, 2.59MB read
  Socket errors: connect 751, read 45, write 0, timeout 12373
Requests/sec:    538.65

Docker イメージにした時のサイズとベンチマークを踏まえての所感

検証の結果を踏まえて次の感想を持ちました.

  • Docker イメージにした時の軽量さは2つに大差はない
  • リクエスト数が増えていった時も FastAPI のほうが処理スピードが速くリクエストを捌く量も多い

また, FastAPI のドキュメントをみていると,FastAPI を作る時に既存のフレームワークを参考に開発したと解説されており, Falcon も参考にして開発されているようなので改良されたのが FastAPI って位置付けなのだと感じました.

fastapi.tiangolo.com

まとめ

FastAPI と Falcon の比較をするための検証で行ったことを整理してみました.ベンチマークしてみて FastAPI が速くてパフォーマンスも優れているという所以を感じることができました.FastAPI を業務で使う機会が出てきたら習熟していけるようになっていきたいです.

データドリブンな組織・仕組み作りを学ぶために『DMM.com を支えるデータ駆動戦略』を読んだ

タダです.

データドリブンな組織や仕組みの考え方や作り方を学びたいと思って「DMM.com を支えるデータ駆動戦略」を読みました.本書を読もうと思ったもう1つのきっかけが DMM.com CTO 松本さんの note を購読しており,その内容が本書でも反映されているとみたので興味をもった次第です.この記事では,その書評記事を書いていきます.

DMM.comを支えるデータ駆動戦略

DMM.comを支えるデータ駆動戦略

目次

  • Chapter 1 データ駆動戦略の全体像を理解する
  • Chapter 2 事業を数値モデルで表現すると予測と自動化ができる
  • Chapter 3 仮説検証を繰り返すことで不確実性を下げていく
  • Chapter 4 なぜ、学習する組織が必要なのか
  • Chapter 5 戦略的Unlearnによる組織モデルの構築
  • Chapter 6 組織構造から発生する力学を操作する
  • Chapter 7 データを集約して民主化する
  • Chapter 8 商品レビューをデータ駆動でグロースさせてみよう!

本書はいくつか目的別の読み方が紹介されているのですが,今回は全体のトピックを抑えたいため Chapter 1,3,4,8 の内容を先行で読んだので章ごとに所感をまとめます.

章ごとの所感

Chapter 1 データ駆動戦略の全体像を理解する

Chapter 1 ではデータ駆動戦略の全体像について説明されてます.データ駆動戦略のために事業の数値モデルによる KPI ツリー作成,課題の可視化での施作の優先度付け,「仮説 -> 実験 -> 学習 -> 意思決定」を回す必要性が書かれています.武器となるのはデータで,事業の KPI を数値化して施作の結果を計測することによって事業の不確実性を下げたり,意思決定にもデータを使えば客観的な指針となり,スピード感も増すとあります.

自分の会社ではデータドリブンな組織を目指しています.データを基に意思決定する土壌はあるのですが,そのデータが蓄積されてないものや振り返りを数値をみながらやれてない部分があるのでやっていきたいと感じました.

Chapter 3 仮説検証を繰り返すことで不確実性を下げていく

Chapter 3 では如何に仮設検証を繰り返して事業が成功するかどうかわからない不確実性を下げる考え方やアプローチが紹介されています.仮設検証の全体フローは「仮説 -> 実験 -> 学習 -> 意思決定」の中で,実験の工程を多くできる環境が必要になるとあります.組織が大きくなると計画に時間をかけがちだが時間をかけるのは実験を正しい方向で実行し,失敗を許容できる範囲でスピードをあげていけるかが重要になります.

そのために影響範囲を小さくしていくいくための基準(予算に対する影響度)を定めつつその範囲で実験を行う.また,失敗のハードルを下げる方法として A/Bテスト MVP(Minimum Viable Product)が紹介されています.失敗をどこまで許容してその範囲で実験を繰り返していけるか(イテレーティブ),実験の中でのボトルネックを可視化(バリューストリーム),WIP をカンバン化などアジャイルの型が本章で登場しました.不確実性がある事業をスケールさせるために変化に強くあるためのアプローチが本章で取り上げられていたと思います.

自分が所属する会社は小さく早く実験を行うことは寛容なので土壌はあるなと思いつつ,本章のようなアジャイルライクにやれているかと問われるとそこまでではないかもしれないので本章のメソッドを取り入れられるところは取り入れたいと感じました.

Chapter 4 なぜ、学習する組織が必要なのか

Chapter 3 で仮設検証を回すためには仮説に対する検証から正しく学習できる組織であらねばならず,誰かからの指示待ちではなく個々人が状況を判断していく組織を目指すことが書かれています.本章では Unlearn という言葉が登場します.検証結果から学んで終わりではなく,都度検証ごとに適応し続けて学習する(アップデートし続ける)行為を指します.チームにあった Unlearn のプロセスを作っていくことが書かれてありました.自分の会社に当てはめてみると小さい組織だからその場その場の学習して経験を積む機会は多いと思うのですが,それがチームに浸透しているかというと特定の人に寄っているかもしれないと感じるので相互に学習をアップデートしつづけるようなプロセスを作りたいです.

note.com

Chapter 8 商品レビューをデータ駆動でグロースさせてみよう!

Chapter 8 はケーススタディでデータ駆動による事業グロースのアプローチの仕方が載っていました.自分は事業開発や事業責任みたいなロールではないですが,ロールに囚われずにこの辺はやっていきたいし,他のチームメンバーと共同で進めていきたいと思っています.自分が事業をみるような立場になった時に備えて繰り返し本章を読んでいこうと思います.

まとめ

DMM.com を支えるデータ駆動戦略」の全体的なトピックをさらうために読んだ所感を整理しました.事業の不確実性に対して如何に失敗を許容して仮設検証の結果を血肉にするために学んでいく,データ駆動戦略の考え方を大枠をつかめたと思いますし,多数の事業を行われている DMM.com のナレッジを読めて学びが多い本だと感じます.全般を読めたわけではないので他のパートを読んでいきます!