Redis面试核心原理与数据结构使用场景

文章目录

    • Redis单线程和高性能
      • Redis单线程如何处理并发客户端连接
    • 常见5种数据结构
      • String
        • 应用场景
      • Hash
        • 应用场景
      • List
        • 两个阻塞指令
        • 应用场景
      • Set
        • 指令
        • 应用场景
          • 抽奖活动
          • 点赞,收藏,标签
          • 集合操作,微博微信关注功能模型
          • 微博微信关注功能模型
        • 购物网站商品筛选
      • ZSET
        • 集合操作
        • 排行榜

Redis单线程和高性能

所有数据都在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);采用单线程,避免了不必要的上下文切换的性能消耗。

因为Redis是单线程,所以使用Redis指令时需要注意谨慎使用耗时的指令,如keys,避免Redis出现卡顿。

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

基于IO多路复用,redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。

Redis默认最大连接数是10000:

ocalhost:6379> config get maxclients
1) "maxclients"
2) "10000"

根据官方的测试,10000连接数QPS约9000,如图:
Redis面试核心原理与数据结构使用场景_第1张图片

常见5种数据结构

字符串(String),散列(Hash),列表(List),集合(Set),有序集合(Sorted Sets)

Redis面试核心原理与数据结构使用场景_第2张图片

String

应用场景

  1. 单值缓存
set key value
get key
  1. 对象缓存
set user:1 value
mset user:1:name Cherry user:1:age 18
mget user:1:name user:1:age
  1. 分布式锁
setnx user:1 true ex 5 nx 
setnx user:1 true ex 5 nx # 

del user:1
  1. 计数器(文章阅读量,点赞等)
incr article:readCount:{id}
  1. session共享
    spring session + redis 实现分布式session共享

  2. 分布式系统全局序列号(自增id,订单id等)

incrby userId 10000

Hash

优点:

  1. 相比string操作消耗内存和cpu更少
  2. 比string节省空间

缺点:

  1. 过期功能只能设置在key上,不能作用在field上
  2. Redis集群下不适合大规模使用

应用场景

  1. 对象缓存
hmset user {userId}:name Cherry {userId}:age 18
  1. 购物车实现

用户id未key,商品id为field,商品数量为value

hset cart:{userId} {productId} productCount

假设用户id是userId1,商品id是product1:

  • 添加一件商品到购物车:

    hset cart:userId1 product1 1
    
  • 增加商品数量

    hincrby cart:userId1 product1 1
    
  • 购物车删除商品

    hdel cart:userId1 product1
    
  • 获取商品总数

    hlen cart:userId1
    
  • 获取购物车所有商品

    hgetall cart:userId1
    

List

Redis面试核心原理与数据结构使用场景_第3张图片

两个阻塞指令

blpop:从列表表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout设置成0,则一直等待。

brpop:从列表表尾弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout设置成0,则一直等待。

应用场景

  1. 实现栈和队列数据结构

栈(FILO):

lpush + lpop

队列:

lpush + rpop

阻塞队列:

lpush + brpop
  1. 微博和微信公众号发送和查看消息

场景描述:用户A关注了汽车之家和本地宝两个公众号:
1. 汽车之家推送新消息时,往用户A的消息队列插入这条消息id
lpush msg:{用户A的ID} {id}
1. 本地宝推送新消息时,往用户A的消息队列插入这条消息id
lpush msg:{用户A的ID} {id}
2. 用户A查看最新消息
lrange msg:{用户A的ID} 0 5

Set

指令

srandmember key [count]

从集合中选出count个元素,元素不从key中删除

spop key [count]

从集合中选出count个元素,元素从key中删除

应用场景

抽奖活动
  1. 参与抽奖,加入集合
sadd key {userId}
  1. 查看参与抽奖所有用户
smembers key
  1. 抽取count名中奖者
srandmember key [count]
(或spop key [count])
点赞,收藏,标签
  1. 点赞

sadd like:{messagId} {userId}

  1. 取消点赞

srem like:{messagId} {userId}

  1. 检查用户是否点赞

sismember like:{messagId} {userId}

  1. 获取点赞用户列表

smembers like:{messagId}

  1. 获取点赞用户数
    scard like:{messagId}
集合操作,微博微信关注功能模型

Redis面试核心原理与数据结构使用场景_第4张图片

交集:sinter set1 set2 set3
结果:{a}

并集:sunion set1 set2 set3
结果:{a,b,c,d,e,f}

差集(以第一个元素为基准):sdiff set1 set2 set3
结果:{b}

微博微信关注功能模型

Redis面试核心原理与数据结构使用场景_第5张图片

  1. 我关注的人
    me: {tangyan, luojin,eryingzhang}

  2. 唐嫣关注的人
    tangyan: {luojin}

  3. 罗晋关注的人
    luojin: {tangyan}

  4. 我和罗晋共同关注的人
    sinter me tangyan --> {luojin}

  5. 我关注的人也关注他(唐嫣)
    sismember luojin tangyan
    sismember eryingzhang tangyan

  6. 我可能认识的人
    sdiff luojin me

购物网站商品筛选

Redis面试核心原理与数据结构使用场景_第6张图片

如上图,通过redis维护各个筛选参数:
sadd brand:lenovo T50
sadd brand:apple macbook-pro-2020
sadd ram:16G T50 2020

sinter brand:apple ram:16G 可以查询出结果:{macbook-pro-2020}

ZSET

集合操作

  1. zunionstore destKey numberkeys key[key…]:并集计算
  2. zinterstore destKey numberkeys key[key…]:交集计算

排行榜

  1. 点击新闻
    incryby hotNews:{日期20200701} 1 {newsId}

  2. 查询排前10的新闻
    zrevrange hotNews:20200701 0, 9 withscores

  3. 查询7天搜索榜单
    zunionstore hotNews:20200701-20200707 7 hotNews:20200701 hotNews:20200702 hotNews:20200703 hotNews:20200704 hotNews:20200705 hotNews:20200706 hotNews:20200707

  4. 7天排行前十榜单
    zinterstore hotNews:20200701-20200707 0 9 withscores

你可能感兴趣的:(Redis,redis,java,数据结构)