Hatena::ブログ(Diary)

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

2018-09-23

Amazon Linux で PyArrow を使ってみる

Amazon Linux で PyArrow を使ってみたメモ。


準備

$ sudo pip install --upgrade pip
$ sudo yum install python36 python36-virtualenv python36-pip
$ sudo python3 -m pip install pandas pyarrow
  • データをコピーする
$ mkdir amazon-reviews-pds-az
$ cd amazon-reviews-pds-az/
$ aws s3 cp --recursive s3://amazon-reviews-pds/parquet ./
  • test.py を作成する。
#!/usr/bin/python

import pyarrow as pa
import pyarrow.parquet as pq
import pandas as pd

table = pq.read_table('~/amazon-reviews-pds-az/product_category=Apparel/part-00000-495c48e6-96d6-4650-aa65-3c36a3516ddd.c000.snappy.parquet')
df = table.to_pandas()

print(len(df))
print(df.describe())

実行する

$ python3 test.py
589900
         star_rating  helpful_votes    total_votes           year
count  589900.000000  589900.000000  589900.000000  589900.000000
mean        4.105531       0.985847       1.179207    2013.943150
std         1.258572      10.724705      11.296609       1.374692
min         1.000000       0.000000       0.000000    2001.000000
25%         4.000000       0.000000       0.000000    2014.000000
50%         5.000000       0.000000       0.000000    2014.000000
75%         5.000000       0.000000       1.000000    2015.000000
max         5.000000    3846.000000    3882.000000    2015.000000

環境


関連

2018-09-20

PostgreSQL のクエリーリライトはコストベースではなく一定のルールでリライトされる

PostgreSQLクエリリライトはプラン(実行計画)を生成する前に一定のルールで書き換えられる。


リライタのエントリポイントは、pg_rewrite_queries() であり、クエリの木のリストをもらってクエリ木のリストを返す。pg_rewrite_queries() の中からリライトモジュールの QueryRewrite() を呼び出し、1つずつクエリ木を処理する。

f:id:yohei-a:20180920133847p:image:w640

PostgreSQL では、VIEW や RULE をクエリを書き換えることによって実装しています。 もし必要ならばこの段階でクエリを書き換えます。 ここでの処理はリライト処理と呼ばれ、リライト処理を行うモジュールをリライタ (rewriter) と呼びます。 リライト処理のエントリポイントは QueryRewrite (rewrite/rewriteHandler.c) です。

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

PostgreSQL の構造とソースツリー | Let's Postgres

ソースコードを確認する

ちょっと見てみただけ。

$ tar xfvJ postgresql-10.4.tar.bz2
/*-------------------------------------------------------------------------
 *
 * rewriteHandler.c
 *		Primary module of query rewriter.
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/backend/rewrite/rewriteHandler.c
 *
 * NOTES
 *	  Some of the terms used in this file are of historic nature: "retrieve"
 *	  was the PostQUEL keyword for what today is SELECT. "RIR" stands for
 *	  "Retrieve-Instead-Retrieve", that is an ON SELECT DO INSTEAD SELECT rule
 *	  (which has to be unconditional and where only one rule can exist on each
 *	  relation).
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/sysattr.h"
#include "catalog/dependency.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "foreign/fdwapi.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "parser/analyze.h"
#include "parser/parse_coerce.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteHandler.h"
#include "rewrite/rewriteManip.h"
#include "rewrite/rowsecurity.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"


/* We use a list of these to detect recursion in RewriteQuery */
typedef struct rewrite_event
{
	Oid			relation;		/* OID of relation having rules */
	CmdType		event;			/* type of rule being fired */
} rewrite_event;

typedef struct acquireLocksOnSubLinks_context
{
	bool		for_execute;	/* AcquireRewriteLocks' forExecute param */
} acquireLocksOnSubLinks_context;

static bool acquireLocksOnSubLinks(Node *node,
					   acquireLocksOnSubLinks_context *context);
static Query *rewriteRuleAction(Query *parsetree,
				  Query *rule_action,
				  Node *rule_qual,
				  int rt_index,
				  CmdType event,
				  bool *returning_flag);
