Hatena::ブログ(Diary)

ablog このページをアンテナに追加 RSSフィード

2018-02-17

Python の Web フレームワーク Flaskを使ってみる

Python の Web フレームワーク Flask を使ってみる


$ pip install Flask
mkdir flask
cd flask
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    name = "Hello World"
    return name

@app.route('/good')
def good():
    name = "Good"
    return name

if __name__ == "__main__":
    app.run(debug=True)
  • 起動する
python hello.py

f:id:yohei-a:20180217204830p:image:w360


参考

2018-02-11

EMRからS3にアクセス時のAPI発行回数を調べる

PySpark on EMR で S3 上の1オブジェクトの読込みに API 発行回数が1回か複数回か調べてみた。


CloudTrail で API 発行を捕捉する

$ export LANG=C
$ export TZ=UTC
$ export AWS_DEFAULT_REGION=ap-northeast-1
$ aws s3api create-bucket --bucket az-s3-trail-log \
	--create-bucket-configuration LocationConstraint=ap-northeast-1
$ cat <<EOF > policy.json
{
     "Version": "2012-10-17",
     "Statement": [
          {
               "Sid": "AWSCloudTrailAclCheck20180211",
               "Effect": "Allow",
               "Principal": {
                    "Service": "cloudtrail.amazonaws.com"
               },
               "Action": "s3:GetBucketAcl",
               "Resource": "arn:aws:s3:::az-s3-trail-log"
          },
          {
               "Sid": "AWSCloudTrailRead20180211",
               "Effect": "Allow",
               "Principal": {
                    "Service": "cloudtrail.amazonaws.com"
               },
               "Action": "s3:*",
               "Resource": "arn:aws:s3:::az-s3-trail-log/*",
               "Condition": {
                    "StringEquals": {
                         "s3:x-amz-acl": "bucket-owner-full-control"
                    }
               }
          }
     ]
}
EOF
$ aws s3api put-bucket-policy --bucket az-s3-trail-log --policy file://policy.json
$ aws s3api create-bucket --bucket az-s3-trail-test \
	--create-bucket-configuration LocationConstraint=ap-northeast-1
  • trail の作成
$ aws cloudtrail create-trail --name s3-trail --s3-bucket-name az-s3-trail-log
$ cat <<EOF >event_selector.json
[
    {
        "ReadWriteType": "All",
        "IncludeManagementEvents": false,
        "DataResources": [
            {
                "Type": "AWS::S3::Object",
                "Values": [
                    "arn:aws:s3:::az-s3-trail-test/"
                ]
            }
        ]
    }
]
EOF
$ aws cloudtrail put-event-selectors --trail-name s3-trail \
	--event-selectors file://event_selector.json
{
    "EventSelectors": [
        {
            "IncludeManagementEvents": false,
            "DataResources": [
                {
                    "Values": [
                        "arn:aws:s3:::az-s3-trail-test/"
                    ],
                    "Type": "AWS::S3::Object"
                }
            ],
            "ReadWriteType": "All"
        }
    ],
    "TrailARN": "arn:aws:cloudtrail:ap-northeast-1:**********:trail/s3-trail"
}
  • ロギングの開始
$ aws cloudtrail start-logging --name arn:aws:cloudtrail:ap-northeast-1:**********:trail/s3-trail

EMR から S3 にアクセスする

  • PySpark で S3 のファイルにアクセスする
$ perl -le 'print for 1..100000000' > number.txt
$ aws s3 cp number.txt s3://az-s3-trail-test/
$ pyspark
>>> rdd = sc.textFile("s3://az-s3-trail-test/number.txt")
>>> rdd.count()
>>> exit()
  • 行数を倍にしてみる
$ perl -le 'print for 1..200000000' > number2x.txt
$ aws s3 cp number2x.txt s3://az-s3-trail-test/
$ pyspark
>>> rdd = sc.textFile("s3://az-s3-trail-test/number.txt")
>>> rdd.count()
>>> exit()

EMR から S3 にアクセスした際の API 発行回数を調べる

  • Trail ログから API 発行回数を確認する。
