redis

redis

参考 redis常用命令

一些记忆方法

  1. 一般只有有序的东西,才会用del命令,无序的就用rem
  2. 有序的才用range,如zrange,xrange,lrange
  3. 字符串的大部分命令,前面加上h就是hash的命令了

对所有类型生效命令

flushall

  • 删除所有键值对
  • 即删除redis中的所有内容

字符串

set

  • set key value
  • 设置一个键值对
  • 由于key不可以重复,我们可以对一个key设置多次来覆盖之前的值

get

  • get key
  • 根据key找到对应的value

exists

  • exists key
  • 判断key是否存在

keys

  • key 匹配字符串
  • 根据匹配字符串查找对应的key
  • 如果要查找现在有的所有key
  • 可以使用
  • keys *

del

  • del key
  • 删除某个key

expire

  • expire key time(second)
  • 设置某个键的过期时间
  • expire也是过期的意思

ttl

  • ttl key
  • 查看某个键的过期时间
  • ttl是 time to live的缩写

persist

  • persist key
  • 取消某个键的过期时间
  • persist也是持久的意思

setex

  • set key second value
  • 设置某个键,并且顺带设置键的过期时间
  • setex是set 和expire命令的合体 set ex

setnx

  • setnx key value
  • 当某个键不存在时,才创建这个键
  • setnx是 set+no exists ,即set when no exists

列表

lpush

  • lpush key value1 value2 value3
  • 从左边添加一个元素或多个元素

rpush

  • rpush key value value2 value3
  • 从右边添加一个或多个元素

lrange

  • lrange key start stop
  • 从左到右输出列表中的元素,并且从start开始stop结束,stop可以从右边数起,即可以为-1,-2
  • 实例
  • lrange letter 0 -1
  • 从0位置开始输出,-1位置结束
  • 注意,没有rrange
  • 没有从右往左输出
  • 其实他的意思为list range

lpop

  • lpop key [number]
  • 从左边开始pop一个列表中的数据,
  • 也可以指定number,来指定pop出几个元素

rpop

  • rpop key [number]
  • 从右边开始pop一个列表中的数据
  • 同样的,也可以指定number 来pop多个数据

llen

  • llen key
  • 查看列表的长度

ltrim

  • ltrim key start stop
  • 修剪列表,只保留start和stop范围内的数据

集合

sadd

  • sadd key member [member…]
  • 向集合中添加一个或多个元素,
  • sadd意为 set add

srem

  • srem key member [member…]
  • 在集合中删除一个或多个成员
  • 意为 set remove

smember

  • smembers key
  • 查看集合中的 成员

sismember

  • sismembers key member
  • 查看该成员是不是集合中的成员
  • 注意
  • 相较于smembers,这个命令不仅多了is ,还少了末尾的s

sinner

sunion

sdiff

有序集合(zset,sortedSet)

  1. 定义
    1. 他和set的区别是
    2. 他的每个元素都会关联一个浮点类型的分数,然后按照从小到大排序,元素是不能重复的,但是分数是可以重复的

zadd

  • zadd key [score member] [socre member…]
  • 可以向一个zset里面添加一个或多个成员,每个成员前面需要关联一个分数,
  • zadd result 100 数学 98 英语 70 语文

zrange

  • zrange key start stop [withscores]
  • 类似list的操作,只不过拥有了zset不可重复的特点而已
  • 如果在后面加上withscores参数,那么就会带分数一起输出
  • 只有有序的东西采用range
  • 如list

zscore

  • zscore key member
  • 查看某个成员的分数

zrank

  • zrank key member
  • 查看某个成员的排名,或者说在zset里面的排序
  • 排序从0开始

zrevrank

  • zrevrank key member
  • 输出从后往前数的排名
  • 最后的一个成员的排名是0

zrem

  • zrem key member
  • 删除某个成员

哈希(天然适合存储对象)

hset

  • hset key member value
  • 类似set命令,是不过是将键值对收集了起来放在一起了

hget

  • hget key member
  • 获取hash里面某个member的值(value)

hgetall

  • hgetall key
  • 获取某个hash里面的所有member和value