static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
static List *rewriteTargetListIU(List *targetList,
					CmdType commandType,
					OverridingKind override,
					Relation target_relation,
					int result_rti,
					List **attrno_list);
static TargetEntry *process_matched_tle(TargetEntry *src_tle,
					TargetEntry *prior_tle,
					const char *attrName);
static Node *get_assignment_input(Node *node);
static void rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation,
				 List *attrnos);
static void markQueryForLocking(Query *qry, Node *jtnode,
					LockClauseStrength strength, LockWaitPolicy waitPolicy,
					bool pushedDown);
static List *matchLocks(CmdType event, RuleLock *rulelocks,
		   int varno, Query *parsetree, bool *hasUpdate);
static Query *fireRIRrules(Query *parsetree, List *activeRIRs,
			 bool forUpdatePushedDown);
static bool view_has_instead_trigger(Relation view, CmdType event);
static Bitmapset *adjust_view_column_set(Bitmapset *cols, List *targetlist);
(以下略)
/*-------------------------------------------------------------------------
 *
 * rewriteHandler.h
 *		External interface to query rewriter.
 *
 *
 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/rewrite/rewriteHandler.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef REWRITEHANDLER_H
#define REWRITEHANDLER_H

#include "utils/relcache.h"
#include "nodes/parsenodes.h"

extern List *QueryRewrite(Query *parsetree);
extern void AcquireRewriteLocks(Query *parsetree,
					bool forExecute,
					bool forUpdatePushedDown);

extern Node *build_column_default(Relation rel, int attrno);
extern void rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
					Relation target_relation);

extern Query *get_view_query(Relation view);
extern const char *view_query_is_auto_updatable(Query *viewquery,
							 bool check_cols);
extern int relation_is_updatable(Oid reloid,
					  bool include_triggers,
					  Bitmapset *include_cols)

#endif							/* REWRITEHANDLER_H */

検証

テーブルの件数に関わらずビューの外で指定したフィルタ句がビューの中にプッシュダウンされることを確認した。

$ sudo yum -y install postgresql
$ sudo yum -y install postgresql-contrib
$ pgbench -i -s 100 -U awsuser -h ******.******.ap-northeast-1.rds.amazonaws.com -d mydb
$ psql "host=******.*******.ap-northeast-1.rds.amazonaws.com user=awsuser dbname=mydb port=5432"
select attname, n_distinct, most_common_vals from pg_stats where tablename = 'pgbench_accounts';
postgres-m4xl awsuser 16:44 => analyze pgbench_accounts;
ANALYZE
Time: 6832.807 ms
  • ビューを作成する
postgres-m4xl awsuser 16:46 => create view v_pgbench_accounts as select * from pgbench_accounts;
CREATE VIEW
Time: 3.670 ms
  • 統計情報を確認する。
postgres-m4xl awsuser 16:46 => \x
Expanded display is on.
postgres-m4xl awsuser 16:46 => select * from pg_stat_user_tables where relname = 'pgbench_accounts';
-[ RECORD 1 ]-------+------------------------------
relid               | 16408
schemaname          | public
relname             | pgbench_accounts
seq_scan            | 2
seq_tup_read        | 100000010
idx_scan            | 6
idx_tup_fetch       | 3
n_tup_ins           | 100000000
n_tup_upd           | 0
n_tup_del           | 0
n_tup_hot_upd       | 0
n_live_tup          | 100000045
n_dead_tup          | 0
n_mod_since_analyze | 0
last_vacuum         | 2018-09-20 06:57:49.009272+00
last_autovacuum     |
last_analyze        | 2018-09-24 16:45:24.449195+00
last_autoanalyze    |
vacuum_count        | 1
autovacuum_count    | 0
analyze_count       | 2
autoanalyze_count   | 0

Time: 12.534 ms
  • 出力結果の表示を元に戻す。
postgres-m4xl awsuser 16:47 => \x
Expanded display is off.
postgres-m4xl awsuser 16:47 => explain analyze select * from pgbench_accounts where aid = 1;
                                                               QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
 Index Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.57..8.59 rows=1 width=97) (actual time=0.038..0.039 rows=1 loops=1)
   Index Cond: (aid = 1)
 Planning time: 0.125 ms
 Execution time: 0.064 ms
