Redis总结

什么是Redis

Redis是非结构化的key-value数据库,以内存存储数据,特点是性能比较高,但一致性,安全性一般。

Redis的Key常用命令

Keys * #查看所有key
del #删除key
exists #判断key是否存在
expire #给一个key设置有效期
ttl #查看key的剩余有效期
help #查看key的具体用法

Redis的数据结构

5种基本类型:string,hash,list,set,SortedSet(zset)
3种特殊类型:GEO(坐标数据),BitMap,HyperLog(集合基数)
String:存储字符串,底层是动态的Byte数组,通过预分配减少内存的频繁分配,类似ArrayList
常用命令:set,set,setnx,setex,incr
Hash:存储键值对,底层使用了哈希表和压缩列表ziplist实现,当键值对较少时,使用ziplist实现,ziplist是一种连续的存储结构,可以节省内存空间。当键值对数量较多时,使用Hash表存储,使用拉链法解决冲突,当链表较长转换为跳表,提高查询效率。
常用命令:hset key field value,hget key field,hgetall key
List:底层数据结构使用的是快速列表QuickList,他是一种双向链表+压缩列表的结构,链表的每个节点是一个ziplist,ziplist是连续的存储结构,可以存储多个元素,可以避免大量的指针占用内存空间,提高内存的利用率。
常用命令:lpush,lpop,rpush,rpop(删除并返回)
Set:底层是hash表,类似java的hashSet。
常用命令:sadd,srem,scard(元素个数),sismember,sinter,sunion,sdiff
SortedSet:是一种排序的Set,类似java的TreeSet,在添加元素时会加上一个score用来排序,他的底层使用Hash表和跳表的数据结构,hash表的key是元素值,value是score值。跳表可以根据score给元素排序,他的底层是多层的链表,可以实现快速的查找。
常用命令:zadd,zrem,zscore,srank,zcard(获取个数)

Redis的Java客户端

Redis常用的客户端有两种,Jedis(简单)和lettuce(安全),而SpringDataRedis提供了一套API,底层可以使用Jedis或Lettuce,默认是Lettuce。

Redis实战使用

短信登录
Session方式:用户输入手机号,点击发送验证码,服务器向该手机号发送验证码(sessionID),并将验证码保存到该用户的SessionID对应的session中。用户输入验证码点击登录后,将验证码和sessionID发送给服务器,服务器对比验证码和session中的是否相同,如果相同,说明手机号有效,然后判断该手机号是否注册,如果没有注册,先自动注册用户,然后将用户信息保存到session中,然后并返回(cookie中携带SessionID)。登录校验时,拦截器拦截每个请求(线程),从session中获取用户信息,将用户信息加入ThreadLocal方便再服务中直接使用。
再Tomcat集群环境下,由于Tomcat之间不能共享session,切换到不同Tomcat时会导致session数据丢失。解决方法:使用Redis存储验证码和用户信息。
Redis方式:发送验证码时将<phone,code>保存到Redis,登录时判断code是否相同。相同则手机号验证成功,然后判断手机号是否注册,没有则注册,然后将用户信息保存到<token,user>,然后返回(携带token)。登录校验时,拦截器拦截token,从redis中查询用户,若有,将用户放入ThreadLocal,放行。

商户查询
先从Redis查询商户信息,有则返回,没有再从数据库查询,并存入Redis。
缓存更新策略:内存淘汰 超时剔除 主动更新
主动跟新最佳实践:先跟新数据库,再删除缓存

优惠劵秒杀
为优惠券生成全局唯一ID
1.先判断库存是否充足,用户是否已经下过单
2.库存-1,创建订单

并发超卖问题:使用乐观锁CAS解决
判断库存时stock=1,对库存-1时添加where stock=1

一人一单问题:利用Redis对用户ID加分布式锁(分布式锁-分布式环境下(多台机器)对共享资源的访问)set lock thread1 nx ex 10 ; del key;

使用Lua脚本实现多条Redis命令的原子性(获取锁,判断锁,释放锁)防止释放锁失败导致一直占用锁。

使用Redisson的分布式锁工具解决自定义锁存在的的问题(不可重入、不可重试、超时释放)
使用Redsson的MultiLock多节点锁解决锁所在的节点宕机问题,只要有一个节点上有锁,则不会释放。

使用Redis提升秒杀性能:
1.新增秒杀券的同时,将优惠券信息保存到Redis中,使用set保存已抢购用户
2.基于lua脚本,对Redis完成抢购
– 输入优惠券id和用户id
– 根据优惠券id判断库存是否充足,根据用户id判断是否重复下单
– 抢购成功返回0
3.如何抢购成功,将优惠券id和用户id交给Redis的阻塞队列(Stream结构)
4.后台线程从阻塞队列中获取信息,对mysql数据库进行操作,实现异步下单。

