# 一.安装使用

# 1.安装 redis

#进入安装目录
cd /usr/local/

#获取 redis 资源
wget http://download.redis.io/releases/redis-4.0.8.tar.gz

#解压
tar xzvf redis-4.0.8.tar.gz

#进入redis目录
cd redis-4.0.8

#编译
make

#进入目录
cd src

#编译安装
make install PREFIX=/usr/local/redis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2.配置文件

#移动配置文件到安装目录下
mkdir /usr/local/redis/etc

#移动配置文件
mv /usr/local/redis-4.0.8/redis.conf /usr/local/redis/etc

#修改配置文件
vim /usr/local/redis/etc/redis.conf

#以守护进程的模式运行
daemonize no  -->  daemonize yes

#redis.conf配置文件里的bind 127.0.0.1注释掉

#protected-mode 设置为no,关闭远程访问保护
#设置密码
requirepass 123456
protected-mode no

#将redis加入到开机启动
vim /etc/rc.local
#在里面添加内容:(意思就是开机调用这段开启redis的命令)
/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 3.bin 目录

#将redis-cli,redis-server拷贝到bin下,让redis-cli指令可以在任意目录下直接使用
cp /usr/local/redis/bin/redis-server /usr/local/bin/
cp /usr/local/redis/bin/redis-cli /usr/local/bin/

#设置redis密码
redis-cli
config get requirepass
config set requirepass xxx
1
2
3
4
5
6
7
8

# 4.启动 redis

#原路径启动
/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf

#启动redis
redis-server

#加上`&`号使redis以后台程序方式运行
cd /usr/local/redis/bin/
redis-server /usr/local/redis/etc/redis.conf &

#客户端连接redis
redis-cli -h 127.0.0.1 -p 6379
redis-cli -h 127.0.0.1 -p 6379 -a 123456

#退出
ctrl+c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 5.停掉服务

#查询停掉
ps -ef |grep redis

#根据端口号查询
netstat -lntp | grep 6379
ss -nltp

#停掉redis
kill -9 pid
1
2
3
4
5
6
7
8
9

# 6.卸载

#删除安装目录
rm -rf /usr/local/redis

#删除所有redis相关命令脚本
rm -rf /usr/bin/redis-*

#删除redis解压文件夹
rm -rf /root/download/redis-4.0.4
1
2
3
4
5
6
7
8

# 7.redis 客户端工具

  • QuickRedis 是一款 永久免费 的 Redis 可视化管理工具。比较稳定简洁的 redis UI 工具。
  • idea 的 redis 插件
  • AnotherRedisDesktopManager 一款比较稳定简洁的 redis UI 工具。
  • Redis Desktop Manager 一款基于 Qt5 的跨平台 Redis 桌面管理软件,目前已开始收费。
  • Redis Client 是 Redis 客户端的 GUI 工具,使用 Java swt 和 jedis 编写,可以方便开发者浏览 Redis 数据库。该软件支持简体中文,非常适合国内用户使用,不需要汉化就可以直接使用

# 二.系统命令

# 1.info

  • info 命令
  • Info memory 查询内存的情况
> info
# Server
redis_version:4.0.8
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:e857951d47b9ef85
redis_mode:standalone
os:Linux 4.18.0-348.7.1.el8_5.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:8.5.0
process_id:25860
run_id:48b5966b9c1aa0fdb66a3bddee56a1c1028ce457
tcp_port:6379
uptime_in_seconds:661
uptime_in_days:0
hz:10
lru_clock:13393178
executable:/usr/local/redis/bin/redis-server
config_file:/usr/local/redis/etc/redis.conf

# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:827672
used_memory_human:808.27K
used_memory_rss:3641344
used_memory_rss_human:3.47M
used_memory_peak:828720
used_memory_peak_human:809.30K
used_memory_peak_perc:99.87%
used_memory_overhead:815398
used_memory_startup:765664
used_memory_dataset:12274
used_memory_dataset_perc:19.79%
total_system_memory:3755278336
total_system_memory_human:3.50G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:4.40
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1691114117
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:0
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
aof_last_cow_size:0

# Stats
total_connections_received:2
total_commands_processed:20
instantaneous_ops_per_sec:0
total_net_input_bytes:593
total_net_output_bytes:3095
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:10
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Replication
role:master
connected_slaves:0
master_replid:2fe48eb22bdf88e26febf1bd6becc9a0943d6943
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:0.38
used_cpu_user:0.25
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=1,expires=0,avg_ttl=0
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

# 2.全局命令

#查询所有key
keys *

#切换数据库,默认情况下,一个客户端连接到数据库0
select index

#ping指令测试当前数据库是否联通
ping

#move指令将指定名称的key移动到指定数据库索引下的数据库
move key_name db_Index

#dbsize指令查看当前数据库下的key数量
dbsize

#显示redis配置信息
info

#redis 的内存占用
info memory

#清除当前数据库下的所有数据
flushdb

#清除所有库中的数据
flushall

#同步--把数据存储到磁盘
save

#异步--把数据存储到磁盘
bgsave

#上次存储时间key的时间
127.0.0.1:6379> lastsave
(integer) 1691115551

#退出
quit
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

# 3.帮助命令

127.0.0.1:6379> help @string
127.0.0.1:6379> help @list
127.0.0.1:6379> help @hash
127.0.0.1:6379> help @set
1
2
3
4

# 4.显示 value 数据类型

127.0.0.1:6379> set kwan 1234
OK
127.0.0.1:6379> type kwan
string
1
2
3
4

# 5.显示底层编码方式

127.0.0.1:6379> object encoding kwan
"int"
1
2

# 6.过期时间

  • TTL 命令将以秒为单位返回键的剩余生存时间
  • PTTL 命令则会以毫秒为单位返回键的剩余生存时间
  • -1 代表没有设置过期时间
  • -2 代表给定的键不存在
127.0.0.1:6379> ttl kwan
(integer) -1
127.0.0.1:6379> pttl kwan
(integer) -1
127.0.0.1:6379> pttl kwan1
(integer) -2
1
2
3
4
5
6

# 7.查看版本号

#使用info
info

#使用redis-cli
[testuser@vm-11-211-41-22 redis]$ redis-cli -v
redis-cli 4.0.8

#使用redis-cli
[testuser@vm-11-211-41-22 redis]$ redis-cli --version
redis-cli 4.0.8
1
2
3
4
5
6
7
8
9
10