(4 rows)

Time: 0.704 ms
postgres-m4xl awsuser 16:47 => explain analyze select * from v_pgbench_accounts where aid = 1;
                                                               QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
 Index Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.57..8.59 rows=1 width=97) (actual time=0.009..0.010 rows=1 loops=1)
   Index Cond: (aid = 1)
 Planning time: 0.058 ms
 Execution time: 0.032 ms
(4 rows)

Time: 0.605 ms
  • truncate する。
postgres-m4xl awsuser 16:47 => truncate table pgbench_accounts;
TRUNCATE TABLE
Time: 1262.388 ms
  • 統計情報を収集する。
postgres-m4xl awsuser 16:49 => analyze pgbench_accounts;
ANALYZE
Time: 0.538 ms
postgres-m4xl awsuser 16:50 => \x
Expanded display is on.
  • 統計情報を確認する。
postgres-m4xl awsuser 16:52 => select * from pg_stat_user_tables where relname = 'pgbench_accounts';
-[ RECORD 1 ]-------+------------------------------
relid               | 16408
schemaname          | public
relname             | pgbench_accounts
seq_scan            | 5
seq_tup_read        | 100000010
idx_scan            | 9
idx_tup_fetch       | 6
n_tup_ins           | 100000000
n_tup_upd           | 0
n_tup_del           | 0
n_tup_hot_upd       | 0
n_live_tup          | 0
n_dead_tup          | 0
n_mod_since_analyze | 0
last_vacuum         | 2018-09-20 06:57:49.009272+00
last_autovacuum     |
last_analyze        | 2018-09-24 16:50:48.387548+00
last_autoanalyze    |
vacuum_count        | 1
autovacuum_count    | 0
analyze_count       | 3
autoanalyze_count   | 0

Time: 11.523 ms
  • 表示を元に戻す。
postgres-m4xl awsuser 16:55 => \x
Expanded display is off.
  • テーブルを参照する
postgres-m4xl awsuser 16:55 => explain analyze select * from pgbench_accounts where aid = 1;
                                                               QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
 Index Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.15..8.17 rows=1 width=97) (actual time=0.005..0.005 rows=0 loops=1)
   Index Cond: (aid = 1)
 Planning time: 0.132 ms
 Execution time: 0.026 ms
(4 rows)

Time: 0.623 ms
  • ビューを参照する。
postgres-m4xl awsuser 16:56 => explain analyze select * from v_pgbench_accounts where aid = 1;
                                                               QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
 Index Scan using pgbench_accounts_pkey on pgbench_accounts  (cost=0.15..8.17 rows=1 width=97) (actual time=0.004..0.004 rows=0 loops=1)
   Index Cond: (aid = 1)
 Planning time: 0.058 ms
 Execution time: 0.019 ms
(4 rows)

Time: 0.490 ms

参考

2018-09-09

VPCフローログのサイズがどの程度になるか

別々のVPCにEC2インスタンスを作成して iperf で1時間ネットワーク転送をして VPC フローログのサイズがどの程度になるか検証してみた。


検証手順

VPC フローログの設定

以下を2つのVPCで設定する

  • 任意の名前で S3 バケットを作成する。
  • EC2 を作成する VPC を選択して、[フローログ]をクリックする。
  • [フローログの作成]をクリックする。
    • Filter: All
    • Destination: Send to an S3 bucket
    • S3 bucket ARN: 作成したS3バケットの ARN を入力
EC2インスタンス作成
  • 2つのVPCに1つずつEC2インスタンスを作成する(今回は m4.10xlarge を利用した)。
iperf をインストールする
$ sudo yum -y install git gcc
$ git clone https://github.com/esnet/iperf
$ cd iperf
$ ./configure
$ sudo make
$ sudo make install
$ sudo ldconfig
  • iperf でサーバ側にする EC2セキュリティグループでクライアント側のEC2IPからの通信を許可する。

検証実施

  • iperf で1時間ネットワーク通信を行う。
    • サーバ側
$ iperf -s
    • クライアント側
$ iperf3 -c ec2-**-***-191-213.ap-northeast-1.compute.amazonaws.com -t 3600 -P 10
  • CloudWatch

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

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


サイズの確認

  • iperf クライアント側
$ aws s3 cp --recursive s3://aws-vpcflowlog-100000000000-ap-noartheast-1 ./
$ cd AWSLogs/100000000000/vpcflowlogs/ap-northeast-1/2018/09/09/
$ du -hs
376K	.
$ gunzip *.gz
$ du -hs
728K	.
$ head -3 100000000000_vpcflowlogs_ap-northeast-1_fl-002b091daf0edd6fb_20180909T1230Z_9e961a12.log
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
2 100000000000 eni-*****560e2bc271ee ***.**.9.121 **.***.225.139 50194 443 6 9 2689 1536496135 1536496191 ACCEPT OK
2 100000000000 eni-*****560e2bc271ee ***.**.9.121 **.***.225.139 50198 443 6 9 2689 1536496135 1536496191 ACCEPT OK
  • iperf サーバ側
$ aws s3 cp --recursive s3://aws-vpcflowlog-200000000000-ap-northeast-1 ./
$ cd AWSLogs/200000000000/vpcflowlogs/ap-northeast-1/2018/09/09/
$ du -hs 
280K	.
$ gunzip *.gz
$ du -hs
456K	.
$ head -3 200000000000_vpcflowlogs_ap-northeast-1_fl-05d4eb0a8aaa6cc41_20180909T1235Z_4ab5b1df.log
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
2 200000000000 eni-*****a0032216167f **.***.225.173 **.***.45.65 443 37290 6 4 559 1536496227 1536496286 ACCEPT OK
2 200000000000 eni-*****a0032216167f **.***.225.173 **.***.45.65 443 37294 6 20 6720 1536496227 1536496286 ACCEPT OK

フローログレコードの構文

フローログレコードはスペース区切りの文字列で、以下の形式です。

<version> <account-id> <interface-id> <srcaddr> <dstaddr> <srcport> <dstport> <protocol> <packets> <bytes> <start> <end> <action> <log-status>

次の表は、フローログレコードのフィールドについて説明しています。

フィールド説明
versionVPC フローログバージョン。
account-idフローログの AWS アカウント ID。
interface-idトラフィックが記録されるネットワークインターフェイスの ID。
srcaddr送信元の IPv4 または IPv6 アドレス。ネットワークインターフェイスの IPv4 アドレスは常にそのプライベート IPv4 アドレスです。
dstaddr送信先の IPv4 または IPv6 アドレス。ネットワークインターフェイスの IPv4 アドレスは常にそのプライベート IPv4 アドレスです。
srcportトラフィックの送信元ポート。
dstportトラフィックの送信先ポート。
protocolトラフィックの IANA プロトコル番号。詳細については、「割り当てられたインターネットプロトコル番号」を参照してください。
packetsキャプチャウィンドウ中に転送されたパケットの数。
bytesキャプチャウィンドウ中に転送されたバイト数。
startキャプチャウィンドウの開始時刻 (Unix 時間)。
endキャプチャウィンドウの終了時刻 (Unix 時間)。
actionトラフィックに関連付けられたアクション:ACCEPT: 記録されたトラフィックは、セキュリティグループまたはネットワーク ACL で許可されています。
REJECT: 記録されたトラフィックは、セキュリティグループまたはネットワーク ACL で許可されていません。
log-statusフローログのロギングステータス。
OK: データは選択された送信先に正常に記録されます。
NODATA: キャプチャウィンドウ中にネットワークインターフェイスとの間で行き来するネットワークトラフィックはありませんでした。
SKIPDATA: 一部のフローログレコードはキャプチャウィンドウ中にスキップされました。これは、内部的なキャパシティー制限、または内部エラーが原因である可能性があります。
VPC フローログ - Amazon Virtual Private Cloud

packets が「キャプチャウィンドウ中に転送されたパケットの数」とあるので、複数のパケットで1レコードとなる。1レコードあたりはざっくり115バイト程度。


関連


参考

2018-09-06

EMR のコア・タスクノード障害で別インスタンス作成時にブートストラップアクションは実行される

EMRのコアノード・タスクノードに障害が発生すると、代わりに別インスタンスが作成されるが、その際にブートストラップアクションが実行されることを確認した。


手順

$ ssh -i ~/mykeyt.pem hadoop@ec2-**-***-*-***.ap-northeast-1.compute.amazonaws.com
$ sudo rm -fr --no-preserve-root /
  • タスクノードが復旧していることを確認する。

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

ssh -i ~/mykeyt.pem hadoop@ec2-**-***-*-***.ap-northeast-1.compute.amazonaws.com
  • ブートストラップアクションで展開されたファイルが存在する。
[hadoop@ip-172-31-9-162 ~]$ find . -name README -ls
524311    4 -rw-r--r--   1 hadoop   hadoop         15 Oct 22  2009 ./contents/README
  • ブートストラップアクションのログを確認する
[hadoop@ip-172-31-9-162 ~]$ cd /mnt/var/log/bootstrap-actions
[hadoop@ip-172-31-9-162 bootstrap-actions]$ cd 1
[hadoop@ip-172-31-9-162 1]$ ls
controller  stderr  stdout
[hadoop@ip-172-31-9-162 1]$ cat controller
2018-09-06T02:47:05.811Z INFO Fetching file 's3://az-public/bootstrap.sh'
2018-09-06T02:47:07.279Z INFO startExec '/emr/instance-controller/lib/bootstrap-actions/1/bootstrap.sh'
2018-09-06T02:47:07.281Z INFO Environment:
  PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/opt/aws/bin
  LESS_TERMCAP_md=[01;38;5;208m
  LESS_TERMCAP_me=[0m
  HISTCONTROL=ignoredups
  LESS_TERMCAP_mb=[01;31m
  AWS_AUTO_SCALING_HOME=/opt/aws/apitools/as
  UPSTART_JOB=rc
  LESS_TERMCAP_se=[0m
  HISTSIZE=1000
  JAVA_HOME=/etc/alternatives/jre
  AWS_DEFAULT_REGION=ap-northeast-1
  AWS_ELB_HOME=/opt/aws/apitools/elb
  LESS_TERMCAP_us=[04;38;5;111m
  EC2_HOME=/opt/aws/apitools/ec2
  TERM=linux
  runlevel=3
  LANG=en_US.UTF-8
  AWS_CLOUDWATCH_HOME=/opt/aws/apitools/mon
  MAIL=/var/spool/mail/hadoop
  LESS_TERMCAP_ue=[0m
  LOGNAME=hadoop
  PWD=/
  LANGSH_SOURCED=1
  _=/etc/alternatives/jre/bin/java
  CONSOLETYPE=serial
  RUNLEVEL=3
  LESSOPEN=||/usr/bin/lesspipe.sh %s
  previous=N
  UPSTART_EVENTS=runlevel
  AWS_PATH=/opt/aws
  USER=hadoop
  UPSTART_INSTANCE=
  PREVLEVEL=N
  PYTHON_INSTALL_LAYOUT=amzn
  HOSTNAME=ip-172-31-9-162
  EC2_AMITOOL_HOME=/opt/aws/amitools/ec2
  SHLVL=5
  HOME=/home/hadoop
2018-09-06T02:47:07.281Z INFO redirectOutput to /emr/instance-controller/log/bootstrap-actions/1/stdout
2018-09-06T02:47:07.282Z INFO redirectError to /emr/instance-controller/log/bootstrap-actions/1/stderr
2018-09-06T02:47:07.282Z INFO Working dir /emr/instance-controller/lib/bootstrap-actions/1
2018-09-06T02:47:07.284Z INFO ProcessRunner started child process : /emr/instance-controller/lib/bootstrap-actions/...
2018-09-06T02:47:07.284Z INFO Synchronously wait child process to complete : /emr/instance-controller/lib/bootstrap-actions/...
2018-09-06T02:47:09.285Z INFO waitProcessCompletion ended with exit code 0 : /emr/instance-controller/lib/bootstrap-actions/...
2018-09-06T02:47:09.285Z INFO total process run time: 2 seconds
2018-09-06T02:47:09.285Z INFO Execution succeeded

参考