Redis基础知识

Redis CentOS7下安装

Redis的安装,有epel和remi两个yum源可选。当然也可以选择从源码安装。
如下介绍epel和remi的两种安装方式。

EPEL安装

CentOS 7中EPEL中redis最新的版本是3.2.12-2

安装命令如下:

1
2
3
4
5
sudo yum install epel-release yum-utils
sudo yum install redis
sudo systemctl start redis
sudo systemctl enable redis
sudo systemctl status redis

REMI安装

remi-release-7中redis最新的版本是6.0.5

安装命令如下:

1
2
3
4
5
6
7
sudo yum install epel-release yum-utils
sudo yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum-config-manager --enable remi
sudo yum install redis
sudo systemctl start redis
sudo systemctl enable redis

基本配置

配置访问密码

配置

/etc/redis.conf中修改requirepass master_password, 将master_password换成所要配置的密码。
注意: 配置文件中描述, redis每秒可以承受150k的密码撞击,所以务必将密码设置的极为复杂。

Warning: since Redis is pretty fast an outside user can try up to
150k passwords per second against a good box. This means that you should
use a very strong password otherwise it will be very easy to break.

因为密码显示的存在配置文件中,因此不用担心会忘记密码,尽可能的使用复杂密码,
网上一个使用sha256sum来生成强密码的方法 How to Install and Secure Redis on Centos7

1
2
3
[root@localhost lib]# echo "hello-world" | sha256sum
d79f2e37784e5cd8631963896ebc6c9c66934af94a1854504717eaec04bc3d09 -
[root@localhost lib]#

试验

cli中使用AUTH来输入密码。

1
2
3
4
5
6
[root@localhost ~]# redis-cli
127.0.0.1:6379> AUTH d79f2e37784e5cd8631963896ebc6c9c66934af94a1854504717eaec04bc3d09
OK
127.0.0.1:6379> get a
"1"
127.0.0.1:6379>

没有密码时,执行命令会报错

1
2
3
4
[root@localhost ~]# redis-cli
127.0.0.1:6379> get b
(error) NOAUTH Authentication required.
127.0.0.1:6379>

访问安全

Redis Security中有相关描述。

Redis is designed to be accessed by trusted clients inside trusted environments.
Redis设计的用途就是在信任环境中使用的,因此自身没有用户系统和访问控制机制。

redis默认的安全设定

  • /etc/redis.conf配置中,默认bind 127.0.0.1,即只能从本地访问redis
  • 从3.2.0开始,Protected mode默认是启动的,默认配置protected-mode yes。在这个模式中,只有来自loopback interface的请求才会被响应,其他地址的请求会被返回错误。

外部控制

如果redis需要对外提供服务,那么需要在bind后面加上绑定的本机IP, 例如:

1
bind 127.0.0.1 192.168.187.182

但因为redis除了密码以外,没有其他的访问控制机制。因此需要依赖于系统防火墙进行访问控制,比如设置访问白名单。

1
2
3
4
sudo firewall-cmd --new-zone=redis --permanent
sudo firewall-cmd --zone=redis --add-port=6379/tcp --permanent
sudo firewall-cmd --zone=redis --add-source=192.168.187.0/24 --permanent
sudo firewall-cmd --reload

配置持久化

配置说明

持久化目录, 由/etc/redis.confdir配置, 配置的解释

1
2
3
4
5
6
7
8
9
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /var/lib/redis

其中epel中安装的redis,默认目录是/var/lib/redis.

修改方法

修改redis目录为/opt/app/redis的方法如下。
创建目录

1
2
3
sudo mkdir -p /opt/app/redis
sudo chown -R redis:redis /opt/app/redis
sudo chmod 750 /opt/app/redis

修改/etc/redis.confdir参数为/opt/app/redis

1
dir /opt/app/redis

重启redis

1
systemctl restart redis

异常

如果切换了dir的目录,但执行save命令时失败,log中有Permission denied的错误时。

1
Failed opening the RDB file dump.rdb (in server root dir /opt/app/redis) for saving: Permission denied

有可能的原因:

  • 目录没有设置为redis账户可读写
  • 开启了selinux所致。