hdel

  • hdel key member
  • 和字符串的del类似,删除某个hash里面的成员
  • 注意
  • 只有string和hash类型才用del,其他都是用rem的

hexists

  • hexists key member
  • 判断某个成员存不存在

hkeys

  • hkeys key
  • 获取哈希里面的所有成员

hlen

  • hlen key
  • 获取哈希表里面成员的个数

频道

  • 有局限性
    • 消息无法持久化
    • 无法查看历史消息

subscribe

  • subscribe channelName
  • 使用这个命令可以订阅一个频道,别人可以在频道上发布信息,你可以实时收到

publish

  • publish channelName message
  • 使用这个命令可以往频道上发送一个消息

消息流stream

  • 所有命令以x开头

xadd

  • xadd steamName Id key value [key value]
  • 往一个steam里面添加消息,以键值对的形式
  • id
  • 由两部分组成 时间戳-序列号
  • 可以用*表示让redis自动生成
  • 也可以部分让redis自动生成如
  • xadd myStream 1745245810715-* name hhh
  • 表示让redis自动生成1745245810715-后面的部分
  • 例子
    • xadd lzg * name hhh age 13 city 北京
    • 往名字为lzg的steam里面添加了三个键值对,而id则让redis自动生成
    • 结果为
    • 1) 1) “1745245810715-0”

2) 1) “name”

2) “hhh”

3) “age”

4) “13”

5) “city”

6) “北京

xrange

  • xrange steamName start stop
  • 查看一个stream的所有消息

-符号表示尽可能小的id

+符号表示尽可能大的id

  • xrange steamName - +
  • 表示查看该stream内的所有范围的消息
  • 也可以组合使用
  • xrange streamName 1650432084877-
  • 表示该时间戳下面最小的id

xdel

  • xdel streamName streamId
  • 删除指定id的消息

xtrim

  • xtrim streamName 策略名称 [~]^是否使用近似修剪 最大长度或者 id
  • 根据策略对消息进行修剪
  • 例子
  • xtrim lzg MAXLEN ~ 2
  • 对lzg消息进行修剪,使用MAXLEN策略,使用近似修剪 修建后的长度为2
  • xtrim lzg MINID 1-1
  • 对lzg消息进行修剪,使用MINID策略,最小的id为1,即将 timestamp-id后面的id小于1的消息进行删除
  • 注意
  • 策略也可以配合xadd进行使用,claude说这比直接使用xtrim更高效和更推荐

xread

  • xread COUNT 数量 [BLOCK 时间]^可选 STREAMS 消息名 起始的id
  • 这个命令用于消费消息里面的消息,
  • COUNT 表示要消费的对象,
  • BLOCK 表示如果没有这个消息那么就等待自己指定的时间,看这个时间过后还有没有符合条件的消息,没有就输出nil,
  • STREAMS 表示消息名,后面再加上一个起始的id
  • 起始的id可以用 符号 $表示,他的意思是从现在开始产生的消息,通常配合BLOCK等待消息使用

如果在一个单体应用里面,直接用xread就可以了,

但是如果我们在一个微服务架构的应用里面,使用xread就不够用了,

具体体现在,多个应用争抢一个消息,如多个应用明明是想读取第一条消息,但经过争抢之后,却不是第一条

所以我们引入消费者和消费者组的概念,

消费者,可以按顺序的从stream中读取消息,如果一个消息被读取过了,那么就会进入读取这个消费者的pel(pending entries list 待处理消息队列),然后下一个消费者就会自动读取下一个消息,即redis会自动标记这个消息被读取过了,


xinfo

  • 这个命令可以查看stream中很多东西的信息

xinfo groups

  • xinfo groups streamName
  • 查看一个消息中的每一个组的信息,如有几个组,每个组有几个消费者

xinfo stream

  • xinfo stream streamName
  • 查看一个消息中的信息,如有多少个消息,第一个进入的消息,最后一个进入的消息等

xinfo consumers

  • xinfo consumers streamName groupName
  • 查看一个消费者组中的每一个消费者的信息

xgroup (消费者组)

