Skip to content

redis应用

数据操作

操作类型命令示例描述
显示所有的 keyKEYS *显示所有的 key。支持通配符 *、前缀 prefix*、后缀 *suffix
删除指定的 keyDEL key1 key2 key3 ...删除一个或多个指定的 key。
判断 key 是否存在EXISTS key判断指定的 key 是否存在。
设置 key 的有效期EXPIRE key 10设置指定 key 的过期时间(单位:秒)。
显示 key 的有效期TTL key查看指定 key 的剩余过期时间。
清空当前数据库FLUSHDB清空当前选择的数据库。
清空所有数据库FLUSHALL清空所有 Redis 数据库。
切换数据库SELECT dbNum切换到指定的数据库。
字符串操作
添加值SET key value设置指定 key 的值。
获取值GET key获取指定 key 的值。
批量操作MSET key1 value1 [key2 value2, key3 value3]批量设置多个 key 的值。
自增INCR key将 key 的值自增 1。
自减DECR key将 key 的值自减 1。
设置自增/自减增量INCRBY key increment设置 key 的增量为指定值。
设置带有效期的值SETEX key second value设置 key 的同时设置过期时间(单位:秒)。
仅当 key 不存在时设置SETNX key value如果 key 不存在则设置,否则不做任何操作。
追加值到现有值末尾APPEND key value将指定值追加到 key 原有值的末尾。
查看值的长度STRLEN key返回 key 所储存的字符串值的长度。
哈希操作
存储数据到哈希表HSET key field value设置 key 指定的哈希集中指定字段的值。
获取哈希表中的值HGET key field获取 key 指定的哈希集中指定字段的值。
批量操作HMSET key field value [field value......]批量设置 key 的哈希字段及对应的值。
批量获取HMGET key field [field......]批量获取 key 的哈希字段对应的值。
自增HINCRBY key field increment为 key 的哈希字段自增指定值。
仅当不存在时设置HSETNX key field value当 key 的哈希字段不存在时设置值。
检测字段是否存在HEXISTS key field检测 key 的哈希字段是否存在。
删除指定字段HDEL key field1, field2......删除 key 的哈希字段。
获取所有字段及值HGETALL key获取 key 的所有哈希字段及对应的值。
获取所有字段HKEYS key获取 key 的所有哈希字段。
获取所有值HVALS key获取 key 的所有哈希字段对应的值。
获取字段个数HLEN key获取 key 的哈希字段数量。
列表操作
头部添加数据LPUSH key value [value.......]将一个或多个值插入到列表头部。
尾部添加数据RPUSH key value [value.......]将一个或多个值插入到列表尾部。
判断列表是否存在LPUSHX key value当列表存在时,将值插入到列表头部。
修改列表指定位置的值LSET key index value修改列表中指定位置的值。
获取并删除列表头部值LPOP key移除并返回列表 key 的头元素。
获取并删除列表尾部值RPOP key移除并返回列表 key 的尾元素。
获取列表指定范围的值LRANGE key start stop获取列表 key 中指定范围内的所有值。
获取列表指定位置的值LINDEX key index获取列表 key 中指定位置的值。
获取列表长度LLEN key获取列表 key 的长度。
删除列表中的值LREM key count value从列表中删除与参数 value 相等的元素。
保留指定范围的值LTRIM key start stop对列表进行修剪,使其只包含指定范围的元素。
集合操作
存储数据到集合SADD key value [value ......]向集合添加一个或多个成员。
获取集合中所有成员SMEMBERS key返回集合中的所有成员。
随机获取一个成员SPOP key [count]移除并返回集合中的一个或多个随机成员。
计算多个集合的交集SINTER set1 set2 ...返回给定所有集合的交集。
计算多个集合的并集SUNION set1 set2 ...返回给定所有集合的并集。
计算多个集合的差集SDIFF set1 set2 ...返回给定所有集合的差集。
删除集合中的成员SREM key value [value.....]移除集合中一个或多个成员。
检查成员是否存在SISMEMBER key value判断成员是否是集合 key 的成员。
有序集合操作
添加数据到有序集合ZADD key score value [score value.....]向有序集合添加一个或多个成员,或者更新已存在成员的分数。
修改分值ZINCRBY key increment value为有序集 key 的成员 value 的分数加上增量 increment 。
获取成员的分值ZSCORE key value返回有序集 key 中,成员 value 的分数值。
获取成员个数ZCARD key返回有序集 key 的基数。
获取指定范围内的成员ZRANGE key start stop [WITHSCORES]返回有序集 key 中,指定区间内的成员。
获取指定范围内的成员ZREVRANGE key start stop [WITHSCORES]返回有序集 key 中,指定区间内的成员(从大到小排序)。
计算指定分数范围内的成员数ZCOUNT key min max返回有序集 key 中,分数介于 min 和 max 之间的成员数。
删除有序集合中的成员ZREM key value删除有序

