01.Redis数据类型及高性能原理

Redis 的五种数据结构及其应用场景

Redis官方文档链接:https://redis.io/commands 中文文档:http://redisdoc.com/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v7hzI30t-1645457507435)(..\images\Redis\7.png)]

一、字符串

命令解释
SET key value存入字符串键值对
MSET key value [key value …]批量存储字符串键值对
SETNX key value存入一个不存在的字符串键值对
GET key获取一个字符串键值
MGET key [key …]批量获取字符串键值
DEL key [key …]删除一个键
EXPIRE key seconds设置一个键的过期时间(秒)
INCR key将key中储存的数字值加1
DECR key将key中储存的数字值减1
INCRBY key increment将key所储存的值加上increment
DECRBY key decrement将key所储存的值减去decrement
应用场景
  1. 单值缓存

    SET key value
    GET key
    
  2. 对象存储

    直接存储对象

    SET  user:1  "{"name":"zhangsan","age":18}"
    GET  user:1
    

    拆分对象存储

    MSET  user:1:name  zhangsan   user:1:age  18
    MGET  user:1:name   user:1:age
    
  3. 分布式锁

    加锁
    SETNX  product:10001  true 		// 第一次执行,返回1代表获取锁成功
    SETNX  product:10001  true 		// 再次执行,返回0代表获取锁失败
    删锁
    DEL  product:10001			// 执行完业务释放锁,防止过期不存在可以使用lua脚本
    加锁时设置超时时间
    SET product:10001 true  ex  10  nx	// 防止程序意外终止导致死锁
    
    
  4. 分布式系统全局流水

    INCRBY  id  2000		// redis 批量生成序列号提升性能
    
  5. 计数器

    例如微信推文的阅读量、视频播放量等
    INCR article:readcount:{文章id}  	
    GET article:readcount:{文章id} 
    
  6. Web集群 session 共享

    spring session 提供了通过 Redis 设置 session 共享的功能

二、Hash

命令解释
HSET key field value存储一个哈希表key的键值
HSETNX key field value存储一个不存在的哈希表key的键值
HMSET key field value [field value …]在一个哈希表key中存储多个键值对
HGET key field获取哈希表key对应的field键值
HMGET key field [field …]批量获取哈希表key中多个field键值
HDEL key field [field …]删除哈希表key中的field键值
HLEN key返回哈希表key中field的数量
HGETALL key返回哈希表key中所有的键值
HINCRBY key field increment为哈希表key中field键的值加上增量increment
应用场景
  1. 对象缓存

    HMSET  user  {userId}:name  zhangsan  {userId}:age  18
    HMSET  user  1:name  zhuge  1:age  18
    HMGET  user  1:name  1:age
    
  2. 商品购物车

在这里插入图片描述

Hash类型的优缺点

优点:

  • 同类数据归类整合储存,方便数据管理

  • 相比 string 操作消耗内存与 cpu 更小

  • 相比 string 储存更节省空间

缺点

  • 过期功能不能使用在 field 上,只能用在 key 上
  • Redis 集群架构下不适合大规模使用

在这里插入图片描述

三、List

命令解释
LPUSH key value [value …]将一个或多个值value插入到key列表的表头(最左边)
RPUSH key value [value …]将一个或多个值value插入到key列表的表尾(最右边)
LPOP key移除并返回key列表的头元素
RPOP key移除并返回key列表的尾元素
LRANGE key start stop返回列表key中指定区间内的元素,区间以偏移量start和stop指定
BLPOP key [key …] timeout从key列表表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
BRPOP key [key …] timeout从key列表表尾部弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待

通过这些操作,可以组成一些常用的数据结构,应用到不同的场景中

  • Stack(栈) = LPUSH + LPOP
  • Queue(队列)= LPUSH + RPOP
  • Blocking MQ(阻塞队列)= LPUSH + BRPOP
应用场景

微博消息、微信订阅号等消息流

在这里插入图片描述

四、Set

