継続は力なり

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

『データドリブンな組織を目指す、AWSを活用したデータ分析基盤の取り組み』と題して AWS DevDay で登壇した

タダです.

10/21 に AWS DevDay Online Japan にて「データドリブンな組織を目指す、AWSを活用したデータ分析基盤の取り組み」と題して登壇させていただきました.この記事で登壇資料と登壇を振り返りをしていきます.

aws.amazon.com

登壇資料

登壇資料はこちらです.

今回の登壇の振り返り

今回の登壇ではスナックミー におけるデータ活用における課題,その課題と向き合った取組みの現状,今後やっていきたいことをお話しさせていただきました.そのため,これからデータ基盤を作りたい,AWS のデータ関連サービスを知りたいといった方向けの事例ベースセッションでした.

課題感としては3つあり,そのうち2つを自分がイベントまでに取り組んでいたのでそのお話をさせてもらいました.Aurora からデータを S3 にエクスポートする部分は発表ではお話が漏れていたのですが,Aurora から S3 への経路は VPC エンドポイントを通すようにして AWS 内の内部ネットワーク内で完結するようにし,データ自体も KMS キーで暗号化しています.また,Athena でクエリをかけるデータもログの保管先も暗号化を有効化してます.

至らないところが多々あったと思うのですが,自分の発表をご覧いただいて反応をくださった @xhiroga さんとデータ基盤の意見交換の機会をいただきました.主に1人で進めているので同じデータ基盤のフェーズの方とお話する機会をいただいたことも,登壇したことでこのように声をかけてもらえたことも大変ありがたいことです.

まとめ

データ基盤として取り組み始めたばかりで発表の内容としてはまだまだな内容が多いでしたが,今回登壇の機会をいただけたこと,反応をいただけたこと,本当にありがとうございました! もっと基盤をブラッシュアップして違う機会でお話させてもらえるようにやっていきます.

関連記事

sadayoshi-tada.hatenablog.com

Mackerel の公式プラグインを使ってメトリック監視を行う

タダです.

Mackerel でメトリック監視を実装するにあたって Mackerel 公式プラグインを検証する機会があったのでこの記事でその内容をまとめていきます.

mackerel.io

github.com

Mackerel の導入環境

Mackerel の導入環境として Amazon Linux2 に入れました.公式プラグインをインストールします.

$ sudo yum install mackerel-agent-plugins

mackerel-agent.conf の中身を見てみると,いろんなプラグインを使うことができる状況です.

$ cat /etc/mackerel-agent/mackerel-agent.conf
# pidfile = "/var/run/mackerel-agent.pid"
# root = "/var/lib/mackerel-agent"
# verbose = false
# apikey = ""

# [host_status]
# on_start = "working"
# on_stop  = "poweroff"

# [filesystems]
# ignore = "/dev/ram.*"

# Configuration for Custom Metrics Plugins
# see also: https://mackerel.io/ja/docs/entry/advanced/custom-metrics

# followings are mackerel-agent-plugins https://github.com/mackerelio/mackerel-agent-plugins

# Plugin for Apache2 mod_status
#   By default, the plugin accesses to http://127.0.0.1/server-status?auto
# [plugin.metrics.apache2]
# command = "mackerel-plugin-apache2"

# Plugin for EC2 CPU Credit
# [plugin.metrics.aws-ec2_cpucredit]
# command = "mackerel-plugin-aws-ec2-cpucredit"

# Plugin for AWS ELB
# [plugin.metrics.aws-elb]
# command = "mackerel-plugin-aws-elb"

# Plugin for Amazon RDS
# [plugin.metrics.aws-rds]
# command = "mackerel-plugin-aws-rds -identifier=<required>"

# Plugin for Elasticsearch
#   By default, the plugin accesses Elasticsearch on localhost.
# [plugin.metrics.elasticsearch]
# command = "mackerel-plugin-elasticsearch"

# Plugin for HAProxy
#   By default, the plugin accesses Elasticsearch on localhost.
# [plugin.metrics.haproxy]
# command = "mackerel-plugin-haproxy"

# Plugin for JVM
#   Required javaname
# [plugin.metrics.jvm]
# command = "mackerel-plugin-jvm -javaname=<required>"

# Plugin for Linux
# [plugin.metrics.linux]
# command = "mackerel-plugin-linux"

# Plugin for Memcached
# [plugin.metrics.memcached]
# command = "mackerel-plugin-memcached"

# Plugin for MongoDB
# [plugin.metrics.mongodb]
# command = "mackerel-plugin-mongodb"

# Plugin for MySQL
#   Appropriate previlege settings required.
#   By default, the plugin accesses MySQL on localhost by 'root' with no password.
# [plugin.metrics.mysql]
# command = "mackerel-plugin-mysql"

