• 欢迎访问 winrains 的个人网站!
  • 本网站主要从互联网整理和收集了与Java、网络安全、Linux等技术相关的文章,供学习和研究使用。如有侵权,请留言告知,谢谢!

Redis使用教程(6):管理

Redis winrains 来源:田守芝 11个月前 (10-20) 38次浏览

7 管理

虽然小白的博客已经运行有一段时间了,可是小白对如何管理Redis依然完全没有概念。比如他知道Redis将所有的数据都存储在内存中,那么如果服务器重启了,Redis中的数据怎么恢复呢?又如怎样给Redis设置密码以防其他未经授权的客户端连接呢?带着这些疑惑,小白再一次找到了宋老师。

本章将会讲解Redis的管理知识,包括持久化、复制和安全内容,同时还会介绍一些第三方的Redis管理工具。

7.3 安全

Redis的作者Salvatore Sanfilippo曾经发表过Redis宣言 ,其中提到Redis以简洁为美。同样在安全层面Redis也没有做太多的工作。

7.3.1 可信的环境

Redis的安全设计是在“Redis运行在可信环境”这个前提下做出的,在生产环境运行时不能允许外界直接连接到Redis服务器上,而应该通过应用程序进行中转,运行在可信的环境中是保证Redis安全的最重要方法。
Redis的默认配置会接受来自任何地址发送来的请求,即在任何一个拥有公网IP的服务器上启动Redis服务器,都可以被外界直接访问到。要更改这一设置,在配置文件中修改bind参数,如只允许本机应用连接Redis,可以将bind参数改成:

bind 127.0.0.1

2.8版本之前,bind参数只能绑定一个地址 ,如果想更自由地设置访问规则需要通过防火墙来完成。

7.3.2 数据库密码

除此之外,还可以通过配置文件中的requirepass参数为Redis设置一个密码。例如:

