- (追記1) s3cmd signがうまく動かない事があったので、sign用のスクリプトを書いた
前置き
CircleCIを使い始めたのだけど、現プロジェクトではRedisに住所データみたいな定数データをぶち込んで使っているので、テスト前にそのデータを読み込まないと完動しないなぁと困っていたのだが、CircleCIのドキュメントを読んでも特にオススメの方法は無いようなので作ることにした。
dump.rdbをそのまま差し替えようかと思ったのだけど、キャッシュ用の、テストに必要の無いデータももりもり入っていて肥大化しているので、今回は必要なデータだけをCircleCIにセットアップするようにした。
また、でかいバイナリデータをgithubにぶち込みたくないので、データのやりとりにはS3を使うようにした。
RedisデータのImport/Export
REDISのImport/Exportネタを探しても"RDBを差し替えようぜ"みたいな話しか無いので困ったなぁと思ってたらいいのがあった。
https://github.com/sripathikrishnan/redis-rdb-tools
http://redis.io/topics/mass-insert
REDISのバイナリプロトコル用のデータを吐き出して、ソレをredis-cliを使って流し込むというもの。コレで良さそう。
テキストプロトコルでの例は http://uokada.hatenablog.jp/entry/2012/12/01/021131 にあった。今回使うデータはバイナリデータを含んでいるのでこちらは使えない。
今回作ったスクリプトはこちら https://gist.github.com/shnjp/886eda28061c37047cd5
Export
まず、redisで念のためbgsaveする。
basetimestamp=`redis-cli lastsave`
redis-cli bgsave
while [ 1 ]
do
curtimestamp=`redis-cli lastsave`
if [ $basetimestamp != $curtimestamp ]
then
break
fi
sleep 1
done
必要なデータだけバイナリプロトコルに変換してgzipする。
rdb --command protocol --key KEY-PATTERN $REDIS_DUMP_RDB gzip --stdout > $REDIS_PROTOCOL_FILE
s3cmdでs3に送る
s3cmd -c S3-CONFIG-FILE put $REDIS_PROTOCOL_FILE $S3_BACKUP_BUCKET
Import
Importはcurlで取ってredis-cliに流せば良いのだけど、CircleCIから取得するためにS3のOne time tokenを使ってURLを生成する必要がある
https://github.com/hajoeichler/s3cmd-signed-url/blob/master/s3cmd-signed-url コレ参考にして必要なところだけ書いた https://gist.github.com/shnjp/886eda28061c37047cd5#file-get_s3_object-sh
TIMESTAMP
の値によってシグネチャエラーが出る問題の原因がわからなかったので、botoを使って書きなおした。
#!/usr/bin/env python
"""
s3sign.py [ACCESS KEY] [SECRET KEY] [BUCKET] [KEY]
"""
import sys
from boto.s3.connection import S3Connection
access_key, secret_key, bucket_name, key_name = sys.argv[1:5]
connection = S3Connection(aws_access_key_id=access_key, aws_secret_access_key=secret_key)
key = connection.get_bucket(bucket_name).get_key(key_name)
print key.generate_url(600)
こんなかんじのスクリプトを作って、circle.ymlに
database:
post:
- curl `./s3sign.py S3-ACCESS-KEY S3-SECRET-KEY S3-BUCKET-NAME redis-cache-data.raw.gz` | gunzip | redis-cli --pipe
こんなのを追加した。
おハマりどころ
シェルスクリプトはあまり書いたこと無いので色々詰まった。
echoの仕様
echoって仕様違うのね。echo -e
が無くて困った。
redis-rdb-toolsがバイナリデータを扱えない
redis-rdb-toolsがutf-8しか見てくれなくてバイナリプロトコルに変換するときにコケた。
パッチ書いてなんとかした。