Redis4.x(二十):配置与管理(部署/备份/恢复/内存监控/客户端)

star2017 1年前 ⋅ 781 阅读

Redis 服务上线后,日常的运维和管理同样非常重要。Redis 服务自带了使用最广泛的管理工具redis-cli,在Linux环境下熟练使用该管理工具是非常必要的。

Redis 运维和管理还需要关注数据备份和恢复,数据迁移,对 Redis 实例内存指标的监控等。

官方文档:Redis Administration,官方同步译文:Redis 的管理

Redis 部署

官方建议在 Linux 操作系统部署 Redis,因为在 Linux 上进行了所有主要压力的测试,Linux 也是大多数生产环境部署的主要选择。

Redis 配置

  1. 指定配置文件,如果不指定,Redis 会使用内置的默认配置启动;在生产环境中大多会对一些配置项进行优化设置,默认配置几乎不会应用在生产环境中。

    # ./redis-server redis.conf
    
  2. 在Redis 配置文件中使用include指令来包含另一个配置文件,通常把公共配置项放在一个公共配置文件redis-common.conf用于共享,然后在redis.conf中引用。

    include /redis/conf/redis-common.conf
    
  3. Redis 服务启动时,在后面追加配置项名和值,来动态指定覆盖redis.conf文件中的配

    # ./redis.conf --loglevel verboss --port 6666
    
  4. 使用 CONFIG GET 命令获取服务器的配置参数

    # config get port
    127.0.0.1:6379> config get port
    1) "port"
    2) "6379"
    
  5. 使用 CONFIG REWRITE 命令把当前服务器配置持久化到配置文件中。注意,若 Redis 启动时没有指定配置文件,此命令会报错,因为不知道向哪里写入配置。

    127.0.0.1:6379> config set loglevel debug
    OK
    127.0.0.1:6379> config rewrite
    OK
    127.0.0.1:6379> exit
    [root@localhost 6379]# grep loglevel redis.conf
    loglevel debug
    
  6. 使用 CONFIG RESETSTAT 命令重置 INFO 命令报告的统计项

    127.0.0.1:6379> info stats
    # Stats
    total_connections_received:3
    total_commands_processed:12
    
    127.0.0.1:6379> config resetstat
    OK
    
    127.0.0.1:6379> info stats
    # Stats
    total_connections_received:0
    total_commands_processed:1
    

    INFO STATS 命令返回的几个计数器

    收到的总连接数:total_connections_received:0
    总处理命令数:total_commands_processed:1
    拒绝连接数:rejected_connections:0。该指标需要特别注意,如果值增加,意味着已达到 maxclients 的限制,新的连接会被拒绝
    过期键数量:expired_keys:0
    键空间命中数:keyspace_hits:0
    键空间未命中数:keyspace_misses:0
    最近一次fork的时间:latest_fork_usec:0
    

    计算键的命中率:HitRate=keyspace_hits/(keyspace_hits+keyspace_misses)

redis-cli 使用

使用 redis-cli 来操作 Redis 非常方便,也是首选。redis-cli 完整参考手册

  1. 连接 Redis 服务

    # ./redis-cli -h <hostname> -p <port> -a <password>
    

    -h :服务器主机名,默认是:127.0.0.1
    -p :服务器端口,默认是:6379
    -a :如果 Redis 服务开启了要求密码登录,则连接服务需要使密码
    如果客户端和Redis实例在同一服务器上,没有配置自定义端口,没有开启密码,则后面一串配置选项都可省略。

  2. redis-cli 还有其它配置项,可通过 --help 查看

    # ./redis-cli --help
    
  3. 常用的一些配置选项

    # 以原始格式输出:
    --raw hget all hashkeyA;若不使用 **--raw**选项,默认输出更具可读性。
    
    # 以 CSV格式输出:
    --csv lrange listkeyA 0 -1
    
    # 以指定时间间隔重复执行命令:
    -r 5 -i 1 info memory |grep used_memory;
    # 执行一组保存在文件中的命令,可以使用管道符将文件内容重定向到 redis-cli
    cat commands |bin/redis-cli
    
    # 执行大量的命令,开启管道功能来提高性能
    cat commands |bin/redis-cli --pipe
    
  4. info [section]的使用
    info 命令提供了 Redis 相关的所有信息,可以使用此命令查看 Redis 各项指标。若 info 后面不跟需要查看的单项名,则显示所有项目的信息,包括:

    • Server(服务器)
    • Clients(客户端)
    • Memory(内存)
    • Persistence(持久化)
    • Stats(统计)
    • Replication(复制)
    • CPU(cpu)
    • Commandstats(命令统计)
    • Cluster(集群)
    • Keyspace(键空间) 等项目信息。