xgroup create

  • xgroup create streamName groupName id [MKSTREAMS]
  • 这个会自动创建一个消费者组,
  • id可以手动指定,也可以使用$符号让redis自动保持递增然后分配id
  • MKSTREAMS 参数表示如果没有这个stream,就自动创建这个stream

xgroup createconsumer

  • xgroup createconsumer streamName groupName consumerName

xreadgroup

  • xreadgroup GROUP groupName consumerName COUNT cnt BLOCK timemiles STREAMS streamName >
  • 注意要在GROUP参数后面加上消费者的名字
  • 最后的>符号表示读取消息中最先进入,且未被读取的消息

xack

  • xack streamName groupName 处理完的消息id
  • 该命令表示该id的消息已经被处理完了,下次其他消费者不用再处理一次了

地理空间(geospatial)(了解即可)

hyperloglog(了解即可)

位图(bitmap)

  • 位图以及后面的位域本质上还是字符串
  • 位图的顺序从左到右 依次是 0 1 2 3 4 5,依次递增

setbit

  • setbit bitMapName offset value
  • 设置位图中的某一位的值,值只能位1或0
  • offset表示第几位,也就是偏移量

getbit

  • getbit bitMapName offset
  • 获得位图中某一位的值

set

  • set本来是string中的命令,但是也可以用来设置位图
  • set bitMapName “\xf0”
  • 设置位图的值,使用字符串表示,
  • 这里有个技巧使用十六进制\x f0来表示位图
  • 表示1111 0000

bitcount

  • bitcount bitMapName
  • 获得位图中值为1的个数

bitpos

  • bitpos bitMapName value
  • 查看第一个value的位置
  • bitpos hhh 0
  • 查看hhh中第一个0的位置

位域(bitfield)(组合起来的位图)

set

  • bitfield bitfieldName set 数据类型(u8,u4) offset value
  • 设置位域,数据类型可以是有符号的整形也可以是无符号的整形,但是多少位都可以
  • 如 u8,无符号8位整型,
  • u4,无符号4位整型
  • offset ,偏移量,可以是使用绝对的偏移量,如0,1,2,表示数据的写入起始位置为偏移多少个字节
  • 也可以使用相对偏移量,即使用你前面设置的数据类型的长度,如u8(无符号8位整型),作为数据写入的起始位置

get

  • bitfield bitfieldName get 数据类型 offset
  • 根据数据类型从offset开始读取一个数据类型长度的数据

incrby(注意,incr后面没有e)

  • bitfield bitfieldName INCRBY 数据类型 offset 要增加的数目
  • 表示使用某个数据类型给offset开始的数据类型长度的数据增加一个数字,即加法

事务

  • 注意
  • 这个事务并不等同与mysql中的事务,
  • 这个事务并不保证原子性
  • 这个事务仅仅是一系列命令的集合
  • 一个命令执行失败,其他命令也会执行

multi

  • multi
  • 开启一个事务,
  • 他表示接下来会有很多命令

exec

  • exec
  • 执行事务队列中的命令

discard

  • discard
  • 退出事务
  • discard英文为丢弃,弃置

watch

  • watch key [key…]
  • 在执行事务前检查可以有没有被修改过,如果被修改过就放弃执行事务
  • 本是上是乐观锁
  • 乐观锁适合读取多写入少等冲突比较少的场景
  • 乐观锁还可以避免死锁问题

redis备份

rdb备份(redis database)

  1. 自动备份
    1. 配置文件
    2. 在配置文件redis.conf里面配置命令
    3. save <seconds> <changes> [<seconds> <changes> ...]
    4. 就可以监控修改次数,从而自动保存
save 3600 1 300 100 60 10000

除非另有说明,默认情况下 Redis 会保存数据库:
# * 3600 秒 (一小时) 后,如果进行了至少一次更改
# * 300 秒 (5 分钟) 后,如果进行了至少 100 次更改
# * 如果进行了至少 10000 次修改,60 秒后


5. 表示的意思为 在seconds这个时间内,如果进行了changes次更改,那么就执行备份
6. 他会自动保存到配置文件中,dir命令指定的路径

1745460393455-dcd0edda-aee1-4c1f-b940-4fd46fbcd64a.png