数据类型

数据结构描述
key-string一个 key 对应一个字符串,通常用来存储单个值。
key-hash一个 key 对应一个哈希表(Map),通常用来存储对象数据。
key-list一个 key 对应一个列表,通常用来实现栈和队列等数据结构。
key-set一个 key 对应一个集合,用于实现数据的交集、并集、差集等操作。
key-zset一个 key 对应一个有序集合,用于实现带分数的数据存储和排序。
HyperLogLog用于基数统计和近似计数的数据结构。
GEO用于存储地理位置信息的数据结构。
经度的范围在 (-180, 180],纬度的范围 在(-90, 90]
BIT用来存储位操作相关的数据,通常存储 byte[] 类型的字符串。
HyperLogLog

HyperLogLog

sh
#1.统计非重复的字符串个数(占用内存小,计算速度快)
PFADD key value1 value2 value3 ...
PFCOUNT key
#1.统计非重复的字符串个数(占用内存小,计算速度快)
PFADD key value1 value2 value3 ...
PFCOUNT key

一个 key 关联了一个数据集合,同时对这个数据集合做统计。

  • 统计一个 APP 的日活、月活数;
  • 统计一个页面的每天被多少个不同账户访问量(Unique Visitor,UV));
  • 统计用户每天搜索不同词条的个数;
  • 统计注册 IP 数。

通常情况下,我们面临的用户数量以及访问量都是巨大的,比如百万、千万级别的用户数量,或者千万级别、甚至亿级别的访问信息。

布隆过滤器

布隆过滤器由n个Hash函数和一个二进制数组组成,主要用于判断一个元素是否在一个集合中

image-20221108151558574

1.初始状态

一开始,二进制数组里是没有值的

image-20221108151626952

2.存储操作

发来一个请求数据hello 对数据hello经过三次hash运算,分别得到三个值(假设1,3,5)。 在对应的二进制数组里,将下标为1,3,5的值置为1。

3.查询操作

发来一个请求数据hello 对数据hello经过三次hash运算,分别得到三个值(假设1,3,5)。 在二进制数组里,将下标为1,3,5的值取出来,如果都为1,则表示该数据已经存在。

4.删除操作

布隆过滤器很难进行删除操作。

如果hash2(hello)结果为3,hash2(world)结果也为3,那么如果删除了hello的值,就意味着world的值也会被其删除。

5.误判率

假设保存两个值,hello和world hello对应的index(也就是hash计算后的值)为1,3,5 world对应的index(也就是hash计算后的值)为2,4,6

而此时来了一个值java,对应的index为1,4,5,查询得出结果:exist(java) = true,但其实,java这个数据并不存在,这就会产生一定的误判。

Redis 官方提供的布隆过滤器到了 Redis 4.0 才正式登场。Redis 4.0 提供了插件功能,布隆过滤器作为一个插件加载到 Redis Server 中,给 Redis 提供了强大的布隆去重功能。

使用Docker进行安装

