Redis Memory 분석 툴은
대상 Redis 서버에 각 data type 별 key 개수는 어떻게 되는지, 메모리 사용량은 어떻게 되는지 등을 파악하기 위해 사용되며
분석 방법에 따라 크게 두가지로 나뉘고 대표적인 제품은 아래와 같습니다.

  • Live data Scan : RMA (Redis Memory Analyzer), Redis sampler
  • rdb file : RDB tools

이 중에서 온라인 중에 scan 을 통해 안전하게 분석이 가능하고 detail한 정보를 보여주는 RMA 라는 tool 에 대해 알아보겠습니다.

Install

  • Pre-Requisites
    python >= 3.5 and pip.
    redis-py

아래 두가지 방법 중 택 1

  • Install from pip
    pip install rma
  • source 설치
    pip install git+https://github.com/gamenet/redis-memory-analyzer@v0.2.0

command

>rma --help
usage: rma [-h] [-s HOST] [-p PORT] [-a PASSWORD] [-d DB] [-m MATCH] [-l LIMIT]
           [-b BEHAVIOUR] [-t TYPES]

RMA is used to scan Redis key space in and aggregate memory usage statistic by
key patterns.

optional arguments:
  -h, --help                 show this help message and exit
  -s, --server HOST          Redis Server hostname. Defaults to 127.0.0.1
  -p, --port PORT            Redis Server port. Defaults to 6379
  -a, --password PASSWORD    Password to use when connecting to the server
  -d, --db DB                Database number, defaults to 0
  -m, --match MATCH          Keys pattern to match
  -l, --limit LIMIT          Get max key matched by pattern
  -b, --behaviour BEHAVIOUR  Specify application working mode. Allowed values
                             are all, scanner, ram, global
  -t, --type TYPES           Data types to include. Possible values are string,
                             hash, list, set. Multiple types can be provided. If
                             not specified, all data types will be returned.
                             Allowed values arestring, hash, list, set, zset
  -f --format TYPE           Output type format: json or text (by default)
  -x --separator SEPARATOR   Specify namespace separator. Default is ':'
  • -b, –behaviour : Memory 분석의 수준을 정하는 옵션
    • all : scanner, ram , global 분석 정보를 모두 포함함 (default)
    • scanner : data type 과 key 개수 정도의 간단한 정보, namespace 도 간략화 되어 a:b:1, a:c:1 같은 데이터는 a:* 으로 통합하여 보여줌
    • ram : key size, value size , key+value memory size, TTL, object 정보 등 자세한 정보를 보여줌
    • global: 전체 key 개수, info memory 같은 정보, 특이한 건 key space overhead 를 알려줌
  • match : key 에 대해 Pattern 검색하는 옵션
  • limit : large dataset을 scan 하는 것은 오래 걸리기 때문에 scan 하는 key 개수 limit 을 설정하는 옵션
  • -t, –type : 특정 data type의 key 만 memory 분석 수행

RMA 예시

AL01542225:~ nhn$ rma -s localhost -p 6379 -a qhdks123 

Match *: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100602/100602 [00:00<00:00, 13348.56it/s]
Processing String patterns:  17%|████████████████████


Nodes

#### behaviour : global 수준의 정보 

| Stat                               | Value          |
|:-----------------------------------|:---------------|
| info used_memory                   | 35683616       |
| info used_memory_human             | 34.03M         |
| info used_memory_rss               | 44531712       |
| info used_memory_rss_human         | 42.47M         |
| info used_memory_peak              | 35755632       |
| info used_memory_peak_human        | 34.10M         |
| info used_memory_peak_perc         | 99.80%         |
| info used_memory_overhead          | 5931176        |
| info used_memory_startup           | 791416         |
| info used_memory_dataset           | 29752440       |
| info used_memory_dataset_perc      | 85.27%         |
| info allocator_allocated           | 35772056       |
| info allocator_active              | 38588416       |
| info allocator_resident            | 41447424       |
| info total_system_memory           | 6239903744     |
| info total_system_memory_human     | 5.81G          |
| info used_memory_lua               | 1249280        |
| info used_memory_lua_human         | 1.19M          |
| info used_memory_scripts           | 488            |
| info used_memory_scripts_human     | 488B           |
| info number_of_cached_scripts      | 1              |
| info maxmemory                     | 1000000000     |
| info maxmemory_human               | 953.67M        |
| info maxmemory_policy              | volatile-lru   |
| info allocator_frag_ratio          | 1.08           |
| info allocator_frag_bytes          | 2816360        |
| info allocator_rss_ratio           | 1.07           |
| info allocator_rss_bytes           | 2859008        |
| info rss_overhead_ratio            | 1.07           |
| info rss_overhead_bytes            | 3084288        |
| info mem_fragmentation_ratio       | 1.25           |
| info mem_fragmentation_bytes       | 8874792        |
| info mem_not_counted_for_evict     | 0              |
| info mem_replication_backlog       | 0              |
| info mem_clients_slaves            | 0              |
| info mem_clients_normal            | 66616          |
| info mem_aof_buffer                | 0              |
| info mem_allocator                 | jemalloc-5.1.0 |
| info active_defrag_running         | 0              |
| info lazyfree_pending_objects      | 0              |
| used proto-max-bulk-len            | 536870912      |
| used active-defrag-max-scan-fields | 1000           |
| used hash-max-ziplist-entries      | 512            |
| used hash-max-ziplist-value        | 64             |
| used list-max-ziplist-size         | -2             |
| used set-max-intset-entries        | 512            |
| used zset-max-ziplist-entries      | 128            |
| used zset-max-ziplist-value        | 64             |
| totalKeys                          | 100602         |
| redisKeySpaceOverhead              | 3149824        |


