Redis命令详解以及存储原理

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis命令详解以及存储原理

Redis是什么

  • 远程字典服务
  • 分布式场景重的一个单独的节点。
  • 请求回应的模式:发起请求,处理之后得到回应的结果。
  • 字典的形式存储&索引数据。
  • 内存数据库
  • 数据在内存中,不可以出现需要的内存不在内存中而在磁盘中
  • 速度快,内存100ns,磁盘一次IO10ms
  • kv数据库
  • 关系型数据库:b+树索引
  • kv数据库:通过key索引数据
  • 数据结构数据库
  • string:字节串(不是以\0作为分隔符,是用长度描述的)
  • list:链表
  • hash:
  • zset:有序集合(member确定唯一,score确定有序)
  • set:集合
  • stream:消息队列,通常用kafka
  • hyperloglog:基于统计的数据,概率型数据结构
  • 。。。

认识Redis

  • key:都是字节串,用户定义的名字。
  • value:使用什么命令决定。

安装编译

git clone https://github.com/redis/redis.git -b 6.2
cd redis
make -j32
sudo make install

启动

mkdir redis-server
cd redis-server
redis-server redis.conf
redis-cli
>auth [password]

Redis命令

set teacher king
# ok
keys *
#1) "teacher"
get teacher
# "king"
lpush teachers mark darren king
# (integer) 3
lrange teachers 0 -1
hset teacher:10001 name mark
hset teacher:10001 age 30
hset teacher:10001 sex 1
hgetall teacher:10001
sadd teacher:set mark king darren
smembers teacher:set
zadd teacher:rank 98 mark 99 darren 100 king
zrange teacher:rank 0 -1 withscores
zadd teacher:rank 101 mark

Redis存储结构

  • key通过哈希,生成一个64位的整数。Redis维护一个恰好大于n的2的n次幂的数组。对key取余,得到数组的索引值。kv对存储在索引下面,有多个的时候用链表链接。
  • list是一个双向循环链表
  • list,hash和zset可能会使用压缩列表,数据少的时候使用(7.0之后是listpack不记录最后偏移,时间复杂度差不多)
  • zset:跳表
  • set:整形数组,如果元素使整数,那就是整数有序数组
  • string:动态字节串
object encoding teacher # 查看value的类型
incr teacher
incr counter # 没有自动创建为0然后+1
incrby counter 100
decr counter 1
setnx counter 10000
setbit bitstr 1 1
setbit bitstr 2 1
getbit bitstr 3
bitcount bitstr 0 -1

Redis存储转换

String

字符数组,这不是字符串的意思,是字节串。也就是说,redis的string是可以有’\0’符号的。该字符串是动态字符串raw,字符串长度小于1M时,加倍扩容;超过1M每次只扩容1M;字符串的最大长度为512M;

由于String是二进制安全字符串,所以他可以存储图片,二进制协议等二进制数据。

基础命令

# 设置key的val值
set key val
# 获取key的val值
get key
# 执行原子加1操作
incr key
# 执行原子加一个整数的操作
incrby key increment
# 执行原子减1操作
decr key
# 执行原子操作减一个整数
drcrby key increment
# 如果key不存在就等于set,如果存在就什么都不做
setnx key value
# 删除key val键值对
del key
# 设置动态字符串,节省内存
setbit key offset value
# 获取offset处的bit值
getbit key offset
# 统计字符串设置为1的数量
bitcount key [start end]

存储结构

字符串长度小于20且能转化为整数,则用int存储;

字符串长度小于等于44,使用embstr;

字符串长度大于44,使用raw;

实际使用

对象存储
set role:1001 '{["name"]:"lennlouis",["sex"]:"male",["age"]:21}'
set role:1002 '{["name"]:"selena",["sex"]:"female",["age"]:20}'
get role:1001
  • 用在属性字段极少改变的时候
  • redis客户端(redisinsight)使用:来构建树状目录;
  • 存储json格式的value,方便业务解析;
累加器
# 统计阅读数 累加1
incr reads
# 累加100
incrby reads 100

分布式锁

# 尝试将lock的值设置为1
    setnx lock 1
    # 尝试将lock的值设置为一个唯一的标识符uuid
    setnx lock uuid
    #设置过期时间为30s,每个客户端只有一把有效期为30s的锁
    set lock uuid nx ex 30
    # 释放锁
    del lock
    if (get(lock) == uuid)
      del(lock);

位运算

setbit sign:10001:202106 1 1
# 计算 2021年6月份 的签到情况
bitcount sign:10001:202106
# 获取 2021年6月份 第二天的签到情况 1 已签到 0 没有签到
getbit sign:10001:202106 2

List

双向链表的实现,列表首尾操作(删除和增加)时间复杂度为o(1);查找中间元素时间复杂度为o(n);

列表中数据是否压缩的依据

  • 元素长度小于48,不压缩;
  • 元素压缩前后长度差不超过8,不压缩;

基础命令

# 从队列左侧入队一个或者多个元素
lpush key value [value ...]
# 从队列左侧弹出一个元素
lpop key
# 从队列右侧入队一个或多个元素
rpush key value [value ...]
# 从队列右侧弹出一个元素
rpop key
# 返回差从队列的start和end之间的元素
lrange key start end
# 从存于key的列表里移除前count次出现的值为value的元素
# list没有去重功能
lrem key count value
# 他是rpop的阻塞版本,因为这个命令会在给定list无法弹出任何元素的时候阻塞链接
brpop key timeout # 超时时间 + 延时队列

应用

队列(先进先出FIFO)
lpush+rpop
# 或者
rpush+lpop
阻塞队列
lpush+brpop
rpush+blpop
异步消息队列