# 8.事务操作

#监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断
watch key

#取消监视一个
unwatch key

#开启事务,事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令在一个原子时间内执行
multi

#执行所有事务块内的命令
exec
1
2
3
4
5
6
7
8
9
10
11
#取消事务,放弃执行事务块内的所有命令。
redis> DISCARD

#开启事务
redis> MULTI
OK

redis> INCR user_id
QUEUED

redis> PING
QUEUED

#执行所有事务块内的命令
redis> EXEC

#取消 WATCH 命令对所有 key 的监视。
redis> UNWATCH

#监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
redis> WATCH lock lock_times
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 9.获取所有参数

#获取所有参数
redis> CONFIG GET *
1) "dir"
2) "/var/lib/redis"
3) "dbfilename"
4) "dump.rdb"
1
2
3
4
5
6

#save 选项在 redis.conf 中是用多行文字储存的,但在 CONFIG GET 命令中,它只打印一行文字。 以下是 save 选项在 redis.conf 文件中的表示:

save 900 1
save 300 10
save 60 10000
1
2
3

但是 CONFIG GET 命令的输出只有一行:

redis> CONFIG GET save
1) "save"
2) "900 1 300 10 60 10000"
1
2
3

上面 save 参数的三个值表示:在 900 秒内最少有 1 个 key 被改动,或者 300 秒内最少有 10 个 key 被改动,又或者 60 秒内最少有 1000 个 key 被改动,以上三个条件随便满足一个,就触发一次保存操作。

# 10.客户端相关

# 列出所有已连接客户端
redis 127.0.0.1:6379> CLIENT LIST
addr=127.0.0.1:43501 fd=5 age=10 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

# 杀死当前客户端的连接
redis 127.0.0.1:6379> CLIENT KILL 127.0.0.1:43501
OK
1
2
3
4
5
6
7

# 11.密码相关

#登录后指定密码
auth  xxxx密码

# 将密码设置为 secret_password
redis> CONFIG SET requirepass secret_password

# 输入正确的密码   secret_password为密码
redis> AUTH secret_password

# 通过将密码设为空字符来清空密码
redis> CONFIG SET requirepass ""
1
2
3
4
5
6
7
8
9
10
11

# 12.脚本

# EVAL 命令对 Lua 脚本进行求值,脚本的原子性
redis> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1
2

# 13.key 相关

#删除key
127.0.0.1:6379> del name
(integer) 1

#序列化key
redis> DUMP greeting

#key是否存在
redis> EXISTS db
(integer) 1

#设置过期时间为 30 秒
redis> EXPIRE cache_page 30

# 这个 key 将在 2012.12.12 过期
redis> EXPIREAT cache 1355292000

# 匹配数据库内所有 key
redis> KEYS *
KEYS *         #匹配数据库中所有 key 。
KEYS h?llo     #匹配 hello , hallo 和 hxllo 等。
KEYS h*llo     #匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo  #匹配 hello 和 hallo ,但不匹配 hillo 。

# 将 song 移动到数据库 1
redis> MOVE song 1

# 字符串的编码方式
redis> OBJECT ENCODING game
"raw"

# 移除 key 的生存时间  变为持久存在的
redis> PERSIST mykey

#到哪里过期
redis> PEXPIREAT mykey 1555555555005

#返回毫秒
redis> PTTL key

#返回秒
redis> TTL key

#随机返回一个key
redis> RANDOMKEY

#改名
#当 key 和 newkey 相同,或者 key 不存在时,返回一个错误。
#当 newkey 已经存在时, RENAME 命令将覆盖旧值。
redis> RENAME message greeting

# newkey 不存在,改名成功
redis> RENAMENX player best_player

#反序列化
redis> RESTORE greeting-again 0 "\x00\x15hello, dumping world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"

#排序
redis> SORT today_cost
redis 127.0.0.1:6379> SORT today_cost DESC

#返回value的类型
redis> TYPE weather
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

# 三.对象命令

# 1.字符串对象命令

常见命令:

  • set :添加键值对
  • setnx :只有在 key 不存在时 设置 key 的值
  • setex :设置键值的同时,设置过期时间,单位秒
  • get :查询对应键值 a
  • getset :以新换旧,设置了新值同时获得旧值
  • append :将给定的追加到原值的末尾
  • strlen :获得值的长度
  • incr :将 key 中储存的数字值增 1(只能对数字值操作,如果为空,新增值为 1)
  • decr :将 key 中储存的数字值减 1(只能对数字值操作,如果为空,新增值为-1)
  • incrby :将 key 中储存的数字值增加步长数值,自定义步长
  • decrby :将 key 中储存的数字值减少步长数值,自定义步长
  • incrbyfloat :将 key 中储存的浮点型数值增加步长数值,自定义步长
  • mset :同时设置一个或多个 key-value 对
  • mget :同时获取一个或多个 value
  • msetnx : 同时设置一个或多个 K-V,当且仅当所有给定 key 都不存在时成功
  • getrange : 获得值的范围,类似 java 中的 substring,包前也包后[闭区间]
  • setrange :用覆写所储存的字符串值,从<起始位置>开始(索引从 0 开始)

特殊指令:

  • NX:当数据库中 key 不存在时,可以将 key-value 添加数据库

  • XX:当数据库中 key 存在时,可以将 key-value 添加数据库,与 NX 参数互斥

  • EX:key 的超时秒数

  • PX:key 的超时毫秒数,与 EX 互斥

# 1.1.set

set 命令的作用是 设置一个 key 的 value 值

127.0.0.1:6379> set key1 value1
OK
1
2

set 命令除了基本的用法外,还有几个参数,先来说一下 nx 和 xx 两个参数。

  • nx 表示 key 不存在时,执行操作

  • xx 表示 Key 存在时,执行操作

127.0.0.1:6379> set k1 v1 nx
OK
127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> set k2 v2 xx
(nil)
127.0.0.1:6379> keys *
1) "k1"
1
2
3
4
5
6
7
8
  • ex 表示 设置的过期时间以秒为单位

  • px 表示 设置的过期时间以毫秒为单位

127.0.0.1:6379> set k2 v2 ex 5
OK
127.0.0.1:6379> ttl k2
(integer) 3
127.0.0.1:6379> ttl k2
(integer) 0
127.0.0.1:6379> ttl k3
(integer) -2
127.0.0.1:6379> set k2 v2 px 5000
OK
1
2
3
4
5
6
7
8
9
10

