Redis教程

百科:

Redis - 维基百科

推荐:

Redis 教程 - 菜鸟

请习惯查看官网

可视化工具

RedisInsight

RedisInsight 是 Redis 官网可视化工具,前身为 Redis Desktop Manager。

AnotherRedisDesktopManager

https://github.com/qishibo/AnotherRedisDesktopManager

官方

https://redis.io/

https://github.com/redis/redis

官方命令手册: https://redis.io/docs/latest/commands/

下载与安装

Linux

请从GitHub下载源码编译安装:

检查

1
2
3
4
5
6
7
8
9
10
11
12
13
find / | grep redis.conf
find / | grep .*redis.*

gcc --version
make --version
yum install gcc
yum install make

firewall-cmd --state
systemctl start firewalld
systemctl stop firewalld
systemctl enable firewalld
systemctl disable firewalld

安装

1
2
3
4
5
6
7
8
9
10
11
mkdir -p /opt/local/redis/log
mkdir -p /opt/local/redis/pid
mkdir -p /opt/local/redis/cluster
cd /opt/local
tar -zxvf redis-7.4.0.tar.gz
cd /opt/local/redis-7.4.0

make distclean
make
make PREFIX=/opt/local/redis install
make uninstall

为了让reids命令可以在任何位置执行,需配置环境变量,参考:** 环境变量持久化 **

1
2
3
echo "export PATH=/opt/local/redis/bin:$PATH" >> /etc/profile
source /etc/profile
vim /etc/profile

节点配置文件

阿里云Redis支持的参数及说明: https://help.aliyun.com/zh/redis/user-guide/supported-parameters

从解压目录复制一份配置文件:cp /opt/local/redis-7.4.0/redis.conf /opt/local/redis/redis.conf

创建 aclfile。Redis 6之后,requirepass 仅为default用户设置密码,而且启用 ACL 会使它失效。

1
2
echo "user default on ~* &* +@all >123456789" >> /opt/local/redis/users.acl
echo "user worker on ~* &* +@all >123456789" > /opt/local/redis/users.acl

新建master节点配置文件 vim /opt/local/redis/redis_6379.conf

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
################################## INCLUDES ###################################
include /opt/local/redis/redis.conf

################################## NETWORK #####################################
bind * -::*
# 默认情况下启用保护模式。仅当您确定希望其他主机的客户端连接到 Redis(即使未配置身份验证)时,才应禁用它。即开启远程访问
protected-mode no
port 6379
# 设置tcp的backlog,backlog其实是一个连接队列,backlog队列总和=未完成三次握手队列 + 已经完成三次握手队列。 在高并发环境下你需要一个高backlog值来避免慢客户端连接问题。
# 请注意,Linux内核默认会将这个值减小到/proc/sys/net/core/somaxconn的值(128),因此请确保同时提高
# /proc/sys/net/core/somaxconn 和 /proc/sys/net/ipv4/tcp_max_syn_backlog(128)两个值,以获得所需的效果
tcp-backlog 511
# 客户端空闲N秒后关闭连接(0表示禁用,即永不关闭)。
timeout 0
# 对访问客户端的一种心跳检测,每个n秒检测一次。单位为秒,如果设置为0,则不会进行Keepalive检测,建议设置成60
tcp-keepalive 300


################################# GENERAL #####################################
# 服务后台启动
daemonize yes
# 进程号保存文件
pidfile /opt/local/redis/pid/redis_6379.pid
# 日志级别
loglevel notice
# 指定日志文件名
logfile "/opt/local/redis/log/redis_6379.log"
# 设置数据库数量
databases 16

################################## SECURITY ###################################
# 创建ACL用户(Redis ACL 是访问控制列表 (Access Control List) 的缩写,它允许对某些连接进行限制,限制其可执行的命令和可访问的密钥。)
# 有些客户端不支持复杂的用户名,会导致连接的用户密码对无效,比如 Another Redis Desktop Manager
#user worker on ~* &* +@all >123456789
aclfile /opt/local/redis/users.acl
# 为default用户设置密码。>>> 若启用ACL,则该配置失效 <<<
requirepass 123456789

