Redis| 青训营笔记

64 阅读2分钟

这是我参与「第五届青训营 」笔记创作活动的第12天。

Redis

什么是Redis

为什么需要Redis

  • 数据库从单表到分表分表
  • Mysql从单机演变到集群:数据量增长、读写压力大
  • 数据分冷热:将热数据储存在内存中

image.png

Redis原理

  • 从内存中读写数据
  • 数据保存到硬盘防丢失
  • 单线程处理命令

image.png

应用案例

连续签到

用户每日有一次签到机会,若签到成功,则累积签到加一,若断签,则清零。
使用redis过期

func addContinuesDays(ctx context.Context, userID int64) {
   key := fmt.Sprintf(continuesCheckKey, userID)
   // 1. 连续签到数+1
   err := RedisClient.Incr(ctx, key).Err()
   if err != nil {
      fmt.Errorf("用户[%d]连续签到失败", userID)
   } else {
      expAt := beginningOfDay().Add(48 * time.Hour)
      // 2. 设置签到记录在后天的0点到期
      if err := RedisClient.ExpireAt(ctx, key, expAt).Err(); err != nil {
         panic(err)
      } else {
         // 3. 打印用户续签后的连续签到天数
         day, err := getUserCheckInDays(ctx, userID)
         if err != nil {
            panic(err)
         }
         fmt.Printf("用户[%d]连续签到:%d(天), 过期时间:%s", userID, day, expAt.Format("2006-01-02 15:04:05"))
      }
   }
}

消息通知

List数据结构:QUICKLIST
双向链表+ListPack实现:

image.png

listpack可以包含多个元素,达到节省内存的作用。

计数

一个用户有多个数据需要计数,可以使用hash结构存储
若使用数据库表记录,性能过差,查询效率低

hash结构

image.png

排行

zset结构

跳跃表: image.png

增强链表的访问速度,通过跳跃表实现。将长链分成多条子链。

而zset是跳跃表加hash的实现方式

image.png

分布式锁

要求并发场景下,多个协程只能有一个协程执行,执行完成后,其他等待中的协程才能执行。
利用了redis中的两个特性:

  1. Redis单线程执行命令
  2. setnx只有未设置过才能执行成功

注意事项

大key和热key

string:认为value大于10KB的叫大key
Hash、set、list等复杂数据结构,元素大于5000或者总value大于10MB则认为是大key

大key的危害:

  1. 读取慢
  2. 容易导致慢查询(过期)
  3. 主从复制异常服务阻塞

用户访问某数据频率很高,可以认为是热key

image.png

处理方法:localCache

慢查询

  1. 批量传入过多查询
  2. 大key
  3. zset过大导致性能下降

缓存穿透/缓存雪崩

缓存穿透:热点数据查询绕过缓存直接查询数据库
缓存雪崩:大量缓存同时过期

解决方法:返回控制、布隆过滤器

小结

本节课程主要讲述了三个方面问题:为什么需要Redis,Redis的基本工作原理、Redis应用案例以及在字节跳动,使用Redis有哪些注意事项。