达人探店
发布探店笔记,使用Redis的ZSet存储<博客id,用户id的ZSet(sorce为时间戳)>点赞信息,实现点赞排行榜(点赞时判断用户是否在zset中)

好友关注
关注和取关:《我id,博主id》插入关系表,取关 删除关系表
共同关注:我id关注id的集合,博主id关注id的集合,求交集
关注推送:Feed流(投喂流)- 推模式/拉模式
推模式实现:
1.在保存博客到数据库时,查询所有粉丝,推送到粉丝的收件箱(粉丝id,Zset(博客id,时间戳))
2.收件箱使用Redis实现
滚动查询:每次查询时根据上一次查询的最下时间戳实现滚动查询

附近商户(GEO)
GEO(Geolocation)表示地理坐标《经度,纬度,值》,可以计算两点的距离,指定圆心半径内的值。

用户签到(BitMap)
BitMap是一个二进制数组,可以设置setbit某个位置为0或1,获取getbit指定位置的值,统计1的个数等。
用户签到时,根据《userID:yyyyMM,当月第几天》更新bitmap

UV 独立访客量统计(HyperLogLog)
hyperLogLog是一种用于基数估计的概率数据结构,可以使用很少的内存,记录非常大的集合基数,它的原理是使用的概率算法,不是存储真实的值,所以存在小于1%的误差。
核心只有两个命令:向集合添加元素,统计集合中元素的个数
PFADD hl1 e1 e2 e3 e4 d5 向HL1集合中添加5个元素
PFCOUNT hl1 统计HL1集合中的元素个数

Redis分布式缓存(Redis集群)

单点Redis的问题及如何解决:
1.数据丢失 Redis持久化
2.并发能力 Redis主从结构(读写分离)
3.存储能力 Redis分片集群
4.故障恢复能力 Reids主从+哨兵

Redis持久化
1.RDB(数据备份文件)持久化 :将Redis内存快照记录到磁盘中,故障时恢复
2.AOF(追加文件)持久化:将Redis指令的命令记录到文件中,恢复时重新执行日志文件
RDB体积小,恢复速度快,但备份速度慢,数据一致性低
AOF体积大,恢复速度慢,但备份速度快,数据一致性高

Redis主从架构 读写分离
写操作使用主节点,读操作使用从节点
使用Slaveof ip 端口 配置从节点
数据同步原理:首次建立连接时使用全量同步,将主节点的RDB复制到从节点,后续执行增量同步,将主节点的命令日志发送给从节点进行同步。

Redis主从+哨兵:主从节点故障自动恢复
当哨兵发现主节点故障时选择一个新的从节点作为主节点,当故障恢复时会成为新的从节点。

Redis分片集群:解决单个主节点写压力大的问题
分片集群数据存储:每个Redis主节点都会分片一系列slot插槽,当添加key value时,先更具key进行hash计算获得slot值,如果在自己的slot范围内,则存储,否则,进行重定向。

Redis网络模型

Redis的核心业务(命令处理)是单线程,其他的数据备份等会使用多线程。
为什么使用单线程:1.Redis内存操作,性能瓶颈不是执行速度,而是网络延迟,多线程并不会带来很大的性能提升。2.多线程存在线程安全问题,实现复杂。

Redis内存回收

过期淘汰:针对过期key的回收,常见的有两种 1.惰性清理 2.定期清理(抽样)
内存淘汰:针对内存不够时的回收,它的策略比较多,常用的有 1.TTL 2.LRU 3.LFU

Redis三大缓存问题

缓存穿透:缓存穿透是指查询的数据在Redis和数据库中都不存在,导致请求总是到达数据库,给数据库造成较大压力。
解决方法:1.缓存空对象,当访问到不存在的对象时,在Redis缓存一个空对象,当在此访问时之间返回Redis空对象,请求不会到达数据库。2.布隆过滤器,请求先经过布隆过滤器判断数据是否存在,不存在时直接返回。【布隆过滤器底层是二进制哈希表,他将数据映射到多个二进制位来判断数据是否存在,由于存在hash冲突,所有判断存在的数据可能实际并不存在,但并不影响功能】

缓存击穿:缓存击穿是热点key失效导致的,热点key就是指被高并发访问的key,在它失效并且重建期间会有大量的请求到达数据库。
解决方法:1.使用互斥锁,确保只有一个线程查询数据库更新缓存。2.设置热点key永不过期或者逻辑过期,在逻辑过期时先返回旧数据,使用另外的线程更新缓存。

缓存雪崩:缓存雪崩是指是同一时间大量的key同时失效或者Redis宕机导致请求直接访问数据库,导致数据库压力过大。
解决方法:1.给key的过期时间添加随机属性,避免同时失效。2.使用Redis集群避免单点故障。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值