备份和恢复

备份

  1. 触发持久化

    127.0.0.1:6379> bgsave
    Background saving started
    
  2. 将生成的持久化文件 RDB 快照文件拷贝出来做为备份文件

    cp dump.rdb /data/backup/redis/dump.$(date +%Y%m%d%H%M).rdb
    

恢复

  1. 检查是否启用了 AOF

    127.0.0.1:6379> config get appendonly
    1) "appendonly"
    2) "yes"
    
  2. 若没有启用 AOF,则执行第 3 步。否则,先禁用 AOF

    127.0.0.1:6379> config set appendonly no
    OK
    127.0.0.1:6379> config get appendonly
    1) "appendonly"
    2) "no"
    
  3. 关闭 Redis 服务,并将数据目录中的 AOF 和 RDB 文件删除或重命名

    127.0.0.1:6379> shutdown save
    not connected> 
    [root@localhost 6379]# rm *.rdb *.aof
    
  4. 将要恢复的 RDB 快照文件复制到 Redis 实例的数据目录中,并重命名为 dump.rdb(与配置中的 defilename 一致)

    cp /data/backup/redis/dump.20181212.rdb /usr/local/redis/bin/dump.rdb
    
  5. dump.rdb 设置正确的权限,并启动 Redis 服务器

    # chown redis:redis dump.rdb
    # ./redis-server redis.conf
    
  6. 若有必要,可开启 AOF 持久化

    127.0.0.1:6379> config set appendonly yes
    OK
    127.0.0.1:6379> config get appendonly
    1) "appendonly"
    2) "yes"
    127.0.0.1:6379> config rewrite
    OK
    

注意:若启用了 AOF ,Redis 首先会试图从 AOF 文件中恢复数据,所以在恢复数据之前禁用 AOF是必要的。如果找不到AOF文件,将从一个空的数据集开始恢复。一旦键的更改触发了 RDB 快照,原始的 RDB文件也将被重写。

监控内存的使用

INFO MEMORY

INFO MEMORY 命令来获取 Redis 内存相关的总体指标。

```
127.0.0.1:6379> info memory
# Memory
used_memory:4940608        //由 Redis 分配器分配的内存总量,包含了redis进程内部的开销和数据占用的内存,以字节(byte)为单位
used_memory_human:4.71M        //用户可读形式显示
used_memory_rss:8826880        //向操作系统申请的内存大小。与 top 、 ps等命令的输出一致。
used_memory_rss_human:8.42M        //用户可读形式显示
used_memory_peak:4992336        //Redis 消耗内存的峰值(以字节为单位)
used_memory_peak_human:4.76M        //用户可读形式显示
used_memory_peak_perc:98.96%        //使用内存达到峰值内存的百分比(used_memory/used_memory_peak) * 100%
used_memory_overhead:1948712        //Redis 内部缓冲区(客户端输出缓冲区,查询缓存区,AOF重写缓冲区,主从复制的 backlog)
used_memory_startup:786576        //Redis 实例启动时消耗的内存
used_memory_dataset:2991896        //数据占用的内存大小(used_memory - used_memory_overhead)
used_memory_dataset_perc:72.02%        //数据占用的内存大小的百分比(used_memory_dataset/(used_memory - used_memory_startup)) * 100%
total_system_memory:8371286016        //整个系统的内存
total_system_memory_human:7.80G        //用户可读形式显示
used_memory_lua:37888        //Lua 脚本存储占用的内存
used_memory_lua_human:37.00K        //用户可读形式显示
maxmemory:2147483648        //分配给 Redis 的最大内存
maxmemory_human:2.00G        //用户可读形式显示
maxmemory_policy:noeviction        //当达到 maxmemory 时的淘汰策略
mem_fragmentation_ratio:1.79        //碎片率 (used_memory_rss / used_memory)内存碎片率
mem_allocator:jemalloc-4.0.3        //内存分配器
active_defrag_running:0        //0 表示没有活动的 defrag(内存碎片整理) 任务正在运行;1 表示有活动的 defrag 正在运行。
lazyfree_pending_objects:0        //0 表示不存在延迟释放(惰性删除)的挂起对象
```