# Plugin for Nginx
#   By default, the plugin accesses to http://localhost:8080/nginx_status
# [plugin.metrics.nginx]
# command = "mackerel-plugin-nginx"

# Plugin for PHP APC
# [plugin.metrics.php-apc]
# command = "mackerel-plugin-php-apc"

# Plugin for Plack
#   By default, the plugin accesses to http://localhost:5000/server-status?json
# [plugin.metrics.plack]
# command = "mackerel-plugin-plack"

# Plugin for PostgreSQL
#   Appropriate previlege settings required.
#   By default, the plugin accesses PostgreSQL on localhost.
# [plugin.metrics.postgres]
# command = "mackerel-plugin-postgres"

# Plugin for Redis
#   By default, the plugin accesses Redis on localhost.
#   Currently AUTH password has not been supported yet.
# [plugin.metrics.redis]
# command = "mackerel-plugin-redis"

# Plugin for SNMP
# [plugin.metrics.pps]
# command = "mackerel-plugin-snmp -name='pps' -community='private' '.1.3.6.1.2.1.31.1.1.1.7.2:eth01in:1:0' '.1.3.6.1.2.1.31.1.1.1.11.2:eth01out:1:0'"

# Plugin for Squid
# [plugin.metrics.squid]
# command = "mackerel-plugin-squid"

# Plugin for Varnish
# [plugin.metrics.varnish]
# command = "mackerel-plugin-varnish"

# Plugin for munin (wrapper)
# [plugin.metrics.nfsd]
# command = "mackerel-plugin-munin -plugin=/usr/share/munin/plugins/nfsd"
# [plugin.metrics.bind9]
# command = "mackerel-plugin-munin -plugin=/etc/munin/plugins/bind9 -plugin-conf-d=/etc/munin/plugin-conf.d"
# [plugin.metrics.postfix]
# command = "MUNIN_LIBDIR=/usr/share/munin mackerel-plugin-munin -plugin=/usr/share/munin/plugins/postfix_mailqueue -name=postfix.mailqueue"

# followings are other samples
# [plugin.metrics.vmstat]
# command = "ruby /etc/sensu/plugins/system/vmstat-metrics.rb"
# [plugin.metrics.curl]
# command = "ruby /etc/sensu/plugins/http/metrics-curl.rb"

プロセス監視の実装

今回は,Nginx のプロセスチェックを設定してみます.Nginx はコメントを外すだけで完了します.

# Plugin for Nginx
#   By default, the plugin accesses to http://localhost:8080/nginx_status
[plugin.metrics.nginx]
command = "mackerel-plugin-nginx"

Nginx のプラグインを使うために /etc/nginx/conf.d/default.conf を作成して以下の定義を追加しておく必要があります.併せてこのファイルを読むこむように Config を変更します.