bash
docker pull redislabs/rebloom:latest # 拉取镜像
docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest #运行容器
docker exec -it redis-redisbloom bash
redis-cli
docker pull redislabs/rebloom:latest # 拉取镜像
docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest #运行容器
docker exec -it redis-redisbloom bash
redis-cli

使用

布隆过滤器基本指令:

  • bf.add 添加元素到布隆过滤器
  • bf.exists 判断元素是否在布隆过滤器
  • bf.madd 添加多个元素到布隆过滤器,bf.add 只能添加一个
  • bf.mexists 判断多个元素是否在布隆过滤器

慢查询日志配置

慢查询日志是存放在Redis内存列表中的, 但是Redis并没有暴露这个列表的键, 而是通过一组命令来实现对慢查询日志的访问和管理。

shell
slowlog get [n] # 获取慢查询日志 参数n可以指定条数
slowlog get [n] # 获取慢查询日志 参数n可以指定条数
shell
127.0.0.1:6379> slowlog get
1) 1) (integer) 666
   2) (integer) 1456786500
   3) (integer) 11615
   4) 1) "BGREWRITEAOF"
2) 1) (integer) 665
   2) (integer) 1456718400
   3) (integer) 12006
   4) 1) "SETEX"
      2) "video_info_200"
      3) "300"
      4) "2"
      ...
127.0.0.1:6379> slowlog get
1) 1) (integer) 666
   2) (integer) 1456786500
   3) (integer) 11615
   4) 1) "BGREWRITEAOF"
2) 1) (integer) 665
   2) (integer) 1456718400
   3) (integer) 12006
   4) 1) "SETEX"
      2) "video_info_200"
      3) "300"
      4) "2"
      ...

每个慢查询日志有4个属性组成, 分别是:

  • 慢查询日志的标识id
  • 发生时间戳
  • 命令耗时
  • 执行命令和参数。
shell
# 获取慢查询日志当前长度
slowlog len

# 清理慢查询日志
slowlog reset
# 获取慢查询日志当前长度
slowlog len

# 清理慢查询日志
slowlog reset

慢查询功能可以有效地帮助我们找到Redis可能存在的瓶颈,但在实际使用过程中要注意以下几点:

  • slowlog-max-len配置建议

    线上建议调大慢查询列表,记录慢查询时Redis会对长命令做截断操作,并不会占用大量内存。增大慢查询列表可以减小慢查询被剔除的可能,例如线上可设置为1000以上。

  • slowlog-log-slower-than配置建议

    默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值。由于Redis采用单线程响应命令,对于高流量的场景,如果命令执行时间在1毫秒以上,那么Redis最多可支撑OPS不到1000。因此对于高OPS场景的Redis建议设置为1毫秒。

  • 慢查询只记录命令执行时间,并不包括命令排队和网络传输时间

    此客户端执行命令的时间会大于命令实际执行时间。因为命令执行排队机制,慢查询会导致其他命令级联阻塞,因此当客户端出现请求超时,需要检查该时间点是否有对应的慢查询,从而分析出是否为慢查询导致的命令级联阻塞。

  • 慢查询日志可能会丢失

    由于慢查询日志是一个先进先出的队列,也就是说如果慢查询比较多的情况下,可能会丢失部分慢查询命令。为了防止这种情况发生,可以定期执行slowget命令将慢查询日志持久化到其他存储中(例如MySQL),然后可以制作可视化界面进行查询,第13章介绍的Redis私有云CacheCloud提供了这样的功能,好的工具可以让问题排查事半功倍。

redis全局配置

shell
#基本配置
daemonize no 是否以后台进程启动
databases 16 创建database的数量(默认选中的是database 0)

save 900 1    #刷新快照到硬盘中,必须满足两者要求才会触发,即900秒之后至少1个关键字发生变化。
save 300 10  #必须是300秒之后至少10个关键字发生变化。
save 60 10000 #必须是60秒之后至少10000个关键字发生变化。
stop-writes-on-bgsave-error yes    #后台存储错误停止写。
rdbcompression yes    #使用LZF压缩rdb文件。
rdbchecksum yes    #存储和加载rdb文件时校验。
dbfilename dump.rdb    #设置rdb文件名。
dir ./    #设置工作目录,rdb文件会写入该目录。