常用基本操作解释
SADD key member [member …]往集合key中存入元素,元素存在则忽略,若key不存在则新建
SREM key member [member …]从集合key中删除元素
SMEMBERS key获取集合key中所有元素
SCARD key获取集合key的元素个数
SISMEMBER key member判断member元素是否存在于集合key中
SRANDMEMBER key [count]从集合key中选出count个元素,元素不从key中删除
SPOP key [count]从集合key中选出count个元素,元素从key中删除
Set集合的运算操作解释
SINTER key [key …]交集运算
SINTERSTORE destination key [key …]将交集结果存入新集合destination中
SUNION key [key …]并集运算
SUNIONSTORE destination key [key …]将并集结果存入新集合destination中
SDIFF key [key …]差集运算
SDIFFSTORE destination key [key …]将差集结果存入新集合destination中
应用场景
  1. 微信、支付宝抽奖小程序

在这里插入图片描述

  1. 微博、微信等点赞、收藏、标签

在这里插入图片描述

  1. 微信、微博、QQ关注模型、社交模型

    1) 我关注的人: 
    meSet--> {特朗普, 拜登 ,汤姆逊}
    2) 特朗普关注的人:
    telangpuSet --> {普京, 拜登, 安倍晋三, 汤姆逊}
    3) 拜登关注的人: 
    pujingSet--> {特朗普, 普京, 汤姆逊, 安倍晋三, 拿破仑)
    4) 我和特朗普共同关注: 
    SINTER meSet telangpuSet--> {汤姆逊, 拜登}
    5) 我关注的人也关注他(杨过老师): 
    SISMEMBER telangpuSet 普京 
    SISMEMBER pujingSet 普京
    6) 我可能认识的人: 
    SDIFF telangpuSet meSet --> (安倍晋三, 普京}
    
  2. 商城商品筛选

在这里插入图片描述

为品牌下插入商品
SADD  brand:huawei  Huawei-P50
SADD  brand:vivo  vivo-x70
SADD  brand:xiaomi  Mi-12
SADD  brand:iPhone iPhone13

为操作系统下插入商品
SADD os:android  vivo-x70  Mi-12
SADD os:ios  iPhone13
SADD os:harmony  Huawei-P50

为CPU、内存等插入商品
SADD cpu:brand:qualcomm  Huawei-P50  Mi-12 vivo-x70
SADD ram:8G  Huawei-P50 vivo-x70 Mi-12 iPhone13

取交集获取商品搜索需要的标签
SINTER  os:android  cpu:brand:qualcomm  ram:8G -> {Mi-12 vivo-x70}

ZSet

常用操作解释
ZADD key score member [[score member]…]往有序集合key中加入带分值元素
ZREM key member [member …]从有序集合key中删除元素
ZSCORE key member返回有序集合key中元素member的分值
ZINCRBY key increment member为有序集合key中元素member的分值加上increment
ZCARD key返回有序集合key中元素个数
ZRANGE key start stop [WITHSCORES]正序获取有序集合key从start下标到stop下标的元素
ZREVRANGE key start stop [WITHSCORES]倒序获取有序集合key从start下标到stop下标的元素
ZSet集合运算解释
ZUNIONSTORE destkey numkeys key [key …]并集运算,并将结果存入destkey
ZINTERSTORE destkey numkeys key [key …]交集运算,并将结果存入destkey
应用场景

排行榜–微博热搜、热搜周榜、同城榜等

1)点击新闻
ZINCRBY  hotNews:20220218  1  xxxx
2)展示当日排行前十
ZREVRANGE  hotNews:20220218  0  9  WITHSCORES 
3)七日搜索榜单计算
ZUNIONSTORE  hotNews:20220212-20220218  7 
hotNews:20220212  hotNews:20220213... hotNews:20220218
4)展示七日排行前十
ZREVRANGE hotNews:20220212-20220218  0  9  WITHSCORES-

Redis高性能原理

  • Redis是真的单线程吗?

    Redis 的单线程主要是指 Redis 的**网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等是由额外的线程执行的**。

  • Redis 单线程为什么这么快?

    所有的操作都是在内存中完成的,纯内存操作非常快,单线程也避免了多线程上下文的切换对性能的损耗。但是因为Redis是单线程,所有必须谨慎使用耗时的操作(例如:keys)。

  • Redis 单线程如何处理并发客户端连接?

    Redis采用了IO的多路复用机制,redis 采用 epoll 实现了 IO 多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。