# 1.2.setnx

setnx 命令的作用是 当指定的键不存在时给该键设置一个值

127.0.0.1:6379> keys *
1) "k1"
2) "key2"
3) "key1"
127.0.0.1:6379> setnx k1 value1
(integer) 0
127.0.0.1:6379> setnx k2 value2
(integer) 1
127.0.0.1:6379> keys *
1) "k1"
2) "key2"
3) "key1"
4) "k2"
1
2
3
4
5
6
7
8
9
10
11
12
13

# 1.3.get


127.0.0.1:6379> keys *
1) "k1"
2) "key2"
3) "key1"
4) "k2"
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> get k2
"value2"
127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> get key2
"value2"
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 1.4.getset

getset 命令的作用是设置一个 key 的 value,并获取设置前的值,该命令相当于 先对指定的 key 进行一次 get 操作,再执行一次 set 操作,两个命令合并,可以保证原子性。

127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> getset k1 11111
"v1"
127.0.0.1:6379> get k1
"11111"
1
2
3
4
5
6

# 1.5.mget

mget 命令的作用是 一次获取多个 key 的值,如果 key 不存在则返回 nil

127.0.0.1:6379> keys *
1) "k1"
2) "key2"
3) "key1"
4) "k2"
127.0.0.1:6379> mget k1 key2 key3
1) "11111"
2) "value2"
3) (nil)
1
2
3
4
5
6
7
8
9

# 1.6.mset

mset 命令的作用是 设置多个 key value

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
1
2
3
4
5
6

# 1.7.msetnx

msetnx 命令的作用是 设置多个 key value,仅当 key 不存在时。

当 k4,k5 存在时,同时设置 k4,k5,k6,则 k6 设置不会成功。

127.0.0.1:6379> msetnx k4 vv4 k5 vv5
(integer) 1
127.0.0.1:6379> mget k4 k5
1) "vv4"
2) "vv5"
127.0.0.1:6379> msetnx k4 v4 k5 v5 k6 v6
(integer) 0
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"
4) "k5"
5) "k4"
127.0.0.1:6379> mget k4 k5
1) "vv4"
2) "vv5"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 1.8.incr

incr 命令的作用是 执行原子加 1 操作

127.0.0.1:6379> set k100 100
OK
127.0.0.1:6379> incr k100
(integer) 101
127.0.0.1:6379> get k100
"101"
1
2
3
4
5
6

# 1.9.decr

decr 命令的作用是 整数原子减 1

127.0.0.1:6379> decr k100
(integer) 100
127.0.0.1:6379> decr k100
(integer) 99
127.0.0.1:6379> get k100
"99"
1
2
3
4
5
6

# 1.10.incrby

incrby 命令的作用是 执行原子增加一个整数

127.0.0.1:6379> incrby k100 100
(integer) 199
127.0.0.1:6379> incrby k100 200
(integer) 399
127.0.0.1:6379> get k100
"399"
1
2
3
4
5
6

# 1.11.decrby

decrby 命令的作用是 原子减指定的整数

127.0.0.1:6379> decrby k100 100
(integer) 299
127.0.0.1:6379> decrby k100 300
(integer) -1
127.0.0.1:6379> get k100
"-1"
1
2
3
4
5
6

# 1.12.incrbyfloat

incrbyfloat 命令的作用是 执行原子增加一个浮点数

127.0.0.1:6379> incrbyfloat k100 0.1
"-0.9"
127.0.0.1:6379> incrbyfloat k100 100.2
"99.3"
127.0.0.1:6379> get k100
"99.3"
1
2
3
4
5
6

# 1.13.setrange

setrange 命令的作用是 修改字符串指定偏移的值。

在 Redis 中,SETRANGE 命令用于更新字符串值的一部分,从指定索引开始。如果指定的索引超过了当前字符串的最大索引,Redis 将在索引超出范围时自动填充零字节('\x00'),然后再进行更新。

这种特性使得 SETRANGE 命令能够动态扩展字符串的长度。如果你在索引位置之前的字符串中有数据,Redis 将保留该数据,并在必要时自动填充零字节。

127.0.0.1:6379> set kstr hello
OK
127.0.0.1:6379> setrange kstr 1 a
(integer) 5
127.0.0.1:6379> get kstr
"hallo"
127.0.0.1:6379> setrange kstr 6 x
(integer) 7
127.0.0.1:6379> get kstr
"hallo\x00x"
127.0.0.1:6379> setrange kstr 0 123
(integer) 7
127.0.0.1:6379> get kstr
"123lo\x00x"
127.0.0.1:6379> setrange kstr 5 k
(integer) 7
127.0.0.1:6379> get kstr
"123lokx"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 1.14.getrange

getrange 命令的作用是 获取存储在 key 上的值的一个子字符串

127.0.0.1:6379> get kstr
"123lokx"
127.0.0.1:6379> getrange kstr 1 2
"23"
127.0.0.1:6379> getrange kstr 0 -1
"123lokx"
127.0.0.1:6379> getrange kstr 0 -2
"123lok"
127.0.0.1:6379> getrange kstr 3 5
"lok"
1
2
3
4
5
6
7
8
9
10

# 1.15.append

append 命令的作用是 追加一个值到 key 上

127.0.0.1:6379> append kstr 1234
(integer) 11
127.0.0.1:6379> get kstr
"123lokx1234"
127.0.0.1:6379> append kstr 4321
(integer) 15
127.0.0.1:6379> get kstr
"123lokx12344321"
1
2
3
4
5
6
7
8

# 1.16.BITCOUNT

BITCOUNT 是 Redis 中用于计算字符串值中位设置为 1 的比特数的命令。它可以用于计算字符串的二进制表示中有多少个 1。

127.0.0.1:6379> BITCOUNT kwan
(integer) 13
1
2

# 1.17.strlen

显示 key 对应值的长度

127.0.0.1:6379> strlen kwan
(integer) 4
1
2

# 2.列表对象命令

# 2.1.lpush

添加元素到列表的左端

> lpush dianqi 风扇 电视 洗衣机 冰箱
4
1
2

image-20220922160218500

# 2.2.rpush

添加元素到列表右端

> rpush dianqi 键盘
5
1
2

image-20220922160558709

# 2.3.LPUSHX、RPUSHX