#主从配置
slaveof <masterip> <masterport> 设为某台机器的从服务器
masterauth <master-password>   连接主服务器的密码
slave-serve-stale-data yes  # 当主从断开或正在复制中,从服务器是否应答
slave-read-only yes #从服务器只读
repl-ping-slave-period 10 #从ping主的时间间隔,秒为单位
repl-timeout 60 #主从超时时间(超时认为断线了),要比period大
slave-priority 100    #如果master不能再正常工作,那么会在多个slave中,选择优先值最小的一个slave提升为master,优先值为0表示不能提升为master。

repl-disable-tcp-nodelay no #主端是否合并数据,大块发送给slave
slave-priority 100 从服务器的优先级,当主服挂了,会自动挑slave priority最小的为主服

#安全配置
requirepass foobared # 需要密码
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 #如果公共环境,可以重命名部分敏感命令 如config

#限制参数
maxclients 10000 #最大连接数
maxmemory <bytes> #最大使用内存

maxmemory-policy volatile-lru #内存到极限后的处理
volatile-lru -> LRU算法删除过期key
allkeys-lru -> LRU算法删除key(不区分过不过期)
volatile-random -> 随机删除过期key
allkeys-random -> 随机删除key(不区分过不过期)
volatile-ttl -> 删除快过期的key
noeviction -> 不删除,返回错误信息

#解释 LRU ttl都是近似算法,可以选N个,再比较最适宜T踢出的数据
maxmemory-samples 3

#日志模式
appendonly no #是否仅要日志
appendfsync no # 系统缓冲,统一写,速度快
appendfsync always # 系统不缓冲,直接写,慢,丢失数据少
appendfsync everysec #折衷,每秒写1次

no-appendfsync-on-rewrite no #为yes,则其他线程的数据放内存里,合并写入(速度快,容易丢失的多)
auto-AOF-rewrite-percentage 100 当前aof文件是上次重写是大N%时重写
auto-AOF-rewrite-min-size 64mb aof重写至少要达到的大小

#慢查询
slowlog-log-slower-than 10000 #记录响应时间大于10000微秒的慢查询
slowlog-max-len 128   # 最多记录128条

#服务端命令
time  返回时间戳+微秒
dbsize 返回key的数量
bgrewriteaof 重写aof
bgsave 后台开启子进程dump数据
save 阻塞进程dump数据
lastsave 

slaveof host port 做host port的从服务器(数据清空,复制新主内容)
slaveof no one 变成主服务器(原数据不丢失,一般用于主服失败后)

flushdb  清空当前数据库的所有数据
flushall 清空所有数据库的所有数据(误用了怎么办?)

shutdown [save/nosave] 关闭服务器,保存数据,修改AOF(如果设置)

slowlog get 获取慢查询日志
slowlog len 获取慢查询日志条数
slowlog reset 清空慢查询

info []

config get 选项(支持*通配)
config set 选项 
config rewrite 把值写到配置文件
config restart 更新info命令的信息

debug object key #调试选项,看一个key的情况
debug segfault #模拟段错误,让服务器崩溃
object key (refcount|encoding|idletime)
monitor #打开控制台,观察命令(调试用)
client list #列出所有连接
client kill #杀死某个连接  CLIENT KILL 127.0.0.1:43501
client getname #获取连接的名称 默认nil
client setname "名称" #设置连接名称,便于调试

#连接命令
auth 密码 #密码登陆(如果有密码)
ping #测试服务器是否可用
echo "some content" #测试服务器是否正常交互
select 0/1/2... #选择数据库
quit #退出连接
#基本配置
daemonize no 是否以后台进程启动
databases 16 创建database的数量(默认选中的是database 0)

