redis-8

redis学习第八章

管理

  1. 安全

1.1 可信的环境

redis的安全设计是在“redis运行在可信环境”这个前提下做出的。在盛传环境运行时不能允许外界直接连接到redis的服务器上,而应该通过应用程序进行中转,运行在可信的环境中是保证redis安全的最重要方法。

redis的默认设置回接收来自任何地址发送来的请求,即在任何一个拥有公网IP的服务器上启动redis服务器,都可以被外界直接访问到。要更改这一设置,在配置文件中修改bind参数,如只允许本机应用连接redis,可以将bind参数改成:bind 127.0.0.1

bind参数只能绑定一个地址(redis可能会在2.8版本中支持绑定多个地址),如果想更自由地设置访问规则需要通过防火墙来完成。

1.2 数据库密码

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

客户端每次连接到redis时都需要发送密码,否则redis会拒绝执行客户端发来的命令。
例如:
redis > GET foo
(error) ERR opeartion not permitted

发送密码需要使用AUTH命令:
redis > AUTH 123
OK
之后就可以执行命令:
redis > get foo
bar

由于redis的性能极高,并且输入错误密码后redis并不会进行主动延迟(考虑到redis的单线程模型),所以攻击者可以通过穷举法破解redis密码(1秒能尝试十几万个密码)因此在设置时一定要选择复杂的密码。

提示 配置redis复制的时候如果主数据库设置了密码,需要在从数据库的配置文件中通过masterauth参数设置主数据库的密码,以使从数据库连接主数据库时自动使用AUTH命令认证。

1.3 命名命令

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

rename-command FLUSHALL sdaskdjakshfsakjhfcbkja

如果希望直接禁用某个命令可以将命令重命名成空字符串:
rename-command FLUSHALL ‘’

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

  1. 通信协议

redis通讯协议是redis客户端与redis之间交流的语言,通信协议规定了命令的返回值和格式,了解redis通信协议后不仅可以理解AOF文件的格式和主从复制时主数据库向从数据库发送的内容等,还可以开发自己的redis客户端(不过由于几乎所有的常用的语言都有相应的redis客户端,需要使用通信协议直接和redis打交道的机会确实不多)。

redis支持两种通信协议,一种是二进制的安全的统一请求协议(unified request protocol)。另一种是比较直观的便于在telnet程序中输入的简单协议。这两种协议只是命令的格式有却别,命令返回值的格式是一样的。

2.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:表示服务端发出的内容。第一行的最后一个参数表示字符串的场地,第二行是字符串的实际内容,因为指定了长度,所以第二行的字符串可以包含二进制字符。但是这个协议已经废弃,被新的统一请求协议取代。“统一”二字指的是所有的命令使用同样的请求方式而不再为某些命令使用特殊方式,如果需要在参数中包含二进制字符应该使用2.2介绍的统一请求。

我们在telnet程序中输入的5命令中恰好展示了redis的5种返回值类型的格式,这些展现形式是经过redis-cli封装的,而上面的内容才是redis真正返回的格式。

1).错误回复
错误恢复(error reply)以-开头,并在后面更上错误信息,最后以\r\n结尾:

-ERR unknow 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

5).多行字符串回复
多行字符串回复(multi-bulk reply)以*开头,并在后面跟上字符串回复的数组,并以\r\n分隔。接着后面跟的就是字符串回复的具体内容了:
*3\r\n$1\r\n3\r\n$1\r\n2\r\n$1\r\n

2.2 统一请求协议

统一请求协议是从redis1.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服务器发送命令则使用简单协议就可以了。

  1. 管理工具

3.1 redis-cli

redis-cli可以执行大部分的redis命令,包括查看数据库的信息的INFO命令,更改数据库设置的CONFIG命令和强制进行RDB快照的save命令等,下面介绍几个管理redis时非常有用的命令。

1).耗时命令日志
当一条命令执行时间超过限制时,redis会将该命令的执行时间等信息加入耗时命令日志(show 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"

每条日志都由一下4个部分组成:
1).该日志唯一ID
2).该命令执行的UNIX时间
3).该命令的耗时单位,单位是微妙
4).命令及其参数

提示 这里将slowlog-log-slower-than参数设置为0,所以才能打印出来

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

3.2 phpRedisAdmin

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

1).安装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文件夹存放到网站目录总即可访问。

phpRedisAdmin自动将redis的键以“:”分隔并用树形结构显示出来,十分直观。如post:1和post:2两个键都在post树中。

点击一个键后可以查看键的信息,包括键的类型、生存时间以及键值,并且可以很方便的编辑。

4).性能
phpRedisAdmin在获取键列表时使用的是KEYS *命令,然后对所有的键使用TYPE命令来获取其数据类型,所以当键非常多的时候性能并不高(对于一个有一百万的键的redis数据库,在一台普通个人计算机上使用KEYS *大约花费几十毫秒)。由于redis使用单线程处理命令,所以对生产环境下拥有大数据量的数据库来说不适宜使用phpRedisAdmin管理。

3.3 Rdbtools

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

1).安装

使用如下命令:
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.json.csv
导出csv文件的字段即说明:

字段 说明
database 存储该键的数据库索引
type 键类型(使用TYPE命令获得)
key 键名
size_in_bytes 键大小(字节)
encoding 内部编码(使用OBJECTENCODING命令获得)
num_elements 键的元素数
len_largest_element 最大元素的长度

你可能感兴趣的:(读书记录)