### behaviour scanner 수준의 정보

Keys by types

| name           |   count | type   | percent   |
|:---------------|--------:|:-------|:----------|
| kimdubi_str:*  |  100000 | string | 99.40%    |
| dori_hash:*    |     200 | hash   | 0.19%     |
| kimdubi_hash:* |     200 | hash   | 0.19%     |
| heedo_hash:*   |     200 | hash   | 0.19%     |
| kimdubi_list   |       1 | list   | 0.00%     |
| kimdubi_set    |       1 | set    | 0.00%     |



### behaviour ram 수준의 정보

Keys statistic

Stat by <string>

| Match         |   Count |   Useful |   Free |    Real |   Ratio | Encoding        |   Min |   Max |   Avg |   TTL Min |   TTL Max |   TTL Avg |
|:--------------|--------:|---------:|-------:|--------:|--------:|:----------------|------:|------:|------:|----------:|----------:|----------:|
| kimdubi_str:* |  100000 |  4088890 |      0 | 9584000 |    2.34 | embstr [100.0%] |    37 |    41 | 40.89 |        -1 |        -1 |     -1.00 |
| Total:        |  100000 |  4088890 |      0 | 9584000 |    0.00 |                 |     0 |     0 |  0.00 |        -1 |        -1 |    nan    |

Stat by <hash>

| Match          |   Count |   Avg field count |   Key mem |    Real |   Ratio |   Value mem |     Real |   Ratio |   System | Encoding         |   Total mem |   Total aligned |   TTL Min |   TTL Max |   TTL Avg. |
|:---------------|--------:|------------------:|----------:|--------:|--------:|------------:|---------:|--------:|---------:|:-----------------|------------:|----------------:|----------:|----------:|-----------:|
| dori_hash:*    |     200 |               500 |   1188890 | 1599920 |    1.35 |     4088890 |  4800000 |    1.17 |  2457600 | ziplist [100.0%] |     5277780 |         8857520 |        -1 |        -1 |      -1.00 |
| kimdubi_hash:* |     200 |               500 |   1188890 | 1599920 |    1.35 |     4088890 |  4800000 |    1.17 |  2457600 | ziplist [100.0%] |     5277780 |         8857520 |        -1 |        -1 |      -1.00 |
| heedo_hash:*   |     200 |               500 |   1188890 | 1599920 |    1.35 |     4088890 |  4800000 |    1.17 |  2457600 | ziplist [100.0%] |     5277780 |         8857520 |        -1 |        -1 |      -1.00 |
| Total:         |     600 |                 0 |   3566670 | 4799760 |    0.00 |    12266670 | 14400000 |    0.00 |  7372800 |                  |    15833340 |        26572560 |        -1 |        -1 |     nan    |

Stat by <list>

| Match        |   Count |   Avg Count |   Min Count |   Max Count |   Stdev Count |   Value mem |   Real |   Ratio |   System | Encoding           |   Total |   TTL Min |   TTL Max |   TTL Avg |
|:-------------|--------:|------------:|------------:|------------:|--------------:|------------:|-------:|--------:|---------:|:-------------------|--------:|----------:|----------:|----------:|
| kimdubi_list |       1 |      100000 |      100000 |      100000 |             0 |      488890 | 800000 |    1.64 |  2101248 | quicklist [100.0%] | 2901248 |        -1 |        -1 |     -1.00 |
| Total:       |       1 |           0 |           0 |           0 |             0 |      488890 | 800000 |    0.00 |  2101248 |                    | 2901248 |        -1 |        -1 |    nan    |

Stat by <set>

| Match       |   Count |   Avg Count |   Value mem |    Real |   Ratio |   System* | Encoding           |   Total |   TTL Min |   TTL Max |   TTL Avg. |
|:------------|--------:|------------:|------------:|--------:|--------:|----------:|:-------------------|--------:|----------:|----------:|-----------:|
| kimdubi_set |       1 |      100000 |      488890 | 3200000 |    6.55 |   3149824 | hashtable [100.0%] | 6349824 |        -1 |        -1 |      -1.00 |
| Total:      |       1 |           0 |      488890 | 3200000 |    0.00 |   3149824 |                    | 6349824 |        -1 |        -1 |     nan    |

살펴볼만 한 내용

  • redisKeySpaceOverhead
    • key를 생성하면서 할당되는 overhead의 총합으로, key의 개수가 많아질 수록 이 값도 커지게 됨, key 하나당 거의 40~50 byte의 overhead 가 있기 때문에 String -> Hash type을 사용해서 key를 줄이면 memory 절감 효과가 있을 수 있음 https://kimdubi.github.io/nosql/redis_str_to_hash/
  • data type 별 개수 / ratio
  • Hash type field 개수
    • hash-max-ziplist-entries 512 설정에 따라 한 key의 field 개수가 512개를 초과하면 hashtable로 encoding 되는데 이때, 메모리를 많이 쓰게됨 (ziplist 의 두배정도 쓴다고 함)
  • encoding
    • hash-max-ziplist-entries 512 같은 설정으로 entry 개수에 따라 ziplist / hashtable 로 나뉘는데 성능이 중요하면 hash table, 메모리를 아껴쓰는 게 중요하면 ziplist 로 관리하도록 함