requirepass TAFK(@~!ji^XALQ(sYh5xIwTn5D s7JF

客户端每次连接到Redis时都需要发送密码,否则Redis会拒绝执行客户端发来的命令。例如:

redis> GET foo
(error) ERR operation not permitted

发送密码需要使用AUTH命令,就像这样:

redis> AUTH TAFK(@~!ji^XALQ(sYh5xIwTn5D s7JF
OK

之后就可以执行任何命令了:

redis> GET foo
" 1"

由于Redis的性能极高,并且输入错误密码后Redis并不会进行主动延迟(考虑到Redis的单线程模型),所以攻击者可以通过穷举法破解Redis的密码(1秒内能够尝试十几万个密码),因此在设置时一定要选择复杂的密码。
提示 配置Redis复制的时候如果主数据库设置了密码,需要在从数据库的配置文件中通过masterauth参数设置主数据库的密码,以使从数据库连接主数据库时自动使用AUTH命令认证。

7.3.3 命名命令

Redis支持在配置文件中将命令重命名,比如将FLUSHALL命令重命名成一个比较复杂的名字,以保证只有自己的应用可以使用该命令。就像这样:

rename-command FLUSHALL oyfekmjvmwxq5a9c8usofuo369x0it2k

如果希望直接禁用某个命令可以将命令重命名成空字符串:

rename-command FLUSHALL ""

注意 无论设置密码还是重命名命令,都需要保证配置文件的安全性,否则就没有任何意义了。

7.4 通信协议

Redis通信协议是Redis客户端与Redis之间交流的语言,通信协议规定了命令和返回值的格式。了解Redis通信协议后不仅可以理解AOF文件的格式和主从复制时主数据库向从数据库发送的内容等,还可以开发自己的Redis客户端(不过由于几乎所有常用的语言都有相应的Redis客户端,需要使用通信协议直接和Redis打交道的机会确实不多)。
Redis支持两种通信协议,一种是二进制安全的统一请求协议(unified request protocol),一种是比较直观的便于在telnet程序中输入的简单协议。这两种协议只是命令的格式有区别,命令返回值的格式是一样的。

7.4.1 简单协议

简单协议适合在telnet程序中和Redis通信。简单协议的命令格式就是将命令和各个参数使用空格分隔开,如“EXISTS foo”、“SET foo bar”等。由于Redis解析简单协议时只是简单地以空格分隔参数,所以无法输入二进制字符。我们可以通过telnet程序测试:

telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SET foo bar
+OK
GET foo
$3
bar
LPUSH plist 1 2 3
:3
LRANGE plist 0 -1
*3
$1
3
$1
2
$1
1
ERRORCOMMAND
-ERR unknown command 'ERRORCOMMAND'

提示 Redis 2.4之前的版本对于某些命令可以使用类似简单协议的特殊方式输入二进制安全的参数,例如:

C:SET foo 3
C:bar
S:+OK

其中C:表示客户端发出的内容,S:表示服务端发出的内容。第一行的最后一个参数表示字符串的长度,第二行是字符串的实际内容,因为指定了长度,所以第二行的字符串可以包含二进制字符。但是这个协议已经废弃,被新的统一请求协议取代。“统一”二字指所有的命令使用同样的请求方式而不再为某些命令使用特殊方式,如果需要在参数中包含二进制字符应该使用7.4.2节介绍的统一请求协议。
我们在telnet程序中输入的5条命令恰好展示了Redis的5种返回值类型的格式,2.3.2节介绍了这5种返回值类型在redis-cli中的展现形式,这些展现形式是经过了redis-cli封装的,而上面的内容才是Redis真正返回的格式。下面分别介绍。
1.错误回复
错误回复(error reply)以-开头,并在后面跟上错误信息,最后以\r\n结尾:

-ERR unknown command 'ERRORCOMMAND'\r\n

2.状态回复
状态回复(status reply)以+开头,并在后面跟上状态信息,最后以\r\n结尾:

+OK\r\n

3.整数回复
整数回复(integer reply)以:开头,并在后面跟上数字,最后以\r\n结尾:

:3\r\n

4.字符串回复
字符串回复(bulk reply)以 开头,并在后面跟上字符串的长度,并以\r\n分隔,接着是字符串的内容和\r\n:

$3\r\nbar\r\n

如果返回值是空结果nil,则会返回 -1以和空字符串相区别。
5.多行字符串回复
多行字符串回复(multi-bulk reply)以*开头,并在后面跟上字符串回复的组数,并以\r\n分隔。接着后面跟的就是字符串回复的具体内容了:

*3\r\n 1\r\n3\r\n 1\r\n2\r\n 1\r\n1\r\n

7.4.2 统一请求协议

统一请求协议是从Redis 1.2开始加入的,其命令格式和多行字符串回复的格式很类似,如SET foo bar的统一请求协议写法是“*3\r\n 3\r\nSET\r\n 3\r\nfoo\r\n 3\r\nbar\r\n”。还是使用telnet进行演示:

telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
*3
$3
SET
$3
foo
$3
bar
+OK

同样发送命令时指定了后面字符串的长度,所以命令的每个参数都可以包含二进制的字符。统一请求协议的返回值格式和简单协议一样,这里不再赘述。
Redis的AOF文件和主从复制时主数据库向从数据库发送的内容都使用了统一请求协议。如果要开发一个和Redis直接通信的客户端,推荐使用此协议。如果只是想通过telnet向Redis服务器发送命令则使用简单协议就可以了。

7.5 管理工具

工欲善其事,必先利其器。在使用Redis的时候如果能够有效利用Redis的各种管理工具,将会大大方便开发和管理。

7.5.1 redis-cli

相信大家对redis-cli已经很熟悉了,作为Redis自带的命令行客户端,你可以从任何安装有Redis的服务器中找到它,所以对于管理Redis而言redis-cli是最简单实用的工具。
redis-cli可以执行大部分的Redis命令,包括查看数据库信息的INFO命令,更改数据库设置的CONFIG命令和强制进行RDB快照的SAVE命令等,下面会介绍几个管理Redis时非常有用的命令。
1.耗时命令日志
当一条命令执行时间超过限制时,Redis会将该命令的执行时间等信息加入耗时命令日志(slow log)以供开发者查看。可以通过配置文件的slowlog-log-slower-than参数设置这一限制,要注意单位是微秒(1000000微秒相当于1秒),默认值是10000。耗时命令日志存储在内存中,可以通过配置文件的slowlog-max-len参数来限制记录的条数。
使用SLOWLOG GET命令来获得当前的耗时命令日志,如:

redis>SLOWLOG GET
1) 1) (integer) 4
2) (integer) 1356806413
3) (integer) 58
4) 1) "get"
2) "foo"
2) 1) (integer) 3
2) (integer) 1356806408
3) (integer) 34
4) 1) "set"
2) "foo"
3) "bar"

