Redisはキャッシュサーバーでありながら、データの冗長化や永続化さらにはソートされたデータの順位の計算も可能なため、(本当は良くないと分かりながらも)つい保存しなければならないデータまでRedisに格納する運用をしていた。
しかし、コスト削減のため1つのサーバーにデータを統合する想定があまりないのか、かなり面倒くさい…しなかなか情報もないという問題があった。
https://www.slideshare.net/ssuserf3788f/redis-58419914 こちらの資料が非常に参考になったが、AWS ElastiCacheのアップデートによって変わった点や他に調べないとわからない点があったため、より具体的に手順を記述する。
手順1:Redisのスナップショットを取得する。
// aws_region,cache-cluster-idは自分の環境に合わせてください。 // S3 bucketを用意してない場合は予め作成してください aws_region=ap-northeast-1 cache_cluster_id=redis-a snapshot_name=redis-snapshot-a s3_bucket_name=bucket-a aws elasticache create-snapshot \ --snapshot-name $snapshot_name \ --cache-cluster-id $cache_cluster_id \ --region $aws_region
手順2:保存するS3バケットにスナップショット作成用権限を一時的に付与する
aws s3api put-bucket-acl --bucket $s3_bucket_name --grant-full-control id=540804c33a284a299d2547575ce1010f2312ef3da9b3a053c8bc45bf233e4353
手順3:作成したRedisのスナップショットをS3にコピーする。
aws elasticache copy-snapshot \ --source-snapshot-name $snapshot_name \ --target-snapshot-name $snapshot_name \ --target-bucket $s3_bucket_name \ --region $aws_region
手順4:S3からスナップショットファイルをダウンロードする。
手順5:ダウンロードしたスナップショットをマージする。
以下のコードを実行して、生成されたファイルをS3にアップロードする。RedisのDumpファイルの中身の構造についてはこちらが参考になった。
またチェックサムの計算の方法については調べても中々出てこずに手間取ったが、こちらの実装コメントが参考になった。
※こちらのスクリプトは1つのRedisスナップショットに複数DBが含まれているケースは想定していない。順に、DB0に1つ目のスナップショットのDB、DB1に2つ目のスナップショット…という具合に結合している。
merge_redis_dump.rb
require 'crc' file_names = [ 'redis-snapshot-a.rdb', 'redis-snapshot-b.rdb', 'redis-snapshot-c.rdb', ] merged_file = file_names.each_with_index.inject("") do |merged_file_str, (file_name, index)| file_str = File.binread(file_name) if index != 0 file_str.slice!(0..10) file_str.insert(0, [254, index].pack("C*")) end if index == file_names.size - 1 file_str.slice!(file_str.size - 8..file_str.size - 1) else file_str.slice!(file_str.size - 9..file_str.size - 1) end merged_file_str << file_str end crc = CRC.new(64, 0xad93d23594c935a9, initial_crc = 0, refin = true, refout = true, xor_output = 0) checksum = crc.digest(merged_file).unpack("C*").reverse.pack("C*") merged_file << checksum IO.binwrite("redis-snapshot-merged.rdb", merged_file)
作成したファイルのチェック
redis-check-dump redis-snapshot-merged.rdb
- 手順6:S3にアップロードする。
- 手順7:アップロードしたファイルに、スナップショット利用権限を付与する。
aws s3api put-object-acl --bucket $s3_bucket_name --grant-full-control id=540804c33a284a299d2547575ce1010f2312ef3da9b3a053c8bc45bf233e4353 --key redis-snapshot-merged.rdb
手順8:新しいRedisサーバーをスナップショットから立ち上げる
一例:
aws elasticache create-cache-cluster \ --cache-cluster-id my-cluster \ --cache-node-type cache.r5.large \ --engine redis \ --engine-version 3.2.4 \ --num-cache-nodes 1 \ --cache-parameter-group default.redis3.2 \ --snapshot-arns arn:aws:s3:$(echo $s3_bucket_name)/redis-snapshot-merged.rdb