Redis-大厂程序员怎么用 学习笔记 | 青训营

90 阅读6分钟

redis学习笔记

为什么需要redis

  1. 数据量增长,读写压力大
  2. 数据从内存直接读取很块
  3. 所以把热数据(经常访问的数据)存到内存中(redis),冷数据放在redis中
  4. 读场景,先去redis找,找不到再找redis
  5. 写场景:直接写到mysql,监听binlog再写入到reids中,或者同时进行写

redis基本原理

  1. 数据从内存中读写
  2. 数据保存到硬盘上防止重启数据丢失
  3. 增量数据保存到AOF文件
  4. redis-client通过RESP协议写入服务进程,然后读写内存
  5. appendonly.aof,写入日志,服务器宕机,redis也能读取出来

image.png RDB,保存所有实例的文件

启动先读取RDB,再对比有没有没执行的命令,有再加载AOF中的未执行命令,保持和上一次状态一致

redis,单线程处理所有操作命令。即是同时发送给了redis几个命令,redis也会顺序处理。

Redis应用案例

连续签到、消息通知、计数、排行榜、限流、分布式锁

1.连续签到案例

掘金用户每日签到,断签签到计数归零

使用string数据结构

  1. Key cc_uid_id
  2. Value 签到计数
  3. exprieAt:过期时间

签到一次,value增加,更新expireAt值

redis中,string是二进制安全的,节省空间,可以快速读取,能很快进行读写,字符变更时,也能很块写入

image.png

数据存储有四段

  1. 数据存入buf,会同时多分配一些空间(避免扩写时的扩容)
  2. key会指向sds的位置,会从flags读取数据类型
  3. alloc,为分配的实际空间
  4. 从len读取实际写入的空间

2.消息通知

掘金:用户写文章更新推送到ES,用户就能搜索到最新的文章数据。让ES引擎知道,即通过消息通知。

image.png 写了13 12 10 三篇文章,希望文章开头能监听到文章变化,如果有变化就读取出来推送到ES中去。

redis的list数据结构:Quicklist

由一个双向链表和listpack实现

image.png

entry——listpack

为了合理节省内存,redis会在一个节点上存储了多个数据

这里把数据压缩到了listpack中:开辟大内存空间,存了多个元素,会告诉有多少个元素,每个元素从哪开始

3.计数

可以通过hash记录一个用户的多项计数需求

比如一个用户有文章被点赞数、被阅读数、关注数、关注者、收藏集、关注标签数

每个数字都一个key会操作很多次,打包到hash中会方便很多

pipeline,可以打包发送执行多个redis数据,减少网络传输

hash结构

image.png

rehash操作,数据进行迁移,同时保证正常被访问数据

渐进式rehash,每次用户访问,都迁移少量数据,将整个迁移过程,平摊到所有访问过程中。

4.排行榜

zset实现,用来排序,实时变更

zskiplist数据结构,实现通过key操作跳表的功能

image.png

跳跃表还结合了hash,便于查询

redis中,找一个元素一般不超过四层

5.限流

1秒内放行的请求为N,超过则禁止访问

redis的key作为一个key,每访问一次,就incr,到了时间就进制访问

也是string类型

6.分布式锁

一次只能使用一个协程执行,执行完成后,其他等待中的协程才能继续

可以使用setnx实现,setnx

只有未设置的key才能执行成功,同时,一次一个线程执行,保证锁住

并不是高可用的分布式锁

Redis使用注意事项

大Key、热Key

value的字节数大于10kb就是大key

复杂数据类型 hash、set、zaset元素个数大于5000,或者总value字节数大于10MB就是大key

大key会使读取成本高、查询慢、主从复制异常、服务阻塞、无法正常响应请求

如果业务侧重使用大Key则可能会使redis超时报错

消除方法:

把大key拆分为小key,把value压缩,然后写入redis

一般如果压缩解决不了才使用拆分方法

redis一般写少,读多

热key,访问一个key的QPS特别高,导致Server实例出现CPU负载突增或者分布不均的情况

热key没有明确标准,QPS超过500就有可能是热key

可以设置Localcache,降低对Redis的QPS。Java的Guava、Golang的Bigcache就是这类的cache

也可以进行拆分,把一个热key复制写入多分,不过代价是需要更新多个key,存在数据短暂不一致

慢查询

导致redis查询慢

  1. 一次性传入过多的key/value(pipiline)一次最好不要超过100个
  2. zset命令,大小超过5k以上,也可能慢查询
  3. 操作的单个value过大
  4. 对dakey的delete/expire也可能导致慢查询

缓存穿透、缓存雪崩

缓存穿透:热点数据查询绕过缓存,直接查询数据库

缓存雪崩:大量缓存同时过期

缓存穿透:

查询一个一定不存在的数据,通常不会缓存不存在的数据,这类请求一般会直接发送到db,容易导致宕机

缓存过期时

一个热key如果过期,可能有大量请求同时击穿到db,影响db性能和稳定

缓存控制,如果在缓存和数据库中不存在,缓存一个控制,下次可以避开

布隆过滤器,存储合法的key,只需要极小的空间存储大量的key

缓存雪崩:

将失效时间分开,或者给不同的key过期时间设置不同的过期时间,这样过期时间可以分散

使用缓存集群,避免一个宕机造成系统宕机

总结

本文记录了课程的一些知识点,对于redis的使用,我们其实也就是根据合适的应用场景去使用合适的数据结构,在使用的过程中,注意需要缓存的一些注意事项即可

redis为了贴合实际运用场景也有很多特殊的类型,比如地理相关的类型,我们根据我们实际需要选择即可。

redis相对于mysql来说,更适合高速读取,我们使用redis做缓存能加快处理速度,而关系型数据库更适合做持久层,能进行复杂化的操作