################################### CLIENTS ####################################
# 设置同时连接的最大客户端数。
maxclients 10000

############################## MEMORY MANAGEMENT ################################
# 最大内存,104857600 Bytes = 100 MB
maxmemory 104857600
# 最大内存策略:当达到最大内存时,Redis 将如何选择删除哪些内容。noeviction -> 不要驱逐任何东西,只是在写操作上返回错误。
maxmemory-policy noeviction
maxmemory-samples 5
# 默认情况下,slave节点忽略其maxmemory设置(除非在故障转移后或手动将其提升为主节点),这意味着keys的驱逐将由master节点处理,当keys在master中驱逐时,将DEL命令发送到slave。
replica-ignore-maxmemory yes
# 删除过期Key(Expire)因子,用于设置每次删除过期Key的延时,取值为[1-10],默认为1。数值越大删除过期Key越快,同时消耗的CPU资源也更多。这是内存、CPU 和延迟之间的权衡。
active-expire-effort 1

################################ SNAPSHOTTING ################################
# RDB(Redis DataBase)默认开启
#** Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,
#** 主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
#** RDB的缺点是最后一次持久化后的数据可能丢失。

# 将数据库保存到磁盘。 save <seconds> <changes> [<seconds> <changes> ...]
# 如果经过给定的秒数并且超过了对数据库的给定写入操作数,Redis将会保存数据库。可以使用单个空字符串参数完全禁用快照,如 save ""
# 除非另有说明,默认情况下Redis将会保存DB:经过3600秒且至少有1次更改,经过300秒且至少有100次更改,经过60秒且至少有10000次更改.
# 可以使用单个空字符串参数完全禁用快照,示例:save ""
save 3600 1 300 100 60 10000
# 默认情况下,如果启用了 RDB 快照(至少一个保存点)并且最新的后台save失败,Redis 将停止接受写入操作。这将使用户(以一种硬性的方式)意识到数据没有正确地保存在磁盘上,
# 否则很可能没有人会注意到并且会发生一些灾难。
# 如果后台save过程再次开始工作,Redis将自动允许再次写入。
# 但是,如果您已经设置了对 Redis 服务器和持久性的正确监控,则可能需要禁用此功能,以便即使磁盘、权限等出现问题,Redis 也能继续照常工作。
stop-writes-on-bgsave-error yes
# 转储.rdb数据库时使用LZF算法压缩字符串对象?默认启用压缩,因为它几乎总是胜利。如果想在saving子进程中节省一些CPU,请将其设置为'no',但如果有可压缩的值或键,数据集可能会更大。
rdbcompression yes
# 检查rdb文件完整性
rdbchecksum yes
# 转储数据库的文件名。
dbfilename dump_6379.rdb
# 工作目录。DB 将写入此目录内,并使用上面使用“dbfilename”配置指令指定的文件名。AOF也将在此目录中创建。请注意,您必须在此处指定目录,而不是文件名。
dir /opt/local/redis/

############################## APPEND ONLY MODE ###############################
# AOF(Append Only File)默认不开启
# AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失)
appendonly yes
appendfilename "appendonly_6379.aof"
appenddirname "appendonlydir_6379"
# 每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
appendfsync everysec
no-appendfsync-on-rewrite no
# Redis会记录上次重写时的AOF大小,当AOF日志大小增长指定percentage且文件大于min-size时,Redis 能够隐式调用 BGREWRITEAOF 自动重写日志文件。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