只对已存在的列表执行推入操作

当用户调用 LPUSH 命令或 RPUSH 命令尝试将元素推入列表的时候,如果给定的列表并不存在,那么命令将自动创建一个空列表,并将元素推入刚刚创建的列表中。

  • LPUSHX 命令只会在列表已经存在的情况下,将元素推入列表左端
  • RPUSHX 命令只会在列表已经存在的情况下,将元素推入列表右端。
  • 未成功返回 0

# 2.4.lpop

弹出列表最左端的元素

用户可以通过 LPOP 命令移除位于列表最左端的元素,并将被移除的元素返回给用户。

> lpop dianqi
冰箱

> lpop dianqi 3    弹出3个元素
冰箱
洗衣机
电视
1
2
3
4
5
6
7

# 2.5.rpop

弹出列表最右端的元素 用户可以通过 RPOP 命令移除位于列表最右端的元素,并将被移除的元素返回给用户。

> rpop dianqi
键盘

> rpop dianqi 2
键盘
风扇
1
2
3
4
5
6

# 2.6.rpoplpush

将右端弹出的元素推入左端,需要提供 2 个列表,一个是取出,一个是插入。 RPOPLPUSH 命令的行为和它的名字一样,首先使用 RPOP 命令将源列表最右端的元素弹出,然后使用 LPUSH 命令将被弹出的元素推入目标列表左端,使之成为目标列表的最左端元素。

返回弹出的元素作为结果

> rpoplpush list1 list2
a

> rpoplpush dianqi dianqi
风扇
1
2
3
4
5

# 2.7.llen

返回列表的长度,列表元素个数

> llen dianqi
3
1
2

# 2.8.lindex

获取指定索引上的元素

  • 正数从左到右从 0 开始
  • 负数从右到左,从-1 开始
  • 它的正数索引必然大于等于 0,并且小于等于 N-1。
  • 它的负数索引必然小于等于-1,并且大于等于-N。
  • 如果是倒序,则左边第一个的 index 为-lenth

image-20220922162219820

> lindex dianqi 0
风扇
> lindex dianqi -2
洗衣机
> lindex dianqi -3
风扇
> lindex dianqi -5
null
1
2
3
4
5
6
7
8

# 2.9.lrange

查询全部的数据

  • 0 是正向开始

  • -1 是逆向开始

> lrange dianqi 0 -1
风扇
洗衣机
电视
1
2
3
4

# 2.10.lset

为指定索引设置新元素,用户可以通过 LSET 命令,为列表的指定索引设置新元素。

> lset dianqi 2 抽烟机
OK
> lrange dianqi 0 -1
风扇
洗衣机
抽烟机
1
2
3
4
5
6

# 2.11.linsert

将元素插入列表,通过使用 LINSERT 命令,用户可以将一个新元素插入列表某个指定元素的前面或者后面。

  • before

  • after

> linsert dianqi before 洗衣机 电视机
4
> lrange dianqi 0 -1
风扇
电视机
洗衣机
抽烟机
1
2
3
4
5
6
7

# 2.12.ltrim

截取指定区域的元素,双闭区间。

> lrange dianqi 0 -1
风扇
电视机
洗衣机
抽烟机
> ltrim dianqi 0 2
OK
> lrange dianqi 0 -1
风扇
电视机
洗衣机
1
2
3
4
5
6
7
8
9
10
11

# 2.13.lrem

移除指定元素,根据 count 不同,功能不同

  • 等于 0,移除所有等于指定元素的元素;
  • 大于 0,从左往右开始删除,删除的个数为 count
  • 小于 0,从右往左开始删除,删除的个数为 count 的绝对值
> lrem dianqi 0 风扇
1
> lrange dianqi 0 -1
电视机
洗衣机
1
2
3
4
5

# 2.14.blpop

阻塞式左侧弹出,带一个秒级的超时时间

> blpop dianqi 5
dianqi
洗衣机
1
2
3

# 2.15.brpop

阻塞式右侧弹出,带一个秒级的超时时间

> brpop dianqi 5
dianqi
洗衣机
1
2
3

# 2.16 BRPOPLPUSH

阻塞式弹出并推入操作,BRPOPLPUSH 命令是 RPOPLPUSH 命令的阻塞版本,BRPOPLPUSH 命令接受一个源列表、一个目标列表以及一个秒级精度的超时时限作为参数。

> brpoplpush dianqi 5
dianqi
洗衣机
1
2
3

# 2.17.列表对象命令汇总

//从list头部插入一个值。
$ret = $redis->lPush('city', 'guangzhou');
//从list尾部插入一个值。
$ret = $redis->rPush('city', 'guangzhou');
//获取列表指定区间中的元素。0表示列表第一个元素,-1表示最后一个元素,-2表示倒数第二个元素。
$ret = $redis->lrange('city', 0, -1);//查看队列所有元素
//将一个插入已存在的列表头部,列表不存在时操作无效。
$ret = $redis->lPushx('city', 'hangzhou');
//将一个或多个值插入已存在的列表尾部,列表不存在时操作无效。
$ret = $redis->rPushx('city', 'hangzhou');
//移除并返回列表的第一个元素,若key不存在或不是列表则返回false。
$ret = $redis->lPop('city');
//移除并返回列表的最后一个元素,若key不存在或不是列表则返回false。
$ret = $redis->rPop('city');
//移除并获取列表的第一个元素。如果列表没有元素则会阻塞列表直到等待超时或发现可弹出元素为止。
//参数:key,超时时间(单位:秒)
//返回值:[0=>key,1=>value],超时返回[]
$ret = $redis->blPop('city', 10);
//移除并获取列表的最后一个元素。如果列表没有元素则会阻塞列表直到等待超时或发现可弹出元素为止。
//参数:key,超时时间(单位:秒)
//返回值:[0=>key,1=>value],超时返回[]
$ret = $redis->brPop('city', 10);
//移除列表中最后一个元素,将其插入另一个列表头部,并返回这个元素。若源列表没有元素则返回false。
$ret = $redis->rpoplpush('city', 'city2');
//移除列表中最后一个元素,将其插入另一个列表头部,并返回这个元素。如果列表没有元素则会阻塞列表直到等待超时或发现可弹出元素为止。
//参数:源列表,目标列表,超时时间(单位:秒)
//超时返回false
$ret = $redis->brpoplpush('city', 'city2', 10);
//返回列表长度。
$ret = $redis->lLen('city');
//通过索引获取列表中的元素。若索引超出列表范围则返回false。
$ret = $redis->lindex('city', 0);
//通过索引设置列表中元素的值。若是索引超出范围,或对一个空列表进行lset操作,则返回false。
$ret = $redis->lSet('city', 2, 'changsha');
//在列表中指定元素前或后面插入元素。若指定元素不在列表中,或列表不存在时,不执行任何操作。
//参数:列表key,Redis::AFTER或Redis::BEFORE,基准元素,插入元素
//返回值:插入成功返回插入后列表元素个数,若基准元素不存在返回-1,若key不存在返回0,若key不是列表返回false。
$ret = $redis->lInsert('city', Redis::AFTER, 'changsha', 'nanjing');
//根据第三个参数count的值,移除列表中与参数value相等的元素。
//count > 0 : 从表头开始向表尾搜索,移除与value相等的元素,数量为count。
//count < 0 : 从表尾开始向表头搜索,移除与value相等的元素,数量为count的绝对值。
//count = 0 : 移除表中所有与value相等的值。
//返回实际删除元素个数
$ret = $redis->lrem('city', 'guangzhou', -2);
//对一个列表进行修剪,只保留指定区间的元素,其他元素都删除。成功返回true。
$ret = $redis->ltrim('city', 1, 4);
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

