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

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,如图:
在这里插入图片描述

常见5种数据结构

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

在这里插入图片描述

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 <!-- 返回1代表获取锁成功,加"ex 5 nx"是为了防止程序中断了导致死锁 -->
setnx user:1 true ex 5 nx # <!-- 返回0代表获取锁失败,加"ex 5 nx"是为了防止程序中断了导致死锁 -->
<!-- ... 执行业务代码 -->
del user:1
  1. 计数器(文章阅读量,点赞等)
incr article:readCount:{id}
  1. session共享
    spring session + redis 实现分布式session共享

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

incrby userId 10000
<!-- 每个服务批量获取id,不需要频繁操作redis -->

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

在这里插入图片描述

两个阻塞指令

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}
集合操作,微博微信关注功能模型

在这里插入图片描述

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

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

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

微博微信关注功能模型

在这里插入图片描述

  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维护各个筛选参数:
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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值