################################# REPLICATION #################################
# 设置一个Redis实例成为另一个Redis服务器的副本。不要指定自己,否则log会快速增长
#replicaof 127.0.0.1 6379
# 节点间互相访问的密码
masterauth 123456789
# 节点间互相访问的用户。从Redis6开始支持,必须指定用户名,否则无法执行PSYNC命令
masteruser worker
# 当master节点失联时,从库依然可以被客户端访问,但可能是过时的数据
replica-serve-stale-data yes
# 从库只读
replica-read-only yes
# 从库同步策略(磁盘或套接字)。主从复制过程中,新slave节点和slave节点重连后无法进行增量同步,需要进行一次全量同步,两种方式:Disk-backed(磁盘备份)、Diskless(无盘备份)。
repl-diskless-sync yes
# 启用Diskless时,可以配置服务器等待的延迟,等待更多slave节点连接然后并行传输。这很重要,因为一旦传输开始,就不可能为新slave提供服务,这些新slave将排队等候下一次RDB传输,因此服务器会等待一段时间,以便让更多slave节点连接。
repl-diskless-sync-delay 5
# 当Diskless启用且有延迟时,如果slave节点数量达到最大值,则立即开始同步,无需达到最大延迟。默认值0表示未定义最大值,Redis将等待完整的延迟。
repl-diskless-sync-max-replicas 0
# 是否开启无盘加载,即从网络接收到 rdb 文件后,是否直接加载,而不是先全部写入磁盘文件,再加载。无盘加载因为不通过磁盘,所以速度快一点,但是因为不写入磁盘,所以在故障转移时可能会丢失数据。
# 副本可以直接从套接字加载它从复制链路读取的 RDB,或者将 RDB 存储到文件中,并在从主服务器完全接收到该文件后读取该文件。
repl-diskless-load disabled
# master向salve发送PING的时间间隔
repl-ping-replica-period 10
# 复制超时时间。包括:
# 1、全量同步时,salve节点从发出请求到 RDB 文件接收完整的超时;
# 2、salve节点的视角,master节点的通信超时(比如从发给主的心跳);
# 3、master节点的视角,salve节点的通信超时;
# 确保该值大于为 repl-ping-replica-period
repl-timeout 60
repl-disable-tcp-nodelay no
replica-priority 100

################################ REDIS CLUSTER ###############################
#cluster-enabled yes
cluster-config-file /opt/local/redis/cluster/nodes-6379.conf
cluster-node-timeout 15000
# cluster-port 0
# cluster-replica-validity-factor 10
# cluster-migration-barrier 1
# cluster-allow-replica-migration yes
# 如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为yes,那么,整个集群都挂掉;
# 如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为no,那么,该插槽数据全都不能使用,也无法存储。
cluster-require-full-coverage yes
# cluster-replica-no-failover no
# cluster-allow-reads-when-down no
# cluster-allow-pubsubshard-when-down yes
# cluster-link-sendbuf-limit 0
# cluster-announce-hostname ""
# cluster-announce-human-nodename ""
# cluster-preferred-endpoint-type ip

新建slave节点配置文件 vim /opt/local/redis/redis_6380.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
include /opt/local/redis/redis_6379.conf

port 6380
requirepass 123456789
pidfile /opt/local/redis/pid/redis_6380.pid
logfile "/opt/local/redis/log/redis_6380.log"
dbfilename dump_6380.rdb

appendfilename "appendonly_6380.aof"
appenddirname "appendonlydir_6380"

################################# REPLICATION #################################
replicaof 192.168.0.7 6379
masterauth 123456789
masteruser worker

################################ REDIS CLUSTER ###############################
cluster-config-file /opt/local/redis/cluster/nodes-6380.conf

启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
redis-server /opt/local/redis/redis_6379.conf
redis-server /opt/local/redis/redis_6380.conf
ps -ef | grep redis

redis-cli -u redis://worker:123456789@localhost:6379/0 -a 123456789 info replication
redis-cli -p 6379 -a 123456789 info replication # 这种方式只能连接default用户
redis-cli -p 6379 # 连接redis,默认端口6379
auth default 123456789
info replication
acl list
select 0 # 切换数据库
dbsize # 查看当前数据库的key的数量
flushdb # 清空当前库
flushall # 清空所有库
acl list