MEMORY USAGE

MEMORY USAGE命令估算一个键的内存使用情况。但没有计入键本身的长度和键过期信息所消耗的内存。

```
127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> memory usage foo
(integer) 52
```
该命令用于估算一个键消耗的内存。

MEMORY STATS

MEMORY STATS查看 Redis 实例中各部分的内存消耗情况

```
127.0.0.1:6379> memory stats
 1) "peak.allocated"        //峰值消耗的的内存(单位:字节)
 2) (integer) 4992336
 3) "total.allocated"        //目前总消耗的内存(单位:字节)
 4) (integer) 4935768
 5) "startup.allocated"        //Redis 实例启动消耗的内存(单位:字节)
 6) (integer) 786576
 7) "replication.backlog"        //主从复制backlog的内存消耗(单位:字节)
 8) (integer) 0
 9) "clients.slaves"        //从实例客户端输出缓冲区的内存消耗(单位:字节)
10) (integer) 0
11) "clients.normal"        //普通客户端缓冲区的内存耗(单位:字节)
12) (integer) 201352
13) "aof.buffer"    //AOF缓冲区的内存消耗(单位:字节)
14) (integer) 0
15) "db.0"        // db 序号
16) 1) "overhead.hashtable.main"        //维护 Redis 中数据的内存开销(缓冲区)
    2) (integer) 959664
    3) "overhead.hashtable.expires"        //在Redis 中存储键过期信息的内存开销
    4) (integer) 184
17) "overhead.total"
18) (integer) 1947776
19) "keys.count"        //键总数(包括所有db)
20) (integer) 17438
21) "keys.bytes-per-key"    //(total.allocated-startup.allocated)/keys.count
22) (integer) 237
23) "dataset.bytes"
24) (integer) 2987992
25) "dataset.percentage"
26) "72.013824462890625"
27) "peak.percentage"        //当前使用内存点峰值的百分比
28) "98.866905212402344"
29) "fragmentation"        //内存碎片率
30) "1.7883034944534302"
```

MEMORY DOCTOR

MEMORY DOCTOR诊断定们内存问题的命令

```
# ./redis-cli memory doctor

或者:
127.0.0.1:6379> memory doctor
Sam, I detected a few issues in this Redis instance memory implants:

High fragmentation: This instance has a memory fragmentation greater than 1.4 (this means that the Resident Set Size of the Redis process is much larger than the sum of the logical allocations Redis performed). 
This problem is usually due either to a large peak memory (check if there is a peak memory entry above in the report) or may result from a workload that causes the allocator to fragment memory a lot. 
If the problem is a large peak memory, then there is no issue. Otherwise, make sure you are using the Jemalloc allocator and not the default libc malloc. Note: The currently used allocator is "jemalloc-4.0.3".

I'm here to keep you safe, Sam. I want to help you.
```

MEMORY DOCTOR诊断流程和逻辑:

  1. 检查使用内存是否大于 5M,如果否,跳到第 5 步。
  2. 检查峰值内存是否大于当前使用内存的 1.5倍
  3. 检查碎片率是否大于 1.4
  4. 检查每个客户端缓冲区的平均内存使用超过 200KB
  5. 检查每个从实例缓存区的平均内存使用超过 100MB
  6. 结束。

每步的诊断结果为时会给出造成问题的可能原因和优化建议。

查看键内存情况

使用./redis-cli- -bigkeys选项查找最大的键和每种类型的键的平均大小