配置日志地址

修改配置中logfile的值。epel安装的redis,默认值为/var/log/redis/redis.log.

1
logfile /var/log/redis/redis.log

常用命令

基本操作

  • DEL key: 该命令用于在 key 存在时删除 key。
  • DUMP key: 序列化给定 key ,并返回被序列化的值。
  • EXISTS key: 检查给定 key 是否存在。
  • EXPIRE key seconds: 为给定 key 设置过期时间。
  • EXPIREAT key timestamp: EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。
  • PEXPIRE key milliseconds: 设置 key 的过期时间以毫秒计。
  • PEXPIREAT key milliseconds-timestamp: 设置 key 过期时间的时间戳(unix timestamp) 以毫秒计
  • KEYS pattern: 查找所有符合给定模式( pattern)的 key 。
  • MOVE key db: 将当前数据库的 key 移动到给定的数据库 db 当中。
  • PERSIST key: 移除 key 的过期时间,key 将持久保持。
  • PTTL key: 以毫秒为单位返回 key 的剩余的过期时间。
  • TTL key: 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
  • RANDOMKEY: 从当前数据库中随机返回一个 key 。
  • RENAME key newkey: 修改 key 的名称
  • RENAMENX key newkey: 仅当 newkey 不存在时,将 key 改名为 newkey 。
  • TYPE key: 返回 key 所储存的值的类型。

基本命令小实验

设置和获取key,设置key的过期时间,获取key的过期时间。

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> set testkey "testvalue"
OK
127.0.0.1:6379> get testkey
"testvalue"
127.0.0.1:6379> TTL testkey
(integer) -1
127.0.0.1:6379> EXPIRE testkey 60
(integer) 1
127.0.0.1:6379> TTL testkey
(integer) 58
127.0.0.1:6379>

TTL命令

当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回 key 的剩余生存时间。

实验过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
127.0.0.1:6379> get testkey # 获取testkey,还没设置,返回nil
(nil)
127.0.0.1:6379> ttl testkey # 获取testkey的过期时间,key不存在,返回-2
(integer) -2
127.0.0.1:6379> set testkey "testvalue" # 设置testkey,但不添加过期时间
OK
127.0.0.1:6379> ttl testkey # 此时获取testkey的过期时间,key存在但没有设置过期时间,返回-1
(integer) -1
127.0.0.1:6379> expire testkey 3600 # 设置testkey的过期时间
(integer) 1
127.0.0.1:6379> pttl testkey # 查看testkey的过期毫秒数
(integer) 3591798
127.0.0.1:6379> ttl testkey # 查看testkey的过期时间,返回将要过期的秒数
(integer) 3580
127.0.0.1:6379> del testkey # 删除testkey
(integer) 1
127.0.0.1:6379> ttl testkey # 获取testkey的过期时间,因为key不存在,返回-2
(integer) -2
127.0.0.1:6379>

key 的变动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
127.0.0.1:6379> keys * # 获取所有的key,为空。
(empty list or set)
127.0.0.1:6379> set testkey "testvalue" # 设置testkey
OK
127.0.0.1:6379> set testkey1 "testvalue1" # 设置testkey1
OK
127.0.0.1:6379> set testkey2 "testvalue2" # 设置testkey2
OK
127.0.0.1:6379> keys * # 获取所有的key,可以看到testkey,testkey1, testkey2
1) "testkey2"
2) "testkey1"
3) "testkey"
127.0.0.1:6379> RANDOMKEY # 随机获取一个key
"testkey2"
127.0.0.1:6379> RANDOMKEY # 随机获取一个key
"testkey2"
127.0.0.1:6379> RANDOMKEY # 随机获取一个key
"testkey"
127.0.0.1:6379> RENAME testkey2 testkey_2 # 重命名testkey2为testkey_2
OK
127.0.0.1:6379> keys * # 获取所有的key,可以看到testkey,testkey1, testkey_2
1) "testkey1"
2) "testkey"
3) "testkey_2"
127.0.0.1:6379> type testkey_2 # 查看testkey_2的类型,为string
string
127.0.0.1:6379>

Reference

留言