每条日志都由以下4个部分组成:
(1)该日志唯一ID;
(2)该命令执行的UNIX时间;
(3)该命令的耗时时间,单位是微秒;
(4)命令及其参数。
提示 为了产生一些耗时命令日志作为演示,这里将slowlog-log-slower-than参数值设置为O,即记录所有命令。如果设置为负数则会关闭耗时命令日志。
2.命令监控
Redis提供了MONITOR命令来监控Redis执行的所有命令,redis-cli同样支持这个命令,如在redis-cli中执行MONITOR:

redis> MONITOR
OK

这时Redis执行的任何命令都会在redis-cli中打印出来,如我们打开另一个redis-cli执行SET foo bar命令,在之前的redis-cli中会输出如下内容:

1356806981.885237 [0 127.0.0.1:57339] "SET" "foo" "bar

MONITOR命令非常影响Redis的性能,一个客户端使用MONITOR命令会降低 Redis将近一半的负载能力。所以MONITOR命令只适合用来调试和纠错。
补充知识 Instagram① 团队开发了一个基于MONITOR命令的Redis查询分析程序redis-faina。redis-faina可以根据MONITOR命令的监控结果分析出最常用的命令、访问最频繁的键等信息,对了解Redis的使用情况帮助很大。
redis-faina的项目地址是https://github.com/Instagram/redis-faina,直接下载其中的redis-faina.py文件即可使用。
redis-faina.py的输入值为一段时间的MONITOR命令执行结果。例如:

redis-cli MONITOR | head -n <要分析的命令数> | ./redis-faina.py

7.5.2 phpRedisAdmin

当Redis中的键较多时,使用redis-cli管理数据并不是很方便,就如同管理MySQL时有人喜欢使用phpMyAdmin一样,Redis同样有一个PHP开发的网页端管理工具phpRedisAdmin。phpRedisAdmin支持以树形结构查看键列表,编辑键值,导入/导出数据库数据,查看数据库信息和查看键信息等功能。
1.安装phpRedisAdmin安装phpRedisAdmin的方法如下:

git clone https://github.com/ErikDubbelboer/phpRedisAdmin.git
cd phpRedisAdmin

phpRedisAdmin依赖PHP的Redis客户端Predis,所以还需要执行下面两个命令下载Predis:

git submodule init
git submodule update

2.配置数据库连接
下载完phpRedisAdmin后需要配置Redis的连接信息。默认phpRedisAdmin会连接到127.0.0.1,端口6379,如果需要更改或者添加数据库信息可以编辑includes文件夹中的config.inc. php文件。
3.使用phpRedisAdmin
安装PHP和Web服务器(如Nginx),并将phpRedisAdmin文件夹存放到网站目录中即可访问,如图7-3所示。
phpRedisAdmin自动将Redis的键以“:”分隔并用树形结构显示出来,十分直观。如post:1和post:2两个键都在post树中。
点击一个键后可以查看键的信息,包括键的类型、生存时间及键值,并且可以很方便地编辑。
4.性能
phpRedisAdmin在获取键列表时使用的是KEYS*命令,然后对所有的键使用TYPE命令来获取其数据类型,所以当键非常多的时候性能并不高(对于一个有一百万个键的Redis数据库,在一台普通个人计算机上使用KEYS*命令大约会花费几十毫秒)。由于Redis使用单线程处理命令,所以对生产环境下拥有大数据量的数据库来说不适宜使用phpRedisAdmin管理。

7.5.3 Rdbtools

Rdbtools是一个Redis的快照文件解析器,它可以根据快照文件导出JSON数据文件、分析Redis中每个键的占用空间情况等。Rdbtools是使用Python开发的,项目地址是https://github.com/sripathikrishnan/redis-rdb-tools。
1.安装Rdbtools
使用如下命令安装Rdbtools:

git clone https://github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
sudo python setup.py install

2.生成快照文件
如果没有启用RDB持久化,可以使用SAVE命令手动使Redis生成快照文件。
3.将快照导出为JSON格式
快照文件是二进制格式,不利于查看,可以使用Rdbtools来将其导出为JSON格式,命令如下:

rdb --command json /path/to/dump.rdb > output_filename.json

其中/path/to/dump.rdb是快照文件的路径,output_filename.json为要导出的文件路径。
4.生成空间使用情况报告
Rdbtools能够将快照文件中记录的每个键的存储情况导出为CSV文件,可以将该CSV文件导入到Excel等数据分析工具中分析来了解Redis的使用情况。命令如下:

rdb -c memory /path/to/dump.rdb > output_filename.csv

导出的CSV文件的字段及说明如表7-1所示。
QQ截图20160318225010.png

7.6 Redis 性能测试

语法
redis 性能测试的基本命令如下:
redis-benchmark [option] [option value]

实例
以下实例同时执行 10000 个请求来检测性能:

redis-benchmark -n 10000
 
PING_INLINE: 141043.72 requests per second
PING_BULK: 142857.14 requests per second
SET: 141442.72 requests per second
GET: 145348.83 requests per second
INCR: 137362.64 requests per second
LPUSH: 145348.83 requests per second
LPOP: 146198.83 requests per second
SADD: 146198.83 requests per second
SPOP: 149253.73 requests per second
LPUSH (needed to benchmark LRANGE): 148588.42 requests per second
LRANGE_100 (first 100 elements): 58411.21 requests per second
LRANGE_300 (first 300 elements): 21195.42 requests per second
LRANGE_500 (first 450 elements): 14539.11 requests per second
LRANGE_600 (first 600 elements): 10504.20 requests per second
MSET (10 keys): 93283.58 requests per second

redis 性能测试工具可选参数如下所示:

序号 选项 描述 默认值
1 -h 指定服务器主机名 127.0.0.1
2 -p 指定服务器端口 6379
3 -s 指定服务器 socket
4 -c 指定并发连接数 50
5 -n 指定请求数 10000
6 -d 以字节的形式指定 SET/GET 值的数据大小 2
7 -k 1=keep alive 0=reconnect 1
8 -r SET/GET/INCR 使用随机 key, SADD 使用随机值
9 -P 通过管道传输 <numreq> 请求 1
10 -q 强制退出 redis。仅显示 query/sec 值
11 –csv 以 CSV 格式输出
12 -l 生成循环,永久执行测试
13 -t 仅运行以逗号分隔的测试命令列表。
14 -I Idle 模式。仅打开 N 个 idle 连接并等待。

实例

以下实例我们使用了多个参数来测试 redis 性能:

redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 10000 -q
 
SET: 146198.83 requests per second
LPUSH: 145560.41 requests per second

以上实例中主机为 127.0.0.1,端口号为 6379,执行的命令为 set,lpush,请求数为 10000,通过 -q 参数让结果只显示每秒执行的请求数。
参考文档:
http://ifeve.com/redis-benchmarks/
http://www.runoob.com/redis/redis-benchmarks.html

7.8 Redis 客户端连接

Redis 通过监听一个 TCP 端口或者 Unix socket 的方式来接收来自客户端的连接,当一个连接建立后,Redis 内部会进行以下一些操作:
  • 首先,客户端 socket 会被设置为非阻塞模式,因为 Redis 在网络事件处理上采用的是非阻塞多路复用模型。
  • 然后为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法
  • 然后创建一个可读的文件事件用于监听这个客户端 socket 的数据发送

最大连接数
在 Redis2.4 中,最大连接数是被直接硬编码在代码里面的,而在2.6版本中这个值变成可配置的。
maxclients 的默认值是 10000,你也可以在 redis.conf 中对这个值进行修改。