$ aws s3 ls --recursive s3://az-s3-trail-log
$ aws s3 cp s3://az-s3-trail-log/AWSLogs/*********/CloudTrail/ap-northeast-1/2018/02/11/*********_CloudTrail_ap-northeast-1_20180211T1030Z_8UxnbO7KHiDJe42P.json.gz ./
$ gunzip *********_CloudTrail_ap-northeast-1_20180211T1030Z_8UxnbO7KHiDJe42P.json.gz
$ cat *********_CloudTrail_ap-northeast-1_20180211T1030Z_8UxnbO7KHiDJe42P.json|jq -r '.Records[]|select(.userAgent|contains("ElasticMapReduce"))|@text "\(.userAgent)\t\(.eventName)"'|head
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	HeadBucket
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	HeadObject
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	HeadBucket
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	HeadObject
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	GetObject
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	GetObject
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	HeadBucket
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	HeadBucket
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	HeadObject
[ElasticMapReduce/1.0.0 emrfs/s3n {}, aws-sdk-java/1.11.129 Linux/4.9.70-25.242.amzn1.x86_64 OpenJDK_64-Bit_Server_VM/25.151-b12/1.8.0_151 scala/2.11.8]	HeadBucket
$ cat *********_CloudTrail_ap-northeast-1_20180211T1030Z_8UxnbO7KHiDJe42P.json|jq -r '.Records[]|select(.userAgent|contains("ElasticMapReduce"))|@text "\(.userAgent)\t\(.eventName)"'|perl -lane 'print $F[$#F]'|sort|uniq -c
  27 GetObject
  13 HeadBucket
  12 HeadObject
  • 行数を倍にした時は API 発行回数が増えている。
$ cat *.json|jq -r '.Records[]|select(.userAgent|contains("ElasticMapReduce"))|@text "\(.userAgent)\t\(.eventName)"'|perl -lane 'print $F[$#F]'|sort|uniq -c 
  57 GetObject
  13 HeadBucket
  17 HeadObject

AWS CLI で s3 cp した際の API 発行回数を調べる

$ time aws s3 cp s3://az-s3-trail-test/number.txt s3://az-to/
copy: s3://az-s3-trail-test/number.txt to s3://az-to/number.txt

real	0m5.046s
user	0m1.073s
sys	0m0.232s

参考

S3イベント通知はオブジェクト作成完了後に通知される

S3イベント通知を使うと、S3バケットオブジェクトが作成されれたタイミングでイベント・ドリブンでLambda関数を呼び出したりSNSトピックにメッセージを送ったりできるが、作成開始ではなく完了したタイミングでイベント通知されることを確認した。


事前準備

環境変数を設定する
$ export LANG=C
$ export TZ=UTC
$ export AWS_DEFAULT_REGION=ap-northeast-1
SNSトピックを作成する
  • トピック名が重複しないよう既存のを確認する
$ aws sns list-topics
  • SNSトピックを作成する
$ aws sns create-topic --name s3-event-test
$ aws sns subscribe --topic-arn arn:aws:sns:ap-northeast-1:*********:s3-event-test \
	--protocol email \
	--notification-endpoint ******@gmail.com
  • 指定したメールアドレスに確認メールが届くので本文のリンクをクリックする。
Subject: AWS Notification - Subscription Confirmation
Body:
You have chosen to subscribe to the topic: 
arn:aws:sns:ap-northeast-1:*********:s3-event-test

To confirm this subscription, click or visit the link below (If this was in error no action is necessary): 
Confirm subscription
  • トピックのポリシーを設定する
$ cat << EOF > sns_topic_policy.json
{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SNS:Publish",
        "SNS:RemovePermission",
        "SNS:SetTopicAttributes",
        "SNS:DeleteTopic",
        "SNS:ListSubscriptionsByTopic",
        "SNS:GetTopicAttributes",
        "SNS:Receive",
        "SNS:AddPermission",
        "SNS:Subscribe"
      ],
      "Resource": "arn:aws:sns:ap-northeast-1:********:s3-event-test",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:s3:::az-test-2018"
        }
      }
    }
  ]
}
EOF
$ aws sns set-topic-attributes \
	--topic-arn arn:aws:sns:ap-northeast-1:********:s3-event-test \
	--attribute-name Policy \
	--attribute-value file://sns_topic_policy.json
S3バケットを作成する
$ aws s3 mb s3://az-test-2018
  • SNSへの通知設定をファイルにJSONで記述する。
$ cat << EOF > topic_config.json
{
    "TopicConfigurations": [
        {
            "TopicArn": "arn:aws:sns:ap-northeast-1:********:s3-event-test",
            "Events": [
                "s3:ObjectCreated:*"
            ]
        }
    ]
}
$ aws s3api put-bucket-notification-configuration --bucket "az-test-2018" --notification-configuration file://topic_config.json