7. 这两个参数一个指定存储的rdb文件的文件名,一个指定的是存储的路径

2. 手动保存
1. save
1. 通过主动使用save命令,来提前进行save保存
2. 1745460933524-9e3dd07e-a01d-4a64-b007-0af864ae5d77.png
3. 这样同样会保存到前面指定的路径和文件名中
2. bgsave
1. 这个命令redis会创建一个子进程,来进行备份,这样做的好处是可以在备份期间,主进程还能够执行命令,但是坏处就是创建进程的时候同样不能够执行命令
2. 1745461472222-4b3b9593-96cd-4fe2-980b-0ffa50d25aaa.png

aof保存(append only file)

1. appendonly 
2. ![1745464346387-e39e664a-2402-4eaa-97dc-bc385f17d3ac.png](/upload/1745464346387-e39e664a-2402-4eaa-97dc-bc385f17d3ac-213504.png)
3. 把这个参数设置为yes
4. redis就会记录你的每一个命令,
5. 等redis重启的时候就会执行你的之前的所有命令,
6. 这样就达到了持久化的目的了
7. 这个比前面的两个保存要更好一点

主从配置

  • 数据会从主节点异步的复制到从节点,从节点的数据不会同步到主节点,数据的流动是单向的,
  • 所以通常主节点负责写操作,从节点负责读操作
  • 如果你想让从节点也负责写可以配置
  • replica-read-only yes
  • 把yes改成no即可
  • replica意为复制品,或者从节点,这句话意为 从节点只能读对吗 yes/no

命令行配置(了解即可)

1745475678739-d1963ba7-5223-4648-99f8-5ef21dc5973b.png

配置文件配置

  1. 修改端口
    1. 首先修改你的从节点的端口号,防止端口冲突,如果是不同的机器,不用修改端口号也行
    2. 默认端口为6379
    3. 1745476236010-08bb6d00-2f2d-406f-9523-c6bca38a6149.png
  2. 修改pidfile
    1. redis以守护进程(也就是后台运行的时候),会将自身的pid写入到这个文件中
    2. redis可以通过这个文件来管理redis进程,为了防止和master机器混用,所以修改为一个新的
    3. 1745476426017-791a0b37-05d4-42fa-aa3b-f4e1df97acc5.png
  3. 修改rdb产生的文件名
    1. rdb备份请看redis备份
    2. 同样为了防止混用
    3. 1745477028425-09d679b2-80f2-4d4f-921f-7ccf925d4637.png
  4. 指定master机器的地址和端口号
    1. replicaof 主机地址 主机端口
    2. 1745479085271-fb5f811a-a764-4436-9c25-d39edeab4fe6.png
  5. 如果你有在主机配置requirepass参数
    1. 即设置了密码
    2. 那么就要在从机的配置文件里面设置
    3. masterauth 主机的密码
    4. 1745480865825-519f2fb6-33f4-4510-bf0d-53cc4858262a.png
  6. 如果你想要这个集群每个集群都有不同的aof,那么还可以设置aof
    1. 设置这两个参数为不同的即可
    2. 1745481137181-82e1fc52-2452-4636-85d2-8220331c5afd.png

info replication

  • 使用这个命令可以查看从机的信息

role

  1. 这个命令可以查看当前机器的角色
  2. 如果是从机
    1. 可以查看主机的ip等等
  3. 如果是主机
    1. 可以查看链接了多少台从机等

哨兵(sentinel)

  1. 作用
    1. 监控
      1. 可以监控所有节点的状态,但是只需要指定主节点的ip即可监控所有节点
    2. 通知
      1. 如果某个节点出问题了,就会发布订阅模式来通知其他节点这个出问题的节点宕机了
    3. 自动故障转移
      1. 哨兵会从从节点中自动投票出新的主节点
  2. 配置配置文件(sentinel.conf)
    1. 配置文件可以配置为其他文件名,一个配置文件对应一个sentinel
  3. 实际应用
    1. 实际生产环境中,一半配置3个哨兵来保证哨兵的高可用,并且这3个哨兵也会自己选举出leader