# 3.hash 对象命令

# 3.1.hset

  • 向 hash 表中插入属性,可以同时插入多个值 hmset 已经弃用
  • key 中的冒号,表示 key 的层级
> hset user:qyj  name 秦英杰
1
> hset dipu  name 秦英杰
1
1
2
3
4

image-20220923181543520

# 3.2.hget

获取哈希属性

> hget dipu  name
秦英杰
1
2

# 3.3.hexists

哈希属性是否存在

hexists dipu age
1
1
2

# 3.4.hkeys

列出所有属性

> hkeys dipu
name
age
身高
体重
1
2
3
4
5

# 3.5.hvals

列出所有属性的值

> hvals dipu
秦英杰
18
178
85
1
2
3
4
5

# 3.6.hincrby

属性值自增,自定义步幅

> hincrby dipu age 2
20
1
2

# 3.6.hsetnx

当且仅当 key 不存在时,插入成功

> hsetnx dipu name 大顶堆
0
> hvals dipu
秦英杰
20
178
85
1
2
3
4
5
6
7

# 3.7.hash 命令总结

命令 描述
hset 集合中的 键赋值
hget 从 key1 中取出指定的 field 对应的 value
hmset 批量插入 key1 的 filed-value 对(已废弃)
hexists 查看哈希表 key 中,给定的 field 是否存在
hkeys 列出该 key 的所有 field
hvals 列出该 hash 集合的所有 value
hincrbu 为哈希表 key 中的域 field 的值加上
hsetnx 给哈希表 key 添加 field-value 对,当且仅当域 field 不存在

# 4.集合对象

# 4.1.sadd

添加一个或者多个元素到集合里

127.0.0.1:6379> sadd lang java c++
(integer) 2
1
2

# 4.2.scard

获取集合中的元素个数

127.0.0.1:6379> scard lang
(integer) 2
1
2

# 4.3.sismember

判断一个值是否在指定的集合中

127.0.0.1:6379> sismember lang java
(integer) 1
127.0.0.1:6379> sismember lang python
(integer) 0
1
2
3
4

# 4.4.smembers

获取指定集合中的所有元素

127.0.0.1:6379> smembers lang
1) "java"
2) "c++"
1
2
3

# 4.5.smove

移动集合中的一个元素到另外一个集合中

127.0.0.1:6379> smove lang otherlang c++
(integer) 1
127.0.0.1:6379> smembers otherlang
1) "c++"
1
2
3
4

# 4.6.spop

返回指定集合中的一个元素,并删除,1 是个数

127.0.0.1:6379> spop lang 1
1) "scala"
1
2

# 4.7.srandmember

从集合中随机返回若干元素,它的指令格式和 spop 类似,它只返回元素而不从集合中删除

127.0.0.1:6379> srandmember lang 1
1) "lua"
127.0.0.1:6379> srandmember lang 2
1) "lua"
2) "c++"
127.0.0.1:6379> srandmember lang 5
1) "ruby"
2) "php"
3) "c++"
4) "python"
5) "lua"
1
2
3
4
5
6
7
8
9
10
11

# 4.8.srem

从集合中删除一个或多个元素

127.0.0.1:6379> srandmember lang 1
1) "java"
127.0.0.1:6379> srem lang java
(integer) 1
127.0.0.1:6379> srem lang c++ python
(integer) 2
127.0.0.1:6379> smembers lang
1) "ruby"
2) "php"
3) "asm"
4) "lua"
1
2
3
4
5
6
7
8
9
10
11

# 4.9.sinter

获得两个集合的交集

127.0.0.1:6379> sinter zhangsan lisi
1) "java"
2) "python"
1
2
3

# 4.10.sunion

获得两个集合的并集

127.0.0.1:6379> sunion zhangsan lisi
1) "c"
2) "ruby"
3) "java"
4) "php"
5) "c++"
6) "python"
1
2
3
4
5
6
7

# 4.11.sdiff

获取两个集合的差集

127.0.0.1:6379> sdiff zhangsan lisi
1) "ruby"
2) "c++"
1
2
3

# 4.12.sinterstore

获取两个集合的交集,并将结果保存到一个 key 中

127.0.0.1:6379> sinterstore result zhangsan lisi
(integer) 2
127.0.0.1:6379> smembers result
1) "java"
2) "python"
1
2
3
4
5

# 4.13.集合命令汇总

命令 描述 时间复杂度
SAdd 添加一个或多个元素到集合中 O(N)
SMembers 返回集合的所有元素 O(N)
SRem 删除集合中指定的元素 O(N)
SCard 返回集合元素的数量 O(1)
SRandMember 从集合中随机返回一个或多个元素 O(N)-O(N)
SMove 中 把一个集合的元素移动到另外一个集合 O(1)
SPop 从集合中随机返回(并删除)一个或多个元素 O(1)
SIsMember 集合成员是否存在判断 O(1)
SScan 增量叠代式返回集合中的元素 O(1)-O(N)

# 5.有序集合对象

# 5.1.zadd

添加元素

> zadd xueke 1 redis
1
> zadd xueke 2 java
1
> zadd xueke xx 2 java   #修改已经存在的java的分数,只会修改已存在
1
> zadd xueke nx 2 java   #只会添加新元素
1
> zadd xueke ch 2 java   #返回修改成员的数量和新增的数量
1
1
2
3
4
5
6
7
8
9
10

image-20220923161128024

# 5.2.zrange

从表头遍历,展示元素

withscores 带分数输出

> zrange xueke 0 2
redis
java

> zrange xueke 0 -1 withscores
redis
1
java
2
math
5
1
2
3
4
5
6
7
8
9
10
11

# 5.3.zrevrange

从表尾遍历,展示元素

withscores 带分数输出

> zrevrange xueke 0  -1
math
java
redis
> zrevrange xueke 0 -1 withscores
math
5
java
2
redis
1
1
2
3
4
5
6
7
8
9
10
11

# 5.4.zcard

获取成员个数

> zcard xueke
2
1
2

# 5.5.zcount

指定分数区间的成员个数

> zcount xueke 0 1
1
> zcount xueke 0 2
2
1
2
3
4

# 5.6.zincrby

指定成员加分数,自增操作

> zincrby xueke 1 java
3
1
2

# 5.7.zrank

从头遍历,返回元素的索引位置

> zrank xueke java
1
1
2

# 5.8.zrevrank

从尾遍历,返回元素的索引位置

> zrevrank xueke java
1
1
2

# 5.9.zrem

删除元素

> zrem xueke java
1
1
2

# 5.10.zscore

返回成员分数

> zscore xueke redis
1
1
2

# 5.11.zrangebyscore

  • zrangebyscore sorted_set min max: 获取分数在[min,max]内的成员

  • zrevrangebyscore sorted_set max min: 获取分数在[max,min]内的成员

  • min 参数和 max 参数分别用于指定用户想要获取的成员的最小分值和最大分值

> zrangebyscore xueke 1 2
1
> zrangebyscore xueke -inf +inf withscores  #无分数限制的展示成员
redis
1
java
2
math
5
1
2
3
4
5
6
7
8
9

# 5.12.zremrangebyrank

zremrangebyrank sorted_set start end:从升序排列的有序集合中移除位于指定排名范围内的成员,然后返回被移除成员的数量

> zremrangebyrank xueke 0 1
2
1
2

# 5.13.zremrangebyscore

zremrangebyscore sorted_set min max:从有序集合中移除位于指定分值范围内的成员,并在移除操作执行完毕返回被移除成员的数量

> zremrangebyscore xueke 0 1
2
1
2

# 5.14.zpopmax

zpopmax/zpopmin

  • zpopmax sorted_set [count]:移除并返回有序集合中分值最大和最小的 N 个元素
  • zpopmin sorted_set [count]:移除并返回有序集合中分值最小和最小的 N 个元素
> zpopmax xueke
2
1
2

# 5.15.有序集合对象示例

127.0.0.1:6379> ZADD price 8.5 apple 5.0 banana 6.0 cherry
(integer) 1
127.0.0.1:6379> zcard price
(integer) 3
127.0.0.1:6379> ZADD myset 2 "world" 3 "bar"
(integer) 2
127.0.0.1:6379> zrange price 0 10 WITHSCORES
1) "banana"
2) "5"
3) "cherry"
4) "6"
5) "apple"
6) "8.5"
1
2
3
4
5
6
7
8
9
10
11
12
13

# 5.16.有序集合命令

命令 描述
ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZCARD key 获取有序集合的成员数
ZCOUNT key min max 计算在有序集合中指定区间分数的成员数
ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment
ZINTERSTORE destination numkeys key [key ...] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 destination 中
ZLEXCOUNT key min max 在有序集合中计算指定字典区间内成员数量
ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合指定区间内的成员
ZRANGEBYLEX key min max [LIMIT offset count] 通过字典区间返回有序集合的成员
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员
ZRANK key member 返回有序集合中指定成员的索引
ZREM key member [member ...] 移除有序集合中的一个或多个成员
ZREMRANGEBYLEX key min max 移除有序集合中给定的字典区间的所有成员
ZREMRANGEBYRANK key start stop 移除有序集合中给定的排名区间的所有成员
ZREMRANGEBYSCORE key min max 移除有序集合中给定的分数区间的所有成员
ZREVRANGE key start stop [WITHSCORES] 返回有序集中指定区间内的成员,通过索引,分数从高到低
ZREVRANGEBYSCORE key max min [WITHSCORES] 返回有序集中指定分数区间内的成员,分数从高到低排序
ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减 (从大到小) 排序
ZSCORE key member 返回有序集中,成员的分数值
ZUNIONSTORE destination numkeys key [key ...] 计算给定的一个或多个有序集的并集,并存储在新的 key 中
ZSCAN key cursor [MATCH pattern] [COUNT count] 迭代有序集合中的元素(包括元素成员和元素分值)

# 四.API

# 1.SDS API?

函数名称 作用 复杂度
sdsempty 创建一个只包含空字符串”” 的 sds O(N)
sdsnew 根据给定的 C 字符串,创建一个相应的 sds O(N)
sdsnewlen 创建一个指定长度的 sds,接受一个指定的 C 字符串作为初始化值 O(N)
sdsdup 复制给定的 sds O(N)
sdsfree 释放给定的 sds O(1)
sdsupdatelen 更新给定 sds 所对应的 sdshdr 的 free 与 len 值 O(1)
sdsMakeRoomFor 对给定 sds 对应 sdshdr 的 buf 进行扩展 O(N)
sdscatlen 将一个 C 字符串追加到给定的 sds 对应 sdshdr 的 buf O(N)
sdscpylen 将一个 C 字符串复制到 sds 中,需要依据 sds 的总长度来判断是否需要扩展 O(N)
sdscatprintf 通过格式化输出形式,来追加到给定的 sds O(N)
sdstrim 对给定 sds,删除前端 / 后端在给定的 C 字符串中的字符 O(N)
sdsrange 截取给定 sds,[start,end] 字符串 O(N)
sdscmp 比较两个 sds 的大小 O(N)
sdssplitlen 对给定的字符串 s 按照给定的 sep 分隔字符串来进行切割 O(N)

# 2.集合和链表 API

