simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

AWS:お金のかからないElastiCache活用術2

simplestar-tech.hatenablog.com
のつづき

適当な値を redis に詰める

ローカルに立てた Redis 5.0.5 サーバー、適当な値を詰めてみます。
たとえば

key : value
9999 : 100
ffff : 100
abcd : efgh

これを前回導入した rdb-tools で json に出力してみましょう。

Redis のバックアップファイルの取得

前回 rdb-tools をインストールしているので
rdb コマンドはどこでも打てる様子
まずは redis コンテナ内に入って rdb ファイルを作りましょう
コンテナ内に入って rdb ファイルを保存するには

winpty docker exec -it redis bash
root@1faa380aff8b:/data# redis-cli dbsize
(integer) 4
root@1faa380aff8b:/data# redis-cli bgsave
Background saving started
root@1faa380aff8b:/data# ls -la
total 12
drwxr-xr-x 2 redis redis 4096 Sep 22 05:41 .
drwxr-xr-x 1 root  root  4096 Sep 22 03:23 ..
-rw-r--r-- 1 redis redis  161 Sep 22 05:41 dump.rdb
root@1faa380aff8b:/data# mv dump.rdb /redis/dump_20190922.rdb

前回 redis フォルダを volume マウントしてましたので、ホストマシンにて .rdb ファイルを確認することができると思います。

Redis のバックアップファイル json

解析コマンドの一つに json 形式で表示するものがありましたので、実行してみます。

rdb --command json -k ".*" dump_20190922.rdb
[{
"abcd":"efgh",
"ffff":"100",
"9999":"100",
"uuid":"4cf5cc323edd423bbf0078ce187acd21"}]

出ますね。
これをリダイレクト出力して .json ファイルを手に入れます。

[
    {
        "abcd": "efgh",
        "ffff": "100",
        "9999": "100",
        "uuid": "4cf5cc323edd423bbf0078ce187acd21"
    }
]

メモリレポートを確認

rdb -c memory dump_20190922.rdb -f memory.csv

memory.csv の内容は次の通り

database,type,key,size_in_bytes,encoding,num_elements,len_largest_element,expiry
0,string,abcd,56,string,4,4,
0,string,ffff,48,string,8,8,
0,string,9999,40,string,8,8,
0,string,uuid,88,string,32,32,

ほか、redis 本体に入って

redis-cli info

と打つと、次のように Memory について情報を確認することができます。

# Memory
used_memory:854496
used_memory_human:834.47K
used_memory_rss:5718016
used_memory_rss_human:5.45M
used_memory_peak:854496
used_memory_peak_human:834.47K
used_memory_peak_perc:100.03%
used_memory_overhead:842262
used_memory_startup:792264
used_memory_dataset:12234
used_memory_dataset_perc:19.66%
allocator_allocated:1058256
allocator_active:1306624
allocator_resident:8474624
total_system_memory:2096144384
total_system_memory_human:1.95G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.23
allocator_frag_bytes:248368
allocator_rss_ratio:6.49
allocator_rss_bytes:7168000
rss_overhead_ratio:0.67
rss_overhead_bytes:-2756608
mem_fragmentation_ratio:7.22
mem_fragmentation_bytes:4926400
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0

CubeWalk 世界の 1/4096 を格納すると何メモリになるか

ローカルで調べます。
世界ブロック数は 1 chunk 16 x 16 x 16 block
256 chunk x 256 chunk x 256 chunk です。
これを 16 chunk x 16 chunk x 16 chunk に切り取って 4096 分の1の世界とすると

16 x 16 x 16 blocks x 16 x 16 x 16 chunk となり、全16,777,216 block であり
横方向 縦方向、奥行き方向それぞれに 256 段階の解像度が求められます

文字で 16 進数を使うと
FF で 256 段階を表す事ができるため
000000 から FFFFFF までのキーを使って直感的に 4096 分の1の世界のブロックを特定できます。

キーに付随する値は 4byte の表現が求められ、数値として入力できない以上 00000000 から FFFFFFFF までの値を入れることにします。

一度、8 件ほどデータを詰めてみて、ダンプ結果を解析してみましょう。

一旦 Redis をクリアする方法はこちら

redis-cli FLUSHDB

CubeWalk データを一括で詰める

試験的に次の 8 ブロック分のデータを詰めることを行ってみた

[
    {
        "FFFFFF": "FFFFFFFF",
        "FFFFFD": "FFFFFFFD",
        "FFFFFC": "FFFFFFFC",
        "FFFFFE": "FFFFFFFE",
        "000002": "00000002",
        "000000": "00000000",
        "000001": "00000001",
        "000003": "00000003"
    }
]

rdb-tools で一括インポートするための protocol は次のコマンドで得ることができる

rdb -c protocol dump_20190922.rdb > data.txt

得られた data.txt の内容は次の通り

*2
$6
SELECT
$1
0
*3
$3
SET
$6
FFFFFF
$8
FFFFFFFF
*3
$3
SET
$6
FFFFFD
$8
FFFFFFFD
*3
$3
SET
$6
FFFFFC
$8
FFFFFFFC
*3
$3
SET
$6
FFFFFE
$8
FFFFFFFE
*3
$3
SET
$6
000002
$8
00000002
*3
$3
SET
$6
000000
$8
00000000
*3
$3
SET
$6
000001
$8
00000001
*3
$3
SET
$6
000003
$8
00000003

読んでいけば db 0 を選んだ後、SET key value を延々と行っているルールが見て取れる
ローカル環境を本番さながらに構築するにはこの protocol を作って次のコマンドで流し込む

cat data.txt | redis-cli --pipe

のが Redis の最善の方法と公式ドキュメントに示されている。

Redis Mass Insertion
redis.io

あとはアプリケーションの話なので、独自に protocol を出力するプログラムを作ればいい