port

  • port 你想指定sentinel的端口号
  • 指定sentinel的监控端口号,你可以在这个端口获取主节点的地址和端口等信息,相当于开了一个和sentinel交互的端口
  • 注意sentinel不提供像nginx那样反向代理的功能
  • 如果你不指定,sentinel就会使用默认的端口26379,并把这个端口还有其他一些信息写入配置文件

monitor(翻译为监控)

  • sentinel monitor 自定义的主机名称 主机ip 主机端口 投票需要的票数
  • 其他都没什么好说的,主要是后面那个参数,
  • 投票需要的票数
    • 意为如果主机宕机了,那么选举其他的节点为主节点需要的票数
    • 详细请看上面 哨兵.1.自动故障转移

auth-pass(节点密码)

  • 如果主节点配置了密码保护 (requirepass),需要在这里指定连接主节点所需的密码。
  • 需要与 sentinel monitor 中定义的名称一致。
  • sentinel auth-pass 节点名(在monitor里面定义) 密码

其他配置项

# 以守护进程方式在后台运行 Sentinel。建议在生产环境设置为 yes。
daemonize <yes|no>

# 指定 Sentinel 的 PID 文件路径。
pidfile <path/to/sentinel.pid>

# 配置 Sentinel 监控的主节点。
# <master-name>: 你为主节点指定的逻辑名称。
# <master-ip>: 主节点的 IP 地址。
# <master-port>: 主节点的端口号。
# <quorum>: Sentinel 集群需要达成的最小 Sentinel 数量才能执行故障转移。
sentinel monitor <master-name> <master-ip> <master-port> <quorum>

# 如果主节点配置了密码保护 (requirepass),需要在这里指定连接主节点所需的密码。
# <master-name> 需要与 sentinel monitor 中定义的名称一致。
sentinel auth-pass <master-name> <password>

# Sentinel 认为一个 Redis 实例下线 (Subjectively Down, SDOWN) 需要等待的毫秒数。
sentinel down-after-milliseconds <master-name> <milliseconds>

# 在故障转移后,新的主节点可以同时进行同步的从节点数量。
sentinel parallel-syncs <master-name> <numslaves>

# 故障转移的超时时间,单位是毫秒。如果在指定的时间内故障转移没有完成,Sentinel 将放弃本次故障转移。
sentinel failover-timeout <master-name> <milliseconds>

# (可选) 当发生特定的 Sentinel 事件时,Sentinel 可以执行一个外部脚本。
# <script-path> 是脚本的路径。
sentinel notification-script <master-name> <script-path>

# (可选) 在故障转移完成后,Sentinel 可以执行一个脚本来通知客户端新的主节点地址。
# <script-path> 是脚本的路径。
sentinel client-reconfig-script <master-name> <script-path>

# 配置 Sentinel 的日志文件路径。如果注释掉或为空,日志将输出到标准输出 (如果不是守护进程模式)。
logfile <path/to/sentinel.log>

# 配置 Sentinel 的网络绑定地址。默认绑定所有可用接口。
bind <ip> [optional ip ...]

# 配置 Sentinel 的受保护模式。如果启用,只接受来自配置的 bind 地址或 localhost 的连接。
protected-mode <yes|no>

# 配置 Sentinel 的 TCP keepalive 设置。
tcp-keepalive <seconds>

# 配置 Sentinel 的连接超时时间,单位是毫秒。
timeout <milliseconds>

# 配置 Sentinel 的脚本执行超时时间,单位是毫秒。
script-time-limit <milliseconds>

# 配置 Sentinel 的优雅关闭行为。设置为 yes 时,Sentinel 在关闭前会尝试保存状态。
shutdown-save <yes|no>

BUG记录

java工程中向redis中写数据的话,出现乱码

  • 原因
    • redisConfig中没有设置编码解码器
  • 解决
    • 1752304142649-09cbd555-5585-4880-a976-ed6c04382834.png
    • 加上这一行即可
    • config.setCodec(new JsonJacksonCodec());

更新: 2025-07-12 15:09:47
原文: https://www.yuque.com/duifangzhengzaishuru-rqbua/axyc58/eim9amremxl1ih5a