config get maxclients
1)"maxclients"
2)"10000"
S.N. 命令 描述
1 CLIENT LIST 返回连接到 redis 服务的客户端列表
2 CLIENT SETNAME 设置当前连接的名称
3 CLIENT GETNAME 获取通过 CLIENT SETNAME 命令设置的服务名称
4 CLIENT PAUSE 挂起客户端连接,指定挂起的时间以毫秒计
5 CLIENT KILL 关闭客户端连接

7.9 Redis 服务器

以下实例演示了如何获取 redis 服务器的统计信息:
127.0.0.1:6379> INFO
# Server
redis_version:3.0.7
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:d8d764d8bdb260a1
redis_mode:standalone
os:Linux 3.10.0-123.9.3.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.8.2
process_id:24865
run_id:6cb5ecae3a2035fbf4a0c8b539c5f2d28282b9eb
tcp_port:6379
uptime_in_seconds:128229
uptime_in_days:1
hz:10
lru_clock:15483518
config_file:
# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
# Memory
used_memory:816072
used_memory_human:796.95K
used_memory_rss:2527232
used_memory_peak:836920
used_memory_peak_human:817.30K
used_memory_lua:36864
mem_fragmentation_ratio:3.10
mem_allocator:jemalloc-3.6.0
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1458285243
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
# Stats
total_connections_received:5
total_commands_processed:81
instantaneous_ops_per_sec:0
total_net_input_bytes:2549
total_net_output_bytes:5289
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:36
keyspace_misses:4
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:182
migrate_cached_sockets:0
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:75.82
used_cpu_user:53.30
used_cpu_sys_children:0.00
used_cpu_user_children:0.00
# Cluster
cluster_enabled:0
# Keyspace
db0:keys=7,expires=0,avg_ttl=0

下表列出了 redis 服务器的相关命令:

序号 命令及描述
1 BGREWRITEAOF
异步执行一个 AOF(AppendOnly File) 文件重写操作
2 BGSAVE
在后台异步保存当前数据库的数据到磁盘
3 CLIENT KILL [ip:port] [ID client-id]
关闭客户端连接
4 CLIENT LIST
获取连接到服务器的客户端连接列表
5 CLIENT GETNAME
获取连接的名称
6 CLIENT PAUSE timeout
在指定时间内终止运行来自客户端的命令
7 CLIENT SETNAME connection-name
设置当前连接的名称
8 CLUSTER SLOTS
获取集群节点的映射数组
9 COMMAND
获取 Redis 命令详情数组
10 COMMAND COUNT
获取 Redis 命令总数
11 COMMAND GETKEYS
获取给定命令的所有键
12 TIME
返回当前服务器时间
13 COMMAND INFO command-name [command-name …]
获取指定 Redis 命令描述的数组
14 CONFIG GET parameter
获取指定配置参数的值
15 CONFIG REWRITE
对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写
16 CONFIG SET parameter value
修改 redis 配置参数,无需重启
17 CONFIG RESETSTAT
重置 INFO 命令中的某些统计数据
18 DBSIZE
返回当前数据库的 key 的数量
19 DEBUG OBJECT key
获取 key 的调试信息
20 DEBUG SEGFAULT
让 Redis 服务崩溃
21 FLUSHALL
删除所有数据库的所有key
22 FLUSHDB
删除当前数据库的所有key
23 INFO [section]
获取 Redis 服务器的各种信息和统计数值
24 LASTSAVE
返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示
25 MONITOR
实时打印出 Redis 服务器接收到的命令,调试用
26 ROLE
返回主从实例所属的角色
27 SAVE
异步保存数据到硬盘
28 SHUTDOWN [NOSAVE] [SAVE]
异步保存数据到硬盘,并关闭服务器
29 SLAVEOF host port
将当前服务器转变为指定服务器的从属服务器(slave server)
30 SLOWLOG subcommand [argument]
管理 redis 的慢日志
31 SYNC
用于复制功能(replication)的内部命令
作者:田守芝
来源:http://www.tianshouzhi.com/api/tutorials/redis/193

版权声明:文末如注明作者和来源,则表示本文系转载,版权为原作者所有 | 本文如有侵权,请及时联系,承诺在收到消息后第一时间删除 | 如转载本文,请注明原文链接。
喜欢 (0)