这是我参与「第五届青训营 」伴学笔记创作活动的第7天
Redis是什么
为什么需要Redis
-
传统互联网业务是一个简单的web Server
-
随着数据量增长,读写数据压力不断增加,数据从单表演进出了库分表,MySQL从单机演进出了集群
-
随着压力越来越大,像高QPS查询MySQL支撑不住,因此如果把数据存到内存中,则会加快数据IO速度
- 经常访问的数据称为热数据
- 热数据放在Redis中,冷数据放到MySQL中
binlog记录MySQL数据的变更,同步Redis和MySQL只需要把binlog变更的数据写入Redis中就行
Redis基本原理
- Redis在内存中存储数据,内存很大的问题是重启服务器数据会丢失,但是Redis的一个重要特征则是其数据一定程度上做到持久化
- Redis是单进程处理系统
两条命令同时到达但是顺序执行
Redis应用
-
连续签到
- 使用了数据的过期处理连续签到场景,即累计连续签到天数,断签则把签到天数归零
- String数据结构
- 数据结构学到什么程度呢?
实际工作中应用到某个功能时能够知道为啥使用这个数据结构,为啥这个数据结构能提高性能或者压缩存储就可
- 特点:
- 存储时足够节省空间
- 快速读取
- 字符发生变更时快速写入数据
- 实现
-
消息通知
使用list作为消息队列
-
list数据结构quicklist
-
-
计数-hash实现
- 如下业务场景
读取掘金文章被点赞数,如果把被点赞信息存到MySQL表中,被点赞一次存储一行记录,读取被点赞数时count该表,如该例,则需要count10693次记录,这还是一个用户需要count的数量,如果同时有100人访问,则服务压力很大
所以这些数据最好存在redis里,如果使用key来存这些数据如关注数,点赞数,阅读数等待,返回需要一个key一个key的返回,会很慢,最好能打包返回,因此使用hash
如上,只需要get userid就能取出这些数据
- 那么怎么一次性io多条数据呢-pipeline打包
- hash数据结构
拉链很长时,需要扩容,同时还需要保证正常响应,会触发渐进式rehash
- 如下业务场景
-
排行榜
-
需求
玩游戏场景,榜单上依据玩家战力排名,每个区有一个统一的榜单,用户数量是千万级别
-
MySQl实现
一个表存储一千万条数据,数据记录了用户的userid和积分,每次用户访问排名的时候,按照积分倒排,这种解决方案对单个用户访问没问题,但是访问的QPS很高的时候服务器就会挂了
-
Redis特别适合该业务场景实现-zset数据结构
-
skiplist
如下链表,要取"7"则需要跳跃7次,时间复杂度是o(7)
有没有更快的方法?-使用跳跃表,把数据链分成许多子链
-
redis使用了跳跃表加hash的数据结构
- 使用hash方便查找key
- 跳跃表通过backward实现双向链表,backward指针指向前序节点,方便排序
- obj指针指向hash表
-
-
限流
防止出现恶意刷单之类对网站不利的行为,要求一秒内放行的请求为N,超过N则禁止访问
时间戳的计数单位是秒,因此只需要统计相同时间戳内超过N的key禁止访问即可
-
分布式锁
要求一次只能有一个协程执行,执行完成后,其他等待中发协程才能执行
- 场景
考虑如下场景,秒杀业务中,产品库存为1,但是两个协程抢到了锁,因此产品被超卖
- 实现
使用redis的setnx,利用了
- Redis是单线程执行命令,所有并行请求都会顺序执行
- setnx只有在这个key未设置过的情况下才能执行成功
setnx不能做成高可用的分布式锁,如:
- 某请求某情况下很长时间无法执行完,那么后续的请求都抢不到锁
- redis主备切换临界点问题,主备切换后,A在主库的锁写进去了,但是在从库可能还没写进去,这个时候客户端访问从库是可以拿到锁的
- redis集群脑裂,出现多个主节点,那么也会导致并发的请求
- 场景
Redis使用注意事项
-
大key
- 危害
因为redis是顺序执行的,因此io大key会导致很多问题
- 大key处理方法
-
拆分
-
压缩
-
使用集合类结构
-
- 危害
-
热key
- 处理方法
-
设置localcache
-
拆分
风险:一个key的更新需要写多个redis实例,如果更新失败,会出现key不完整的问题
-
redis代理
如果每个业务都实现一个localcache显然是不合理的,因此使用redis代理localcache
与localcache不同,其实现由proxy完成,而不是业务端
-
- 处理方法
-
慢查询
慢查询容易导致每个实例访问速度慢,同时可能导致集群崩溃,因此需要避免慢查询
-
缓存传统,缓存雪崩
由于业务的发展,发现MySQl扛不住了,因此使用redis,如果redis服务宕机,则大量请求直接打到数据库上,出现缓存穿透,由于数据库访问很慢,则容易使数据库宕机。缓存雪崩则是大量key同时过期,即缓存失效,这时请求也会直接落到数据库中
-
减少缓存穿透
-
减少缓存雪崩
-