# ./redis-cli --bigkeys

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Biggest set    found so far 'user_exist:82:403' with 1 members
[00.00%] Biggest set    found so far 'push_user:13800138000' with 2 members
[00.00%] Biggest set    found so far 'push_user:13800138001' with 3 members
[00.12%] Biggest set    found so far 'user_exist:80:877' with 5 members
[00.25%] Biggest set    found so far 'push_pool:632' with 8 members
[00.43%] Biggest set    found so far 'push_pool:117' with 10 members
[00.66%] Biggest set    found so far 'push_pool:007' with 13 members
[00.77%] Biggest set    found so far 'sys_user_uv:2018-12-15:98' with 357 members
[05.19%] Biggest set    found so far 'sys_user_uv:2018-12-10:80' with 769 members
[23.74%] Biggest string found so far 'phone_code:13800138002' with 6 bytes

-------- summary -------

Sampled 17446 keys in the keyspace!
Total key length in bytes is 333170 (avg len 19.10)

Biggest string found 'phone_code:18313283114' has 6 bytes
Biggest    set found 'sys_user_uv:2018-12-10:80' has 769 members

10 strings with 60 bytes (00.06% of keys, avg size 6.00)
0 lists with 0 items (00.00% of keys, avg size 0.00)
17436 sets with 46450 members (99.94% of keys, avg size 2.66)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
0 streams with 0 entries (00.00% of keys, avg size 0.00)

管理客户端

Redis 采用的是 C/S(客户端-服务器)模型的 TCP服务器,对C/S模型服务器的客户端连接管理是非常重要的。

Redis 模拟多客户端连接,可使用自带的测试工具redis-benchmark模拟创建多个连接,具体使用可带--help查看。

  1. info clients查看客户端

    127.0.0.1:6379> info clients
    # Clients
    connected_clients:1        //客户端连接数
    client_longest_output_list:0    //当前客户端连接中最长的输出列表
    client_biggest_input_buf:0        //当前客户端连接中最大的输入缓冲区
    blocked_clients:0        //被阻塞命令挂起的客户端数量,如 BLPOP,BRPOP,BRPOPLPUSH等命令上的客户端数量。
    
  2. client list获取每个客户端的详细信息

    127.0.0.1:6379> client list
    id=5 addr=127.0.0.1:42440 fd=9 name= age=222 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
    
  3. client setname对客户端连接进行命名,在多连接时易于区分

    127.0.0.1:6379> client setname my-client
    OK
    127.0.0.1:6379> client list
    id=6 addr=127.0.0.1:42442 fd=9 name=my-client age=18 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
    
  4. client kill client-host:client-port关闭客户端连接

    127.0.0.1:6379> client kill 127.0.0.1:42442
    OK
    
  5. client pause将所有 Redis 客户端暂停指定的时间

    client pause 60000    //暂停60

    在暂停期间,Redis 服务器会停止处理来自普通客户端和发布/订阅客户端的所有命令。所有已连接的客户端在暂停期间被挂起,连接也将被挂起。但,主从复制会继续进行。
    暂停期间的数据集是保证不会发生改变的,因此,可以在暂停期间使用复制机制进行数据迁移。

client list 详解

127.0.0.1:6379> client setname my-client
OK
127.0.0.1:6379> client list
id=6 addr=127.0.0.1:42442 fd=9 name=my-client age=18 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
  1. id:一个唯一的64位客户端ID
  2. addr:客户端IP地址:端口
  3. fd:对应套接字的文件描述符
  4. age:连接总持续时间,单位:秒
  5. idle:连接空亲时间,单位:秒
  6. flags:客户端状态。N表示普通客户端, S 表示从实例等
  7. db:当前数据库ID
  8. sub:订阅的通道数
  9. psub:以模式匹配方式访问的通道数
  10. multi:MULTI/EXEC上下文中执行的命令数
  11. qbuf:查询缓冲区长度, 0 表示没有挂起的查询
  12. qbuf-free:查询缓冲区的空闲空间, 0 表示缓冲区已满
  13. obl:输出固定缓冲区使用的空间
  14. oll:输出列表长度,当缓冲区满时,响应在此列表中排队
  15. omem:输出缓冲区使用的空间
  16. events:文件描述符事件, r 代表套接字可读, w 代表套接字可写
  17. cmd:客户端发出的最后一个命令

其它参考

  1. Redis 配置文件 redis.conf 配置详解
更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: