Redshift起動
バージニアRegionに作成する。
- Node Type: dw.hs1.xlarge
- Cluster Type: Single Node
2TBの容量でOnDemandなので $0.85/hour。
だいたい10分くらいでセットアップ終わってたかな??
Clientのセットアップ
Amazon Linuxで。
redshiftのPostgresqlの近しいVersionは8らしいので、8のクライアントを入れる(それで良いのかはよく知らない)。
sudo yum install postgresql8-devel
redshift側のSecurityGroupで このクライアントマシンのIPからの接続を許可する。
その後こんな感じで接続できる
psql -h *******.us-east-1.redshift.amazonaws.com -p 5439 -d mydb -U root
ユーザ root のパスワード: ******************
psql (8.4.13, サーバ 8.0.2)
注意: psql バージョン 8.4, サーババージョン 8.0.
psql の機能の中で、動作しないものがあるかもしれません。
SSL 接続 (暗号化方式: DHE-RSA-AES256-SHA, ビット長: 256)
"help" でヘルプを表示します.
mydb=#
簡単なデータ入れてみる
試しにこういうデータを考える
- id: int
- type: varchar(32)
- point: int
- event_datetime: datetime # UTC
SQLの文法はこの辺を参照。見慣れないキーワードも出てきていますね。
Create Table sample1 (
id BIGINT IDENTITY(1,1) PRIMARY KEY,
type VARCHAR(32) ENCODE TEXT255,
point INT,
event_datetime TIMESTAMP
)
DISTSTYLE EVEN
SORTKEY (event_datetime);
- DISTSTYLE: は分散のポリシー。KEY か EVEN である。EVEN はRoundRobin的に分散させる。KEYなら分散に使う列を指定する。まあ、今回は Single Node だからあまり関係ない。
- SORTKEY: はRangeで検索するときによく使う列を指定しておくと良いっぽい。
この辺のテーブル設計について詳しくはこの辺を参照
-
IDENTITY: AUTO_INCREMENT みたいなものかな。
-
ENCODE は列圧縮オプション。同様の文字列が出てくるような場合は TEXT255 とかを使うっぽい。圧縮オプションの詳細 はこちら。
Insert とか Select とか
普通に Insert でデータを入れてみる。
mydb=# insert into sample1(type, point, event_datetime) values('hoge', 10, '2013/5/10 10:10:00');
INSERT 0 1
Select とかしてみる。
mydb=# select * from sample1 where event_datetime > '2013-5-2';
id | type | point | event_datetime
----+------+-------+---------------------
1 | hoge | 10 | 2013-05-10 10:10:00
(1 行)
mydb=# select * from sample1 where event_datetime < '2013-5-2';
id | type | point | event_datetime
----+------+-------+----------------
(0 行)
S3からデータのImport
S3にデータをUploadするために s3cmd を Installしておく
sudo yum -y --enablerepo epel install s3cmd
s3cmd --configure
# ACCESS_KEY とか SECRET とかを入力
こんな感じで使うっぽい。
s3cmd ls s3://BUCKET/
s3cmd put FILE FILE... s3://BUCKET/redshift/
データを作成するスクリプトをかく。
# coding: utf-8
# make_data.rb
num = ARGV.shift.to_i
DELI = "\001"
TYPES = ["cat", "dog", "cow", "horse"]
num.times do |i|
type = TYPES[i % TYPES.size]
point = Random.rand(10) + 1
dt = Time.now.utc
puts [type, point, dt].join(DELI)
end
データを作成して、S3にUploadする。
ruby make_data.rb 20000 > 20000.data
gzip 20000.data
s3cmd put 20000.data.gz s3://BUCKET/redshift/sample1/
データをCOPYで取り込んでみる。
COPY sample1
FROM 's3://BUCKET/redshift/sample1/20000.data.gz'
GZIP
DELIMITER '\001'
CREDENTIALS 'aws_access_key_id=***********;aws_secret_access_key=************'
;
ERROR: S3ServiceException:The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.,StatusCode 301,ErrorCode PermanentRedirect,RequestId EC14D5D1453E517A,ExtendedRequestId QjHhcX8gv0D
DETAIL:
...
エラーが出た。
そういえば、そのBucketは東京Regionのものだったので、US Standardに別にBucketを作り直す
(COPYコマンドでS3からデータを取り込むときは同一リージョンでないといけない)
Important: The Amazon S3 bucket that holds the data files must be created in the same region as your cluster.
再度データをUploadし直して、COPYを再実行すると今度は成功。いくつか select を試す。
mydb=# select count(*) from sample1;
count
-------
20001
(1 行)
mydb=# select * from sample1 limit 4;
id | type | point | event_datetime
----+--------+-------+---------------------
1 | hoge | 10 | 2013-05-10 10:10:00
4 | dog | 9 | 2013-05-10 06:20:32
8 | horse | 4 | 2013-05-10 06:20:32
12 | dog | 4 | 2013-05-10 06:20:32
(4 行)
mydb=# select type, count(*), sum(point) from sample1 group by type;
type | count | sum
--------+-------+-------
hoge | 1 | 10
hourse | 5000 | 27270
cat | 5000 | 27386
cow | 5000 | 27529
dog | 5000 | 27501
(5 行)
3~4秒もしないうちに結果が戻ってくる。
全く同じQuery(Limitを変化させた程度では同じ、ような扱い)を投げると直後に戻ってくる。キャッシュされているのかな。