一般不用,会选择kafka这种消息队列。

获取固定窗口记录

hash

散列表,在很多高级语言中包含这种数据结构;C++`unordered_map`通过key快速索引value;

基础命令

# 获取key对应hash中的field
hget key field
# 设置key对应hash中的field
hset key field value
# 设置多个hash键值对
hmset key field1 value1 field2 value2 ... fieldn valuen
# 获取多个field值
hmget key field1 field2 ... fieldn
# 给key对应hash中的field对应的值加1
hincrby key field increment
# 获取key对应的hash中有几个键值
hlen key
# 删除key对应的hash键值对
hdel key field

存储结构

节点数量大于512(hash-max-ziplist-entries)或者所有字符串长度大于64(hash-max-ziplist-value),则使用dict实现;如果节点数量小于等于512且有一个字符串小于64,则使用ziplist。

应用

存储对象
hmset hash:10001 name jiejie age 18 sex male
# 与string比较
set hash:10001 '{["name"]:"mark",["sex"]:"male",["age"]:18}'
# 如果现在要更新数据将年龄改为19岁
# hash
hset hash:10001 age 19
# string
set hash:10001 '{["name"]:"mark",["sex"]:"male",["age"]:19}'
购物车


set

集合:用来存储唯一性字段,不要求有序;

存储不需要有序,操作需要有序。(在取出数据后使用排序算法排序)

基础命令

sadd key member [member ...]
scard key
smembers key
sismember key member
srandmember key [count]
spop key [count]
sdiff key [key ...]
sinter key [key ...]
sunion key [key ...]
• 1
• 2
• 3
• 4
• 5
• 6
• 7
• 8
• 9

存储结构

元素都为整数且节点数量小于等于512,则使用整数数组存储;

元素中有一个不是整数或者节点数量大于512,则使用字典存储;

应用

抽奖
# 添加抽奖用户
sadd Award:1 10001 10002 10003 10004 10005 10006
sadd Award:1 10009
# 查看所有抽奖用户
smembers Award:1
# 抽取用户
srandmember Award:1 10
共同关注
sadd follow:A xiaomin lihua liuwei zhuzhu
sadd follow:B xiaomin lihua liuwei
sinter follow:A follow:B
推荐好友
sadd follow:A xiaomin lihua liuwei zhuzhu
sadd follow:B xiaomin lihua liuwei
# B可能认识的人
sdiff sinter follow:A follow:B

zset

有序集合:用来实现排行榜,是一个唯一有序的集合。

基础命令

zadd key [NX|XX] [CH] [INCR] score member [score member ...]
zrem key member [member ...]
zscore key member
zincrby key increment member
zcard key
zrank key member
zrange key start stop [WITHSCORES]
zrevrange key start stop [WITHSCORES]

存储结构

节点数量大于128或者有一个字符串长度大于64,则使用跳表;

节点数量小于等于128且所有字符串长度小于等于64,则使用`ziplist`;

数据少的时候,节省空间;O(n)

数据多的时候,访问性能;O(1) 或者 O(log2n)

应用

百度热榜


# 点击新闻 增加一个热度
zincrby hot:20240711 1 10001
zincrby hot:20240711 1 10002
zincrby hot:20240711 1 10003
zincrby hot:20240711 1 10004
zincrby hot:20240711 1 10005
zincrby hot:20240711 1 10006
zincrby hot:20240711 1 10007
zincrby hot:20240711 1 10008
zincrby hot:20240711 1 10009
zincrby hot:20240711 1 10010
zincrby hot:20240711 1 10011
zincrby hot:20240711 1 10012
zincrby hot:20240711 1 10013
zincrby hot:20240711 1 10014
zincrby hot:20240711 1 10015
# 获取排行榜
zrevrange hot:20240711 0 14 withscores
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(一)
数据的存储--Redis缓存存储(一)
99 1
|
2月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(二)
数据的存储--Redis缓存存储(二)
52 2
数据的存储--Redis缓存存储(二)
|
2月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
78 6
|
1月前
|
存储 NoSQL 算法
Redis分片集群中数据是怎么存储和读取的 ?
Redis集群采用哈希槽分区算法,共有16384个哈希槽,每个槽分配到不同的Redis节点上。数据操作时,通过CRC16算法对key计算并取模,确定其所属的槽和对应的节点,从而实现高效的数据存取。
48 13
|
1月前
|
存储 NoSQL Redis
【赵渝强老师】Redis的存储结构
Redis 默认配置包含 16 个数据库,通过 `databases` 参数设置。每个数据库编号从 0 开始,默认连接 0 号数据库,可通过 `SELECT <dbid>` 切换。Redis 的核心存储结构包括 `dict`、`expires` 等字段,用于处理键值和过期行为。添加键时需指定数据库信息。视频讲解和代码示例详见内容。
|
1月前
|
存储 NoSQL Java
Redis命令:列表模糊删除详解
通过本文的介绍,我们详细探讨了如何在Redis中实现列表的模糊删除。虽然Redis没有直接提供模糊删除命令,但可以通过组合使用 `LRANGE`和 `LREM`命令,并在客户端代码中进行模糊匹配,来实现这一功能。希望本文能帮助你在实际应用中更有效地操作Redis列表。
54 0
|
2月前
|
缓存 NoSQL 测试技术
Redis如何解决频繁的命令往返造成的性能瓶颈!
Redis如何解决频繁的命令往返造成的性能瓶颈!
|
2月前
|
设计模式 NoSQL 网络协议
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
43 2
|
2月前
|
存储 缓存 NoSQL
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
70 1
|
2月前
|
缓存 NoSQL Redis
Redis命令:列表模糊删除详解
Redis命令:列表模糊删除详解
73 3