函数 作用 时间复杂度
listSetDupMethod 将给定的函数设置为链表的节点值复制函数 O(1)
listGetDupMethod 返回链表当前正在使用的节点值复制函数。 复制函数可以通过链表的 dup 属性直接获得 O(1)
listSetFreeMethod 将给定的函数设置为链表的节点值释放函数 O(1)
listGetFree 返回链表当前正在使用的节点值释放函数。 释放函数可以通过链表的 free 属性直接获得 O(1)
listSetMatchMethod 将给定的函数设置为链表的节点值对比函数 O(1)
listGetMatchMethod 返回链表当前正在使用的节点值对比函数。 对比函数可以通过链表的 match 属性直接获得 O(1)
listLength 返回链表的长度(包含了多少个节点)。 链表长度可以通过链表的 len 属性直接获得 O(1)
listFirst 返回链表的表头节点。 表头节点可以通过链表的 head 属性直接获得 O(1)
listLast 返回链表的表尾节点。 表尾节点可以通过链表的 tail 属性直接获得 O(1)
listPrevNode 返回给定节点的前置节点。 前置节点可以通过节点的 prev 属性直接获得 O(1)
listNextNode 返回给定节点的后置节点。 后置节点可以通过节点的 next 属性直接获得 O(1)
listNodeValue 返回给定节点目前正在保存的值。 节点值可以通过节点的 value 属性直接获得 O(1)
listCreate 创建一个不包含任何节点的新链表 O(1)
listAddNodeHead 将一个包含给定值的新节点添加到给定链表的表头 O(1)
listAddNodeTail 将一个包含给定值的新节点添加到给定链表的表尾 O(1)
listInsertNode 将一个包含给定值的新节点添加到给定节点的之前或者之后 O(1)
listSearchKey 查找并返回链表中包含给定值的节点 O(N) , N 为链表长度。
listIndex 返回链表在给定索引上的节点 O(N) , N 为链表长度。
listDelNode 从链表中删除给定节点 O(1)
listRotate 将链表的表尾节点弹出,然后将被弹出的节点插入到链表的表头, 成为新的表头节点 O(1)
listDup 复制一个给定链表的副本 O(N) , N 为链表长度。
listRelease 释放给定链表,以及链表中的所有节点 O(N) , N 为链表长度。

# 3.整数集合 API

函数 作用 时间复杂度
intsetNew 创建一个新的整数集合。 O(1)
intsetAdd 将给定元素添加到整数集合里面。 O(N) O(N)
intsetRemove 从整数集合中移除给定元素。 O(N) O(N)
intsetFind 检查给定值是否存在于集合。 因为底层数组有序,查找可以通过二分查找法来进行 O(log N)
intsetRandom 从整数集合中随机返回一个元素。 O(1) O(1)
intsetGet 取出底层数组在给定索引上的元素。 O(1) O(1)
intsetLen 返回整数集合包含的元素个数。 O(1) O(1)
intsetBlobLen 返回整数集合占用的内存字节数。 O(1) O(1)

# 4.跳跃表 API

函数 作用 时间复杂度
zslCreate 创建一个新的跳跃表 O(1)
zslFree 释放给定跳跃表,以及表中包含的所有节点 O(N) , N 为被删除节点数量。
zslInsert 将包含给定成员和分值的新节点添加到跳跃表中 平均 O(\log N) ,最坏 O(N) , N 为跳跃表长度。
zslDelete 删除跳跃表中包含给定成员和分值的节点 平均 O(\log N) ,最坏 O(N) , N 为跳跃表长度。
zslGetRank 返回包含给定成员和分值的节点在跳跃表中的排位 平均 O(\log N) ,最坏 O(N) , N 为跳跃表长度。
zslGetElementByRank 返回跳跃表在给定排位上的节点 平均 O(\log N) ,最坏 O(N) , N 为跳跃表长度。
zslIsInRange 给定一个分值范围(range), 比如 0 到 15 , 20 到 28 ,诸如此类, 如果给定的分值范围包含在跳跃表的分值范围之内, 那么返回 1 ,否则返回 0 。 O(1)
zslFirstInRange 给定一个分值范围, 返回跳跃表中第一个符合这个范围的节点。 平均 O(\log N) ,最坏 O(N) 。 N 为跳跃表长度。
zslLastInRange 给定一个分值范围, 返回跳跃表中最后一个符合这个范围的节点 平均 O(\log N) ,最坏 O(N) 。 N 为跳跃表长度。
zslDeleteRangeByScore 给定一个分值范围, 删除跳跃表中所有在这个范围之内的节点 O(N) , N 为被删除节点数量。
zslDeleteRangeByRank 给定一个排位范围, 删除跳跃表中所有在这个范围之内的节点。 O(N) , N 为被删除节点数量。

# 5.压缩列表 API

函数 作用 时间复杂度
ziplistNew 创建一个新的压缩列表 O(1)
ziplistPush 创建一个包含给定值的新节点, 并将这个新节点添加到压缩列表的表头或者表尾 平均 O(N) ,最坏 O(N^2^)
ziplistInsert 将包含给定值的新节点插入到给定节点之后 平均 O(N) ,最坏 O(N^2^)
ziplistIndex 返回压缩列表给定索引上的节点 O(N)
ziplistFind 在压缩列表中查找并返回包含了给定值的节点。 因为节点的值可能是一个字节数组 检查节点值和给定值是否相同的复杂度为 O(N) , 而查找整个列表的复杂度则为 O(N^2^)
ziplistNext 返回给定节点的下一个节点 O(1)
ziplistPrev 返回给定节点的前一个节点 O(1)
ziplistGet 获取给定节点所保存的值 O(1)
ziplistDelete 从压缩列表中删除给定的节点 平均 O(N) ,最坏 O(N^2^)
ziplistDeleteRange 删除压缩列表在给定索引上的连续多个节点 平均 O(N) ,最坏 O(N^2^)
ziplistBlobLen 返回压缩列表目前占用的内存字节数 O(1)
ziplistLen 返回压缩列表目前包含的节点数量 节点数量小于 65535 时 O(1) , 大于 65535 时 O(N)

# 五.开发问题

# 1.hasKey

hasKey 可能存在为 null 的情况,需要包装一下

 Object backListToken = Objects.equals(redisService.hasKey(redisKey), Boolean.TRUE) ? redisService.opsForValue().get(redisKey) : null;
1