server {
    listen 8080;
    server_name localhost;
    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

Nginx の設定ファイルを読み込ませます.

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo nginx -s reload

そして,mackerel-agent を再起動します.

$ sudo systemctl restart mackerel-agent

実装後のチェック

まず,Nginx のプラグインが機能しているとコマンドを打つと,各監視パラメーターのステータスを表示してくれます.また,Mackerel の監視画面上でもメトリックとして確認できます.この状態であればホストメトリック監視でプロセス数をアラートに設定していけます.

$ mackerel-plugin-nginx
nginx.connections.connections   1.000000  1603121705
2020/10/19 15:35:05 OutputValues:  Too long duration
2020/10/19 15:35:05 OutputValues:  Too long duration
2020/10/19 15:35:05 OutputValues:  Too long duration
nginx.queue.reading 0.000000  1603121705
nginx.queue.writing 1.000000  1603121705
nginx.queue.waiting 0.000000  1603121705
  • nginx.connections.connections
  • nginx.queue.reading
  • nginx.queue.waiting
  • nginx.queue.writing
  • nginx.requests.accepts
  • nginx.requests.handled
  • nginx.requests.requests

f:id:sadayoshi_tada:20201020003622p:plain

まとめ

Mackerel の公式プラグインを使って Nginx のメトリック監視を行ってみました.他にも監視できる物が既に揃っているので適宜使い分けて対応していきたいと思います.

20201020 追記

a-know さんより教えていただき,本記事の内容はホスト監視ではなくメトリック監視の検証記事に当たるので記事の内容を修正しました.本記事では扱えていないのですが,プロセス監視には check-procsを活用するのが良いです.実装ではメトリック監視とプロセス監視両軸でいきたいと思います! a-know さん,コメントいただきありがとうございます🙇‍♂️

関連記事

sadayoshi-tada.hatenablog.com

Mackerel の CLI ツール『mkr』を使ってみる

タダです.

はてな社の「Mackerel」を業務利用することになりました.使い始めなこともあり画面から設定をいじっていたのですが, CLI ツールである「mkr」の存在を知ったので,導入と監視設定を取得したりしていきます.

github.com

mkr 導入

mkr」の導入を行ってきます.なお,導入環境は macOS X Catalina です.

sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.6
BuildVersion:   19G2021

mackerel.io

macOS の場合は brew で完結します.

インストールコマンド

$ brew tap mackerelio/mackerel-agent
$ brew install mkr

インストール完了後,バージョンを確認して 0.40.4 でした.

$ mkr --version
mkr version 0.40.4 (rev:ef54761)
$ mkr
NAME:
   mkr - A CLI tool for mackerel.io

USAGE:
   mkr [global options] command [command options] [arguments...]

VERSION:
   0.40.4 (rev:ef54761)

AUTHOR:
   Hatena Co., Ltd.

COMMANDS:
   status       Show the host
   hosts        List hosts
   create       Create a new host
   update       Update the host
   throw        Post metric values
   metrics      Fetch metric values
   fetch        Fetch latest metric values
   retire       Retire hosts
   services     List services
   monitors     Manipulate monitors
   channels     List notification channels
   alerts       Retrieve/Close alerts
   dashboards   Generating custom dashboards
   annotations  Manipulate graph annotations
   org          Fetch organization
   plugin       Manage mackerel plugin
   checks       Utility for check plugins
   wrap         Wrap and monitor batch jobs to run with cron etc
   help, h      Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --conf value     Config file path (default: "/Users/sadayoshitada/Library/mackerel-agent/mackerel-agent.conf")
   --apibase value  API Base (default: "https://api.mackerelio.com")
   --help, -h       show help
   --version, -v    print the version

現状の監視設定を取得する

それでは,現状の監視設定を取得してみます.「mkr」を使うためにはまず API キーを設定します.API キーは https://mackerel.io/orgs/[オーガナイゼーション名]?tab=apikeysで確認できます.

$ export MACKEREL_APIKEY=<API_KEY>

設定後,監視設定を取ってくるのは monitors pull で行います.コマンドを実行すると monitors.json がコマンド実行のディレクトリに作成されます.

$ mkr monitors pull
      info Monitor rules are saved to 'monitors.json' (1 rules).

monitors.json の中身をみると,現状のアラート設定のみが入っている状況でした.このファイルを GitHub で管理すると変更履歴も管理できて良さそうです.

[
    {
        "id": "XXXX",
        "name": "connectivity",
        "type": "connectivity"
    }
]

まとめ

mkr」の導入と画面で設定した監視設定を取得してきました.運用フローを作っていく中でこのツールを使って変更管理や追加の監視設定を入れたりを検討していきたいと考えてます.今後,Mackerel のナレッジを貯めていきます 🙌

【Athena の躓きシリーズ】Athena で JSON データを出力したい時にハマったこと

タダです.

業務で JSON データが入っているテーブルを特定条件で抽出して,集計目的で別テーブルにしたいと思ったときにハマったことがあったので対応を記事にします.

今回のハマったことの概要

今回は下記のようにクエリを投げてjsondataという文字列になった JSON 構造データから特定のキーで情報を抽出したいと思ったのですが, 別テーブルして集計用バケットに吐き出そうとしたところ NOT_SUPPORTED: Unsupported Hive type: json とエラーが出ました.

実行したクエリ

CREATE TABLE XXXX
WITH  (
  format='Parquet',
  external_location='s3://XXXX/jsondata/'
) AS
SELECT 
  date
, json_extract(json_parse(jsondata),'$.hoge') 
, json_extract(json_parse(jsondata),'$.fuga')
, json_extract(json_parse(jsondata),'$.hogo') 
, json_extract(json_parse(jsondata),'$.fugo') 
 FROM "XXXX"."XXXX"  
 ORDER BY date DESC

対応内容

別テーブルとして出したかったのですが,クエリの結果を手にいられれば良いので,別のアプローチを探しました.クエリした結果は Athena の実行ログが保管されている S3 バケットCSV 形式で出力されています.CSV ファイルはクエリの ID で探せたこともあり,自動化したいのでAWS CLIシェルスクリプトにし,CSV ファイルを集計用の別バケットに移動させるようにしました.

シェルスクリプト化した部分抜粋

# クエリ ID を取得
export ATHENA_QUERY_ID=`aws athena start-query-execution --query-string "SELECT 
  date
, json_extract(json_parse(jsondata),'$.hoge') 
, json_extract(json_parse(jsondata),'$.fuga')
, json_extract(json_parse(jsondata),'$.hogo') 
, json_extract(json_parse(jsondata),'$.fugo') 
 FROM "XXXX"."XXXX"  
 ORDER BY date DESC" --result-configuration OutputLocation=s3:/XXXX/ --output text`

# クエリ ID で CSV ファイルを見つけて,集計用バケットに移動
aws s3 cp s3://XXXX/$ATHENA_QUERY_ID.csv s3://XXXX/jsondata/

上記の対応をすることで集計用バケットCSV ファイルが移動してデータ解析ができるようになりました.

f:id:sadayoshi_tada:20201007231208p:plain

まとめ

Athena で JSON データが入っているテーブルを特定条件で抽出した時にハマった内容と対応内容を整理しました.JSON データを別テーブルにしたことがなかったのでハマったのですが,動作仕様もしれて良かったです.この記事が同じ事象に当たった方の参考情報になれば嬉しいです.

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

Lambda のカスタムランタイムで AWS CLI を実行させる

タダです.

Aurora のスナップショットを S3 にエクスポートする処理を自動化したいと思って,Lambda でカスタムランタイムを使ってAWS CLI を実行する検証をしたので備忘録として記事に残しておきます.

カスタムランタイムのコード

カスタムランタイムを実行するためにはbootstrapと一緒に関数のコードをデプロイパッケージに含んでアップロードします.今回は,bootstrapにて AWS CLI の実行準備を行って,関数を実行するように設定したコードfunction.shを用意しました.なお,スナップショット は自動で取得されているものをエクスポートの対象としており,スナップショットを元に作った Athena のテーブルは作成済みの状況です.

bootstrap

#!/bin/sh
set -euo pipefail

# AWS CLI DirectorySetting
export HOME="/tmp"
export PATH="$HOME/.local/bin:$PATH"

# AWS CLI Setup
cd /tmp
curl -sSL https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --user
pip install awscli --user

# Initialization - load function handler
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"

while true
do
    # Request the next event from the Lambda runtime
    HEADERS="$(mktemp)"
    EVENT_DATA=$(curl -v -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
    INVOCATION_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)

    # Execute the handler function from the script
    RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")

    # Send the response to Lambda runtime
    curl -v -sS -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$INVOCATION_ID/response" -d "$RESPONSE"
done

function.sh

function handler() {
    export AWS_DEFAULT_REGION=ap-northeast-1

    # スナップショット名を取得
    export SNAPSHOT_NAME_BEFORE=`aws rds describe-db-cluster-snapshots --snapshot-type automated --query 'DBClusterSnapshots[0].DBClusterSnapshotIdentifier' --output text`
    export SNAPSHOT_NAME=`echo ${SNAPSHOT_NAME_BEFORE} | cut -c 5-`

    # RDSのスナップショットをS3にエクスポート 
    aws rds start-export-task \
        --export-task-identifier ${SNAPSHOT_NAME} \
        --source-arn arn:aws:rds:ap-northeast-1:XXXXXXXXXXXX:cluster-snapshot:rds:${SNAPSHOT_NAME}  \
        --export-only "hogeschema.hogetable1" "hogeschema.hogetable2" \
        --s3-bucket-name [S3 バケット名] \
        --iam-role-arn [IAM ロールの ARN] \
        --kms-key-id [KMS の ARN]  \

    # S3のパスを変更
    aws athena start-query-execution --query-string "ALTER TABLE [テーブル名] SET LOCATION 's3://[S3バケット名]/$SNAPSHOT_NAME/[エクスポートしたデータへのパス]';" --result-configuration OutputLocation=s3://[S3バケット名]/
}

参考にしたドキュメント

docs.aws.amazon.com

docs.aws.amazon.com

docs.aws.amazon.com

カスタムランタイムのコードをデプロイ

カスタムランタイムのコードを書き終えたら権限を設定して zip で圧縮します.

$ chmod 755 function.sh bootstrap
$ zip function.zip function.sh bootstrap

上記の準備ができたらカスタムランタイムの関数を作成します.

 aws lambda create-function --function-name [関数名] \
--zip-file fileb://function.zip --handler function.handler --runtime provided \
--role arn:aws:iam::XXXXXXXXXXXX:role/lambda-role

マネジメントコンソールで関数が作成されたことを確認できました.

f:id:sadayoshi_tada:20201004171218p:plain

まとめ

カスタムランタイムで Lambda を使うのが初めてだったので記事にまとめておきました.同じ用途で使いたいと考えている人にとって参考になれば嬉しいです.

関連記事

sadayoshi-tada.hatenablog.com