其他命令及注意事项

  • keys [MATCH pattern]:遍历全键,找出所有满足特定正则字符串规则的 key,应避免使用,当数据量大时,及其销毁性能
  • scan cursor [MATCH pattern] [COUNT count]渐进式遍历键,第一个是 cursor 整数值(hash桶的索引值),第二个是 key 的正则模式, 第三个是一次遍历的key的数量(参考值,底层遍历的数量不一定),并不是符合条件的结果数量。第一次遍历时,cursor 值为 0,然后将返回结果中第一个整数值作为下一次遍历的 cursor。一直遍历到返回的 cursor 值为 0 时结束。在 scan 过程中,如果有键的变化(增加、 删除、 修改),那么可能出现遍历重复、遗漏等现象
  • Info:查看redis服务运行信息,分为 9 大块,每个块都有非常多的参数
    • Server 服务器运行的环境参数
    • Clients 客户端相关信息
    • Memory 服务器运行内存统计数据
    • Persistence 持久化信息
    • Stats 通用统计数据
    • Replication 主从复制相关信息
    • CPU CPU 使用情况
    • Cluster 集群信息
    • KeySpace 键值对统计数量信息

Redis客户端命令对应的RedisTemplate中的方法列表:

String类型结构
RedisRedisTemplate rt
set key valuert.opsForValue().set(“key”,“value”)
get keyrt.opsForValue().get(“key”)
del keyrt.delete(“key”)
strlen keyrt.opsForValue().size(“key”)
getset key valuert.opsForValue().getAndSet(“key”,“value”)
getrange key start endrt.opsForValue().get(“key”,start,end)
append key valuert.opsForValue().append(“key”,“value”)
Hash结构
hmset key field1 value1 field2 value2…rt.opsForHash().putAll(“key”,map)
hset key field valuert.opsForHash().put(“key”,“field”,“value”)
hexists key fieldrt.opsForHash().hasKey(“key”,“field”)
hgetall keyrt.opsForHash().entries(“key”)
hvals keyrt.opsForHash().values(“key”)
hkeys keyrt.opsForHash().keys(“key”)
hmget key field1 field2…rt.opsForHash().multiGet(“key”,keyList)
hsetnx key field valuert.opsForHash().putIfAbsent(“key”,“field”,“value”
hdel key field1 field2rt.opsForHash().delete(“key”,“field1”,“field2”)
hget key fieldrt.opsForHash().get(“key”,“field”)
List结构
lpush list node1 node2 node3…rt.opsForList().leftPush(“list”,“node”)
rt.opsForList().leftPushAll(“list”,list)
rpush list node1 node2 node3…rt.opsForList().rightPush(“list”,“node”)
rt.opsForList().rightPushAll(“list”,list)
lindex key indexrt.opsForList().index(“list”, index)
llen keyrt.opsForList().size(“key”)
lpop keyrt.opsForList().leftPop(“key”)
rpop keyrt.opsForList().rightPop(“key”)
lpushx list nodert.opsForList().leftPushIfPresent(“list”,“node”)
rpushx list nodert.opsForList().rightPushIfPresent(“list”,“node”)
lrange list start endrt.opsForList().range(“list”,start,end)
lrem list count valuert.opsForList().remove(“list”,count,“value”)
lset key index valuert.opsForList().set(“list”,index,“value”)
Set结构
sadd key member1 member2…rt.boundSetOps(“key”).add(“member1”,“member2”,…)
rt.opsForSet().add(“key”, set)
scard keyrt.opsForSet().size(“key”)
sidff key1 key2rt.opsForSet().difference(“key1”,“key2”)
sinter key1 key2rt.opsForSet().intersect(“key1”,“key2”)
sunion key1 key2rt.opsForSet().union(“key1”,“key2”)
sdiffstore des key1 key2rt.opsForSet().differenceAndStore(“key1”,“key2”,“des”)
sinter des key1 key2rt.opsForSet().intersectAndStore(“key1”,“key2”,“des”)
sunionstore des key1 key2rt.opsForSet().unionAndStore(“key1”,“key2”,“des”)
sismember key memberrt.opsForSet().isMember(“key”,“member”)
smembers keyrt.opsForSet().members(“key”)
spop keyrt.opsForSet().pop(“key”)
srandmember key countrt.opsForSet().randomMember(“key”,count)
srem key member1 member2…rt.opsForSet().remove(“key”,“member1”,“member2”,…)
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值