# 2.模糊查询

 public Long delByPrefix(final String prefixKey) {
        log.info("模糊查询前缀={}", prefixKey);
        Jedis jedis = jedisUtils.getJedis();
        final Set<String> keys;
        try {
            keys = jedis.keys(prefixKey + "*");
            log.info("模糊查询前缀={}", CollectionUtils.isNotEmpty(keys) ? JSONArray.toJSONString(keys) : null);
            if (CollectionUtils.isNotEmpty(keys)) {
                for (String key : keys) {
                    jedis.del(key);
                }
                return (long) keys.size();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedisUtils.close(jedis);
        }
        return null;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 3.NOAUTH

使用 client-cli 登录后,执行命令提示(error)NOAUTH Authentication required 解决方式:

auth '这里是你的密码'
1

# 4.设置从节点个数

意思是 在主从环境中如果你的从节点的数量少于 1 个或者从服务器的数量大于 1 个但是延时超过 10 秒的时候,主节点将不能写入数据

#在客户端的命令行执行如下命令
set min-slaves-to-write 1
set  min-slaves-max-lag 10
1
2
3

# 六.springboot 集成

# 1.yaml 配置

spring:
  redis:
    database: 3
    password: xxxx
    timeout: 60000 #连接超时
    host: 10.xxx.14.40
    port: 6379
    jedis:
      pool:
        max-idle: 6 #最大空闲数
        max-active: 100 #最大连接数
        min-idle: 2 #最小空闲数
1
2
3
4
5
6
7
8
9
10
11
12

# 2.JedisConfig

@Slf4j
@Configuration
public class JedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private Integer timeout;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.database}")
    private Integer database;

    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxActive;

    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Bean
    public JedisPool jedisPool() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);
        jedisPoolConfig.setMaxTotal(maxActive);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, "default", password, database);
        log.info("JedisPool Connection Success:" + host + "\t" + port);
        return jedisPool;
    }


}
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

# 3.JedisClient

@Component
public class JedisUtils {

    @Autowired
    private JedisPool jedisPool;

    /**
     * 获取Jedis资源
     */
    public Jedis getJedis() {
        return jedisPool.getResource();
    }

    /**
     * 释放Jedis连接
     */
    public void close(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Slf4j
@Component
public class JedisClient {

    @Autowired
    private JedisUtils jedisUtils;

    /**
     * 根据key 查询value值
     */
    public String get(String key) {
        Jedis jedis = jedisUtils.getJedis();
        try {
            if (!jedis.exists(key)) {
                log.info("key:{}在redis中查不到数据.", key);
            } else {
                return jedis.get(key);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedisUtils.close(jedis);
        }
        return null;
    }

    /**
     * 设置数据结果
     *
     * @Author cxf
     * @Date 2022/9/5 15:06
     */
    public String set(String key, String val) {
        Jedis jedis = jedisUtils.getJedis();
        try {
            return jedis.set(key, val);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedisUtils.close(jedis);
        }
        return null;
    }


    /**
     * 带过期时间的key-value
     *
     * @param key
     * @param val
     * @param expTime 单位秒
     * @return
     */
    public String set(String key, String val, int expTime) {
        Jedis jedis = jedisUtils.getJedis();
        try {
            return jedis.setex(key, expTime, val);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedisUtils.close(jedis);
        }
        return null;
    }

    /**
     * 常数级别获取字符串长度 (redis SDS 特性)
     *
     * @param key
     * @return
     */
    public Long length(String key) {
        Jedis jedis = jedisUtils.getJedis();
        try {
            return jedis.strlen(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放资源
            jedisUtils.close(jedis);
        }
        return null;
    }

    /**
     * 删除指定前缀key
     *
     * @param prefixKey
     * @return
     */
    public Long delByPrefix(final String prefixKey) {
        log.info("模糊查询前缀={}", prefixKey);
        Jedis jedis = jedisUtils.getJedis();
        final Set<String> keys;
        try {
            keys = jedis.keys(prefixKey + "*");
            log.info("模糊查询前缀={}", CollectionUtils.isNotEmpty(keys) ? JSONArray.toJSONString(keys) : null);
            if (CollectionUtils.isNotEmpty(keys)) {
                for (String key : keys) {
                    jedis.del(key);
                }
                return (long) keys.size();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedisUtils.close(jedis);
        }
        return null;
    }

    /**
     * 删除指定key
     *
     * @param key
     * @return
     */
    public Long deleteKey(String key) {
        Jedis jedis = jedisUtils.getJedis();
        try {
            return jedis.del(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedisUtils.close(jedis);
        }
        return null;
    }
}
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

# 4.RedisClient

@Component
public class BelleRedisClient {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public String get(final String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 写入缓存
     */
    public boolean set(final String key, String value) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 写入缓存,并设置过期时间
     *
     * @param key
     * @param value
     * @param timeout
     * @param unit
     * @return
     */
    public boolean set(final String key, String value, long timeout, TimeUnit unit) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().set(key, value, timeout, unit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 更新缓存
     */
    public boolean getAndSet(final String key, String value) {
        boolean result = false;
        try {
            redisTemplate.opsForValue().getAndSet(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 删除缓存
     */
    public boolean delete(final String key) {
        boolean result = false;
        try {
            redisTemplate.delete(key);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
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

# 七.主从配置

# 1.主节点配置

redis_master.conf
bind 0.0.0.0
port 6379
daemonize yes
pidfile "/data/redis/data/redis_6379.pid"
logfile "/data/redis/logs/redis_6379.log"
dir "/data/redis/data/redis_6379"
masterauth redis密码
requirepass redis密码
appendonly yes
loadmodule /opt//redis-6.0.5/modules/redisgraph.so
min-replicas-to-write 1
min-replicas-max-lag 10
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2.从节点配置

redis_slave1.conf
bind 0.0.0.0
port 6379
daemonize yes
pidfile "/data/redis/data/redis_6379.pid"
logfile "/data/redis/logs/redis_6379.log"
dir "/data/redis/data/redis_6379"
masterauth redis密码
requirepass redis密码
appendonly yes
loadmodule /opt//redis-6.0.5/modules/redisgraph.so
min-replicas-to-write 1
min-replicas-max-lag 10
replicaof master_ip 6379
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 3.启动命令

/opt/redis-6.0.5/src/redis-server /opt/redis-6.0.5/conf/redis_slave1.conf
1

# 4.查看配置信息

info
1
上次更新: 10/29/2024, 10:27:50 AM