SNSに通知されるタイミングを確認する

  • ファイルを作成する
$ perl -le 'print for 1..100000000' > test.txt
$ ls -lh test.txt
-rw-r--r--  1 azekyohe  1896053708   848M Feb 11 10:22 test.txt
$ ls -l test.txt
-rw-r--r--  1 azekyohe  ...  888888898★ Feb 11 01:22 test.txt
$ date; aws s3 cp test.txt s3://az-test-2018/; date
Sun Feb 11 02:28:16 UTC 2018 ★開始時間
upload: ./test.txt to s3://az-test-2018/test.txt
Sun Feb 11 02:30:47 UTC 2018 ★終了時間
  • メールを確認する
Subject:  AWS Notifications
Body:
{"Records":[{"eventVersion":"2.0","eventSource":"aws:s3","awsRegion":"ap-northeast-1",
"eventTime":"2018-02-11T02:30:48.571Z"★,"eventName":"ObjectCreated:CompleteMultipartUpload", ... 
"object":{"key":"test.txt","size":888888898★,...

オブジェクトの作成が完了したタイムスタンプで通知されている。


参考

こんにちは、

"list-objects等で取得可能なキーの一覧には反映されておらず、(キーが)取得できない
(間も、オブジェクトはPUT時の戻り値のキーを引数にget-object等で取得できる)という状況は発生する可能性がある。"
と、理解しました。
つまり、PUT(新規書き込み)完了後、
・キーが取得できないことはあってもオブジェクトが取得できないケースは発生しない(オブジェクトは*必ず*取得できる)
という認識です。もし認識が誤っていればご指摘ください。

はい、そのようなご認識で問題はございません。

「書き込み後の読み取り整合性」は、PUT (新規書き込み)が正常に完了した直後に、GETで該当のキーを結果整合性の影響を受けずに取得できる (=404 NotFoundにはならない) ことを保証しています。

https://forums.aws.amazon.com/thread.jspa?threadID=225802

S3 イベント通知はオブジェクト作成完了後に通知されることを確認する

S3イベント通知を使うと、S3バケットにファイルが作成されたり削除されたのをトリガーにイベントドリブンで、Lambda関数をキックしたり、SNSやSQSにメッセージを送ったりすることができるが、作成や削除が開始したタイミングではなく完了したタイミングでイベント通知が行われることを確認した。S3は結果整合性のため、完了していてもアクセス時にファイルが見つからないことは起こり得る。


事前準備

export LANG=C
export TZ=UTC
export AWS_DEFAULT_REGION=ap-northeast-1
SNSトピックを作成する
  • 既存のSNSトピック名を確認する
aws sns list-topics
  • SNSトピックを作成する
aws sns create-topic --name s3-event-test
aws sns subscribe --topic-arn arn:aws:sns:ap-northeast-1:*********:s3-event-test \
	--protocol email \
	--notification-endpoint ******@gmail.com
  • 指定したメールアドレスに確認メールが届くので本文のリンクをクリックする。
Subject: AWS Notification - Subscription Confirmation
Body:
You have chosen to subscribe to the topic: 
arn:aws:sns:ap-northeast-1:*********:s3-event-test

To confirm this subscription, click or visit the link below (If this was in error no action is necessary): 
Confirm subscription
S3バケットを作成する
aws s3 mb s3://az-test-2018
  • S3 にファイルが copy されたら SNS トピックに通知されるよう設定する。
    • 以下の内容でファイルを作成する。
{
    "TopicConfigurations": [
        {
            "TopicArn": "arn:aws:sns:ap-northeast-1:********:s3-event-test",
            "Events": [
                "s3:ObjectCreated:*"
            ]
        }
    ]
}
aws s3api put-bucket-notification-configuration --bucket "az-test-2018" --notification-configuration file://topic_config.json

試してみる

  • ファイルを作成する
$ perl -le 'print for 1..100000000' > test.txt
$ ls -lh test.txt
-rw-r--r--  1 azekyohe  1896053708   848M Feb 11 10:22 test.txt

S3に copy 時に通知される時刻を確認する

date; aws s3 cp test.txt s3://az-test-2018/; date

2018-01-10

vDSO gettimeofday

There is a Virtual Dynamic Shared Object (VDSO) implemented in the glibc runtime library. The VDSO maps some of the kernel code, which is necessary to read gettimeofday in the user-space. Standard Red Hat Enterprise Linux 5.5 allows the gettimeofday function to be performed entirely in user-space, removing the system call overhead.

2.6.?gettimeofday speedup

x86-64 functions

The table below lists the symbols exported by the vDSO. All of these symbols are also available without the "__vdso_" prefix, but you should ignore those and stick to the names below.

symbol version

─────────────────────────────────

__vdso_clock_gettime LINUX_2.6

__vdso_getcpu LINUX_2.6

__vdso_gettimeofday LINUX_2.6

__vdso_time LINUX_2.6

vdso(7) - Linux manual page

Xen pvclock; does not support vDSO


x86: vdso: pvclock gettime support

Improve performance of time system calls when using Linux pvclock,

by reading time info from fixmap visible copy of pvclock data.

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/arch/x86/vdso/vclock_gettime.c?id=51c19b4f5927f5a646e93d69f73c7e89ea14e737

2018-01-08

vmstat でタイムスタンプを表示する

vmstat: Support for timestamps with '-t' & fix for '-wd'

From now the vmstat can append a timestamp to each line in the

VMSTAT and DISKSTAT mode. You can achieve that with the '-t'

switch.

The '-w' switch now works in the DISKSTAT mode too.

vmstat: Support for timestamps with '-t' & fix for '-wd' (4fcd56bf) ? Commits ? procps-ng / procps ? GitLab

これ以降 vmstat は -t オプションタイムスタンプを表示できるようになっている。

$ vmstat -V
procps version 3.2.8
$ vmstat -t 5
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ ---timestamp---
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 59579072 735596 280408    0    0     0     0   10    2  0  0 100  0  0	2018-01-08 07:33:15 UTC
 0  0      0 59579072 735596 280408    0    0     0     0   30   34  0  0 100  0  0	2018-01-08 07:33:20 UTC
 0  0      0 59578932 735596 280408    0    0     0     0   29   34  0  0 100  0  0	2018-01-08 07:33:25 UTC

この機能追加が入る前のバージョンの vmstat でも以下のように awk などでタイムスタンプを追加してやるとよい。

$ vmstat 5|awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0}'
2018-01-08 07:35:47 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
2018-01-08 07:35:47  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
2018-01-08 07:35:47  1  0      0 59579072 735668 280420    0    0     0     0   10    2  0  0 100  0  0
2018-01-08 07:35:52  0  0      0 59579072 735668 280420    0    0     0     5   69   68  0  0 100  0  0
2018-01-08 07:35:57  0  0      0 59579072 735668 280420    0    0     0     0   32   38  0  0 100  0  0

なお、パイプで tee コマンドに渡すなどすると、awk がバッファリングしてすぐに表示されないので、"fflush()" でフラッシュしてやる。詳しくは下記 URL 参照。

$ vmstat 5|awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0;fflush()}'|tee -a vmstat_20180109.log

vmstat を含む procps プロジェクトのソースコードprocps-ng / procps ? GitLab で読むことができる。


参考

2017-12-29

nethogs でプロセス別の通信量を調べる

nethogs はネットワークの top コマンド的なもので通信量の多いプロセスをランキング表示して、秒間通信量も見ることができる。

f:id:yohei-a:20171229222742p:image


インストール

sudo yum -y install gcc-c++ libpcap-devel.x86_64 libpcap.x86_64 ncurses*
git clone https://github.com/raboof/nethogs
cd nethogs
make
sudo make install

使ってみる

sudo /usr/local/sbin/nethogs

参考

NetHogs is a small 'net top' tool. Instead of breaking the traffic down per protocol or per subnet, like most tools do, it groups bandwidth by process.

NetHogs does not rely on a special kernel module to be loaded. If there's suddenly a lot of network traffic, you can fire up NetHogs and immediately see which PID is causing this. This makes it easy to identify programs that have gone wild and are suddenly taking up your bandwidth.

Since NetHogs heavily relies on /proc, most features are only available on Linux. NetHogs can be built on Mac OS X and FreeBSD, but it will only show connections, not processes.

https://github.com/raboof/nethogs

追記(2018/2/17):

Since NetHogs heavily relies on /proc, most features are only available on Linux. NetHogs can be built on Mac OS X and FreeBSD, but it will only show connections, not processes.

https://github.com/raboof/nethogs

macOS Sierra 10.12.6 でも普通に使えた。

% git clone https://github.com/raboof/nethogs
% cd nethogs
% make
% sudo make install
% sudo /usr/local/sbin/nethogs