ll /root/.cache/vmware/drag_and_drop/
rm -rf /root/.cache/vmware/drag_and_drop/*

哨兵配置文件–使用中

请在上述节点配置文件中,关闭集群模式,并配置主从关系。

编辑哨兵配置文件 vim /opt/local/redis/redis_sentinel_26379.conf。或从解压目录复制一份哨兵配置文件后再修改:cp /opt/local/redis-7.4.0/sentinel.conf /opt/local/redis/redis_sentinel_26379.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected-mode no
port 26379
daemonize yes
pidfile /opt/local/redis/pid/redis_sentinel_26379.pid
loglevel notice
logfile "/opt/local/redis/log/redis_sentinel_26379.log"

# 创建ACL用户(Redis ACL 是访问控制列表 (Access Control List) 的缩写,它允许对某些连接进行限制,限制其可执行的命令和可访问的密钥。)
user worker on ~* &* +@all >123456789
# 为哨兵的default用户设置密码
requirepass 123456789

# 其中 Redis-Maste 是给监控对象起的服务器名称,1 为至少有多少个哨兵同意迁移的数量。
sentinel monitor mymaster 192.168.0.7 6379 1
# 设置连接master和slave时的密码,注意必须为主从设置一样的验证密码。
sentinel auth-pass mymaster 123456789
# 这对于对具有ACL功能(即运行Redis6.0或更高版本)的实例进行身份验证非常有用。当仅提供auth-pass时,
# Sentinel实例将使用旧的“AUTH <pass>”方法向Redis进行身份验证。当还提供用户名时,它将使用“AUTH <user> <pass>”。
sentinel auth-user mymaster worker

# 您可以将 Sentinel 配置为使用特定用户名向其他 Sentinel 进行身份验证。
sentinel sentinel-user worker
# 设置哨兵与其他哨兵的认证密码;(如果没有配置sentinel-user,将使用“default”用户和sentinel-pass命令进行验证)
sentinel sentinel-pass 123456789

启动

sentinel不是数据节点,而是监控节点,所以在nodes节点无法运行select、keys等命令。

1
2
3
4
5
6
7
8
9
redis-sentinel /opt/local/redis/redis_sentinel_26379.conf
ps -ef | grep redis

redis-cli -u redis://worker:123456789@localhost:26379/0 -a 123456789 info sentinel
redis-cli -p 26379 -a 123456789 info sentinel # 这种方式只能连接default用户
redis-cli -p 26379 #-a 123456789 # 连接sentinel,默认端口26379
auth sentinel-worker 123456789
info sentinel
acl list

注意:

反客为主后,会对原salve的配置进行rewrite( Redis Config rewrite 命令 ),而原master节点重新启动并不会成为现master节点的salve,需要重新配置。

开机自启

1
2
3
4
5
6
yum install chkconfig # centos stream9 必须在init文件创建前安装,否则目录已存在则安装失败,可能是系统bug

# 从redis解压包复制init脚本,然后修改启动文件
# cp /opt/local/redis-7.4.0/utils/redis_init_script /etc/init.d/redis
# 或直接新增启动文件
vim /etc/init.d/redis

启动文件内容如下:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.

### BEGIN INIT INFO
# Provides: redis_6379
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Redis data structure server
# Description: Redis data structure server. See https://redis.io
### END INIT INFO

REDISPORT_6379=6379
PIDFILE_6379=/opt/local/redis/pid/redis_${REDISPORT_6379}.pid
CONF_6379="/opt/local/redis/redis_${REDISPORT_6379}.conf"

REDISPORT_6380=6380
PIDFILE_6380=/opt/local/redis/pid/redis_${REDISPORT_6380}.pid
CONF_6380="/opt/local/redis/redis_${REDISPORT_6380}.conf"

REDIS_SENTINELPORT_26379=26379
PIDFILE_26379=/opt/local/redis/pid/redis_sentinel_${REDIS_SENTINELPORT_26379}.pid
CONF_26379="/opt/local/redis/redis_sentinel_${REDIS_SENTINELPORT_26379}.conf"

EXEC=/opt/local/redis/bin/redis-server
SLEXEC=/opt/local/redis/bin/redis-sentinel
CLIEXEC=/opt/local/redis/bin/redis-cli

case "$1" in
start)
if [ -f $PIDFILE_6379 ]
then
echo "$PIDFILE_6379 exists, process is already running or crashed"
else
echo "Starting Redis $REDISPORT_6379 server..."
$EXEC $CONF_6379
fi

sleep 1

if [ -f $PIDFILE_6380 ]
then
echo "$PIDFILE_6380 exists, process is already running or crashed"
else
echo "Starting Redis $REDISPORT_6380 server..."
$EXEC $CONF_6380
fi

sleep 1

if [ -f $PIDFILE_26379 ]
then
echo "$PIDFILE_26379 exists, process is already running or crashed"
else
echo "Starting Redis $REDIS_SENTINELPORT_26379 server..."
$SLEXEC $CONF_26379
fi
;;
stop)
if [ ! -f $PIDFILE_6379 ]
then
echo "$PIDFILE_6379 does not exist, process is not running"
else
PID_6379=$(cat $PIDFILE_6379)
echo "Stopping $REDISPORT_6379 ..."
$CLIEXEC -u redis://worker:123456789@localhost:6379/0 -a 123456789 --no-auth-warning shutdown
while [ -x /proc/${PID_6379} ]
do
echo "Waiting for Redis $REDISPORT_6379 to shutdown ..."
sleep 1
done
echo "Redis $REDISPORT_6379 stopped"
fi

sleep 1

if [ ! -f $PIDFILE_6380 ]
then
echo "$PIDFILE_6380 does not exist, process is not running"
else
PID_6380=$(cat $PIDFILE_6380)
echo "Stopping $REDISPORT_6380 ..."
$CLIEXEC -u redis://worker:123456789@localhost:6380/0 -a 123456789 --no-auth-warning shutdown
while [ -x /proc/${PID_6380} ]
do
echo "Waiting for Redis $REDISPORT_6380 to shutdown ..."
sleep 1
done
echo "Redis $REDISPORT_6380 stopped"
fi

sleep 1

if [ ! -f $PIDFILE_26379 ]
then
echo "$PIDFILE_26379 does not exist, process is not running"
else
PID_26379=$(cat $PIDFILE_26379)
echo "Stopping $REDIS_SENTINELPORT_26379 ..."
$CLIEXEC -u redis://worker:123456789@localhost:26379/0 -a 123456789 --no-auth-warning shutdown
while [ -x /proc/${PID_26379} ]
do
echo "Waiting for Redis $REDIS_SENTINELPORT_26379 to shutdown ..."
sleep 1
done
echo "Redis $REDIS_SENTINELPORT_26379 stopped"
fi
;;
*)
echo "Please use start or stop as first argument"
;;
esac

修改文件权限

1
chmod 777 /etc/init.d/redis

启动

1
2
service redis start
service redis stop # 如果失败,请检查/etc/init.d/redis脚本中的redis密码

设置开机启动

1
2
3
# 设置 redis 服务在运行级别为2、3、4、5时启动。--level 指定读系统服务要在哪一个Linux运行级别中开启或关闭。
chkconfig --level 2345 redis on
chkconfig --level 2345 redis off

集群管理

请在上述节点配置文件中,开启集群模式,并取消主从关系。

redisz主从集群最少需要6个节点。

1
2
3
4
5
cd /opt/local/redis
cp redis_6380.conf redis_6381.conf
cp redis_6380.conf redis_6389.conf
cp redis_6380.conf redis_6390.conf
cp redis_6380.conf redis_6391.conf

修改配置文件,启动6个服务

1
2
3
4
5
6
redis-server /opt/local/redis/redis_6379.conf
redis-server /opt/local/redis/redis_6380.conf
redis-server /opt/local/redis/redis_6381.conf
redis-server /opt/local/redis/redis_6389.conf
redis-server /opt/local/redis/redis_6390.conf
redis-server /opt/local/redis/redis_6391.conf

redis-trib.rb 是官方提供的Redis Cluster的管理工具,无需额外下载,默认位于源码包的src目录下。

1
2
3
4
5
6
7
8
9
10
11
# 将六个节点合成一个集群,组合之前,请确保所有redis实例启动后,nodes-xxxx.conf文件都生成正常。

cd /opt/local/redis-7.4.0/src/ # 必须在此目录下执行
# 此处不要用127.0.0.1,请用真实IP地址
redis-cli --cluster create --cluster-replicas 1 -a 123456789 \
192.168.0.7:6379 \
192.168.0.7:6380 \
192.168.0.7:6381 \
192.168.0.7:6389 \
192.168.0.7:6390 \
192.168.0.7:6391

Redis集群的不足

多键操作是不被支持的

多键的Redis事务是不被支持的。lua脚本不被支持

由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片的方案想要迁移至redis cluster,需要整体迁移而不是逐步过渡,复杂度较大。

windows

https://www.redis.com.cn/redis-installation.html

https://www.runoob.com/redis/redis-install.html 附下载地址

1
2
3
4
5
6
7
8
9
10
11
12
13
# 安装Redis服务
redis-server.exe --service-install redis.windows-service.conf --service-name Redis --loglevel verbose

# 启动
redis-server --service-start
# 测试
redis-cli.exe -h 127.0.0.1 -p 6379
# 停止
redis-server --service-stop

# 卸载Redis服务
redis-server --service-uninstall
sc delete Redis

redis.windows.conf 和 redis.windows-service.conf 的以下配置不同

1
2
3
logfile "server_log.txt"
syslog-enabled yes
syslog-ident redis

redis.windows-service.conf 旨在作为服务/守护程序运行。这意味着它应该在后台运行并由操作系统管理(在重新启动时启动,如果崩溃则重新启动等)。
redis.windows.conf 旨在从命令行或脚本运行并在用户空间中进行管理。
两者之间唯一的实质性区别是服务挂钩到 Windows 系统日志中,这对于服务来说是一个非常好的主意,但对于正常进程来说通常是不必要的。
无论选择哪一种,都需要根据自己的目的对其进行调整。它们只是作为样本。

Redis客户端

1
2
3
4
5
6
7
8
9
10
11
12
-h <hostname> Server hostname (default: 127.0.0.1) # 指定ip
-p <port> Server port (default: 6379) # 指定端口,默认是6379
-a <password> Password to use when connecting to the server # 连接密码
-n <db> Database number # 指定的数据库


# 登录时指定密码,不安全,可以在历史命令中查到
redis-cli -h 127.0.0.1 -p port -a 123456 -n 0

# 不指定密码
redis-cli -h 127.0.0.1 -p 6379 -n 0
auth 123456

Redis五种数据类型

Redis 没有专门的整数类型

String(字符串)

string 是 redis 最基本的数据类型,一个 key 对应一个 value。

string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

基本命令

请参阅字符串命令的完整列表

  • SET存储一个字符串值。
  • SETNX仅当键不存在时才存储字符串值。用于实现锁。
  • GET检索字符串值。
  • MGET在单个操作中检索多个字符串值。

指标管理

  • INCRBY原子地递增(并在传递负数时递减)存储在给定键处的计数器。
  • 浮点计数器存在另一个命令:INCRBYFLOAT

按位运算

要对字符串执行按位运算,请参阅位图数据类型文档。

表现

大多数字符串操作都是O(1),这意味着它们的效率很高。但是,请小心使用SUBSTR复杂GETRANGESETRANGE命令,这些命令可以是O(n)。这些随机访问字符串命令在处理大字符串时可能会导致性能问题。

限制

默认情况下,单个 Redis 字符串最大为 512MB

例子

1
2
3
4
del mykey
set mykey "Hello\nWorld"
OK
get mykey

List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。

每个列表最多可存储 232 - 1 个元素(40多亿)。

Redis 列表经常用于:

  • 实现栈和队列。
  • 为后台工作系统构建队列管理。

基本命令

请参阅完整的列表命令系列

  • LPUSH添加一个新元素到列表的头部;RPUSH添加到尾巴。
  • LPOP从列表的头部移除并返回一个元素;RPOP做同样的事情,但从列表的尾部开始。
  • LLEN返回列表的长度。
  • LMOVE原子地将元素从一个列表移动到另一个列表。
  • LTRIM将列表减少到指定的元素范围。

阻塞命令

列表支持多种阻塞命令。例如:

  • BLPOP从列表的头部移除并返回一个元素。如果列表为空,则命令将阻塞,直到元素可用或达到指定的超时为止。
  • BLMOVE原子地将元素从源列表移动到目标列表。如果源列表为空,则该命令将阻塞,直到有新元素可用为止。

表现

访问其头部或尾部的列表操作的复杂度为 O(1),这意味着它们非常高效。但是,操作列表中元素的命令通常是 O(n)。这些示例包括LINDEXLINSERTLSET。运行这些命令时要小心,特别是在对大型列表进行操作时。

限制

List的最大长度为 232 - 1(40多亿)。

例子

将列表视为队列(先进先出):

1
2
3
4
5
6
7
8
9
del ids
lpush work:queue:ids 1
lpush work:queue:ids 2
lpush work:queue:ids 3

rpop work:queue:ids
"1"
rpop work:queue:ids
"2"

将列表视为堆栈(先进后出):

1
2
3
4
5
6
7
8
9
del ids
lpush work:queue:ids 1
lpush work:queue:ids 2
lpush work:queue:ids 3

lpop work:queue:ids
"3"
lpop work:queue:ids
"2"

检查列表的长度:

1
2
llen work:queue:ids
(integer) 1

创建一个上限为100个元素的列表,可以在每次调用 LPUSH 后调用 LTRIM

1
2
3
4
lpush notifications:user:1 "You've got mail!"
ltrim notifications:user:1 0 99
lpush notifications:user:1 "Your package will be delivered at 12:01 today."
ltrim notifications:user:1 0 99

Set(集合)

Redis 的 Set 是唯一 string 类型元素的无序集合

可以使用 Redis 集来高效地:

  • 跟踪唯一项目(例如,跟踪访问给定博客文章的所有唯一 IP 地址)。
  • 表示关系(例如,具有给定角色的所有用户的集合)。
  • 执行常见的集合运算,例如交集、并集和差集。

基本命令

请参阅set 命令的完整列表

  • SADD将新成员添加到集合中。
  • SREM从集合中删除指定的成员。
  • SISMEMBER测试集合成员的字符串。
  • SINTER返回两个或多个集合共有的成员集合(即交集)。
  • SCARD返回集合的大小(又名基数)。

表现

集合是通过哈希表实现的,所以大多数集合操作,包括添加、删除和检查项是否为集合成员,复杂度都是O(1)。这意味着它们的效率很高。

但是,对于具有数十万或更多成员的大型集,在运行 SMEMBERS 命令时,应谨慎行事。此命令为O(n),并在单个响应中返回整个集合。作为另一种选择,可以考虑SSCAN,它允许您迭代地检索集合的所有成员。

限制

每个集合的最大成员数为 232 - 1(40多亿)。

例子

存储用户 123 和 456 的收藏书 ID 集:

1
2
3
4
5
6
7
sadd user:123:favorites 347
sadd user:123:favorites 561
sadd user:123:favorites 742
sadd user:456:favorites 561

sadd user:456:favorites 99999
srem user:456:favorites 99999

检查用户 123 是否喜欢书籍 742 和 299

1
2
sismember user:123:favorites 742
sismember user:123:favorites 299

用户 123 和 456 有没有共同喜欢的书?

1
sinter user:123:favorites user:456:favorites

用户 123 收藏了多少本书?

1
scard user:123:favorites

Hash(哈希)

Redis hash 是一个键值对集合 (key=>value)。

Redis hash 是一个 string 类型的 field 和 value 的映射表(field=>value对),hash 特别适合用于存储对象

基本命令

请参阅哈希命令的完整列表

  • HSET设置散列上一个或多个字段的值。
  • HGET返回给定字段的值。
  • HMGET返回一个或多个给定字段的值。
  • HINCRBY通过提供的整数,增加给定字段的值。

表现

大多数 Redis 哈希命令的复杂度为 O(1)。

一些命令 - 例如HKEYSHVALSHGETALL- 是 O(n),其中n是字段值对的数量。

限制

每个 hash 可以存储 232 - 1 个 键值对40多亿)。实际上,仅受托管 Redis 部署的 VM 上的总内存的限制。

例子

将用户对象存储为散列

1
2
3
4
del zhangsan
hset zhangsan sno 2022020037 name zhagnsan age 18 sex 1
hget zhangsan sno
hgetall zhangsan

存储设备 777 对服务器执行 ping 操作、发送错误或发出请求的次数的计数器

1
2
3
4
5
6
7
8
del device:777:stats
hincrby device:777:stats pings 1 # key为pings的value加1
hincrby device:777:stats pings 1
hincrby device:777:stats pings 10 # key为pings的value加10

hincrby device:777:stats errors 1 # key为errors的value加1

hincrby device:777:stats requests 1 # key为requests的value加1

zset(sorted set:有序集合)

Redis zset 和 set 一样,也是唯一 string 类型元素的集合。

不同的是,每个元素都会关联一个double类型的分数,通过分数为集合中的成员排序(从大到小)。成员是唯一,分数(score)却可以重复。

当多个字符串具有相同的分数时,字符串按字典顺序排列。zset 的示例:

  • 排行榜。使用排序集轻松维护大型在线游戏中最高分的有序列表。
  • 速率限制器。使用 zset 来构建滑动窗口速率限制器,以防止过多的 API 请求。

基本命令

请参阅排序集命令的完整列表

  • ZADD将新成员和关联的分数添加到已排序的集合中。如果该成员已经存在,则更新分数。
  • ZRANGE返回在给定范围内排序的有序集合的成员。
  • ZRANK返回所提供成员的排名,假设排序是按升序排列。
  • ZREVRANK返回所提供成员的排名,假设排序集按降序排列。

表现

大多数有序集合操作的复杂度为 O(log(n)),其中n是成员数。

ZRANGE运行具有较大返回值(例如,数万或更多)的命令时要小心。此命令的时间复杂度为 O(log(n) + m),其中m是返回的结果数。

备择方案

Redis 排序集有时用于索引其他 Redis 数据结构。如果您需要索引和查询您的数据,请考虑RediSearchRedisJSON

限制

每个集合的最大成员数为 232 - 1(40多亿)。

例子

随着玩家分数的变化更新实时排行榜

1
2
3
4
5
6
7
ZADD leaderboard:455 100 user:1
ZADD leaderboard:455 75 user:2
ZADD leaderboard:455 101 user:3
ZADD leaderboard:455 15 user:4
ZADD leaderboard:455 275 user:2

# 请注意,在最后一次调用user:2中更新了 score 。ZADD

获取前 3 名玩家的分数

1
2
3
4
5
6
7
ZRANGE leaderboard:455 0 2 REV WITHSCORES
1) "user:2"
2) "275"
3) "user:3"
4) "101"
5) "user:1"
6) "100"

用户 2 的排名是多少?

1
2
ZREVRANK leaderboard:455 user:2
(integer) 0