2024/12/2 Redis のはなし2、redis-cli だけでデータマイグレーション
さてローカルでユーザを作成したから dump, restore してみるぞ〜というところから
しかし dump, restore を試す前に Sidekiq が保存する予約ジョブを模したデータが必要 引越し元にデータを作成しておく
Sidekiq が保存する予約ジョブのデータ型は ZSET でスコア順に並ぶデータセットになります スコアを予約日時にタイムスタンプとしているので列挙したときには若い日時の予約ジョブが先頭にきます
今回はSidekiqが知る詳細ではなく、ただスコアと値を入れて保存だけするに留めます
code:zadd
127.0.0.1:6379> ZADD app:schedule 1 "foo"
(integer) 1
127.0.0.1:6379> ZADD app:schedule 2 "bar"
(integer) 1
127.0.0.1:6379> ZADD app:schedule 3 "2000"
(integer) 1
127.0.0.1:6379> ZRANGE app:schedule 0 -1 WITHSCORES
1) "foo"
2) "1"
3) "bar"
4) "2"
5) "2000"
6) "3"
127.0.0.1:6379>
これで準備OKです
code:dump-restore
redis-cli -u redis://127.0.0.1:6379 --raw dump app:schedule > backup.dump
cat backup.dump | redis-cli --user alice -u redis://127.0.0.1:6380/1 -x restore schedule 0
(error) ERR DUMP payload version or checksum are wrong
うまくいきません。なんじゃろなと調べると…
末尾に余計な \n が入るかららしいです。そのため除外しなくてはいけないようです
この辺からストレートな対応じゃなさそうだなという感触をもちはじめます
例にならって末尾を削ります
macOS の場合、GNU head と引数が微妙に違います。GNU準拠のものは coreutils から提供されるので適宜入れておいてください そしてコマンドは ghead となるのでそれも注意してください
code:dump-restore-take2
redis-cli -u redis://127.0.0.1:6379 --raw dump app:schedule | head -c -1 > backup.dump
cat backup.dump | redis-cli --user alice -u redis://127.0.0.1:6380/1 -x restore schedule 0
OK
これでできましたので確認します
code:check
redis-cli -u redis://127.0.0.1:6380
127.0.0.1:6380> SELECT 1
OK
127.0.0.1:63801> ZRANGE schedule 0 -1 WITHSCORES 1) "foo"
2) "1"
3) "bar"
4) "2"
5) "2000"
6) "3"
うまく行ってそう
ところが!!!!
--user オプションを渡して redis-cli を実行した場合には default ユーザで Redis に接続していることに気付きます
code:確認
redis-cli --user alice -u redis://127.0.0.1:6380
127.0.0.1:6380> ACL WHOAMI
"default"
127.0.0.1:6380>
なんてこった…
というわけで Redis URL Schema にユーザを渡してトライすると…
code:migration
cat backup.dump | redis-cli -u redis://alice:@127.0.0.1:6380/1 -x restore schedule 0
(error) NOPERM this user has no permissions to run the 'restore' command
残念のユーザ alice の権限では 'restore' の実行が許可されていません!!!
昨日記載した ACL LIST の時点で気付くべきでしたね
restore は ACL CAT における @dangerous といった権限カテゴリに含まれます
code:acl cat
127.0.0.1:6380> ACL CAT dangerous
1) "migrate"
...snip...
62) "slaveof"
63) "restore"
...snip...
75) "restore-asking"
@dangerous カテゴリにある権限は Admin 以外の通常ユーザには渡したくない
SREと相談しましたがアプリケーションから接続するユーザ向けに危険な操作権限を渡すのは難しいとのことで、 redis-cli を使ったデータマイグレーションをやめたのでした
できたとしても微妙かもという直感もあります
結果的に Sidekiq と Rake タスクでマイグレーションして無事移行したんですが、また別の機会で触れます