save 900 1    #刷新快照到硬盘中,必须满足两者要求才会触发,即900秒之后至少1个关键字发生变化。
save 300 10  #必须是300秒之后至少10个关键字发生变化。
save 60 10000 #必须是60秒之后至少10000个关键字发生变化。
stop-writes-on-bgsave-error yes    #后台存储错误停止写。
rdbcompression yes    #使用LZF压缩rdb文件。
rdbchecksum yes    #存储和加载rdb文件时校验。
dbfilename dump.rdb    #设置rdb文件名。
dir ./    #设置工作目录,rdb文件会写入该目录。

#主从配置
slaveof <masterip> <masterport> 设为某台机器的从服务器
masterauth <master-password>   连接主服务器的密码
slave-serve-stale-data yes  # 当主从断开或正在复制中,从服务器是否应答
slave-read-only yes #从服务器只读
repl-ping-slave-period 10 #从ping主的时间间隔,秒为单位
repl-timeout 60 #主从超时时间(超时认为断线了),要比period大
slave-priority 100    #如果master不能再正常工作,那么会在多个slave中,选择优先值最小的一个slave提升为master,优先值为0表示不能提升为master。

repl-disable-tcp-nodelay no #主端是否合并数据,大块发送给slave
slave-priority 100 从服务器的优先级,当主服挂了,会自动挑slave priority最小的为主服

#安全配置
requirepass foobared # 需要密码
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 #如果公共环境,可以重命名部分敏感命令 如config

#限制参数
maxclients 10000 #最大连接数
maxmemory <bytes> #最大使用内存

maxmemory-policy volatile-lru #内存到极限后的处理
volatile-lru -> LRU算法删除过期key
allkeys-lru -> LRU算法删除key(不区分过不过期)
volatile-random -> 随机删除过期key
allkeys-random -> 随机删除key(不区分过不过期)
volatile-ttl -> 删除快过期的key
noeviction -> 不删除,返回错误信息

#解释 LRU ttl都是近似算法,可以选N个,再比较最适宜T踢出的数据
maxmemory-samples 3

#日志模式
appendonly no #是否仅要日志
appendfsync no # 系统缓冲,统一写,速度快
appendfsync always # 系统不缓冲,直接写,慢,丢失数据少
appendfsync everysec #折衷,每秒写1次

no-appendfsync-on-rewrite no #为yes,则其他线程的数据放内存里,合并写入(速度快,容易丢失的多)
auto-AOF-rewrite-percentage 100 当前aof文件是上次重写是大N%时重写
auto-AOF-rewrite-min-size 64mb aof重写至少要达到的大小

#慢查询
slowlog-log-slower-than 10000 #记录响应时间大于10000微秒的慢查询
slowlog-max-len 128   # 最多记录128条

#服务端命令
time  返回时间戳+微秒
dbsize 返回key的数量
bgrewriteaof 重写aof
bgsave 后台开启子进程dump数据
save 阻塞进程dump数据
lastsave 

slaveof host port 做host port的从服务器(数据清空,复制新主内容)
slaveof no one 变成主服务器(原数据不丢失,一般用于主服失败后)

flushdb  清空当前数据库的所有数据
flushall 清空所有数据库的所有数据(误用了怎么办?)

shutdown [save/nosave] 关闭服务器,保存数据,修改AOF(如果设置)

slowlog get 获取慢查询日志
slowlog len 获取慢查询日志条数
slowlog reset 清空慢查询

info []

config get 选项(支持*通配)
config set 选项 
config rewrite 把值写到配置文件
config restart 更新info命令的信息

debug object key #调试选项,看一个key的情况
debug segfault #模拟段错误,让服务器崩溃
object key (refcount|encoding|idletime)
monitor #打开控制台,观察命令(调试用)
client list #列出所有连接
client kill #杀死某个连接  CLIENT KILL 127.0.0.1:43501
client getname #获取连接的名称 默认nil
client setname "名称" #设置连接名称,便于调试

#连接命令
auth 密码 #密码登陆(如果有密码)
ping #测试服务器是否可用
echo "some content" #测试服务器是否正常交互
select 0/1/2... #选择数据库
quit #退出连接