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

125 阅读5分钟

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

1.主要内容

  • 为什么要用redis
  • 基本原理
  • 使用时候的注意事项

2.详细内容

什么是Redis

Redis (Remote Dictionary Server) 是一个开源的,基于内存的键值对存储系统

为什么需要

  • 数据从单表,演进出了分库分表
  • MySQL从单机演进出了集群
    • 数据量增长
    • 读写数据压力不断的增加
  • 数据分为冷热数据,热数据即为热点数据,经常被访问到的数据
  • 将数据存储到内存之中将大大降低数据库的压力
  • redis的优势有很多,决定性的是redis的高性能和丰富的数据类型

基本工作原理

  1. 存储:Redis 将数据存储在内存中,并提供多种数据结构,例如字符串、列表、集合、散列、有序集合等,这使得 Redis 可以存储复杂的数据结构。

  2. 哈希:Redis 将所有的数据存储在内存中,因此它需要对数据进行快速的检索和存储。它采用哈希表的方式,通过对键进行哈希映射,找到相应的数据。

  3. 多线程:Redis 是单进程单线程的,但它使用了多路 I/O 复用,这意味着它可以同时处理多个客户端的请求。

  4. 序列化:Redis 使用了一种称为 RDB 和 AOF 的序列化方式,用于将内存中的数据保存到磁盘中,以防数据丢失。

总的来说

  • 数据在内存上读写
  • 并使用AOF和RDB持久化
  • 单线程处理操作

应用

数据类型

String

底层数据结构是SDS(Simple Dynamic Strings),是一个动态字符串,内部包含了字符串本身的长度,容量以及字符串的内容

  • 优点
    • 内存分配灵活:SDS 可以根据需要自动分配内存。
    • 字符串操作简单:SDS 相比 C 语言中的字符串,操作更加简单,无需考虑内存分配问题。
    • 性能优越:SDS 的内存布局简单,直接利用指针进行字符串操作,可以有效提高性能

Hash

hash数据结构内部实际上是使用字典(dict)数据结构实现的。字典是一种用于映射键到值的数据结构,在Redis中,键与值都是字符串

  • 渐进式rehash
    • 插入新元素时同时进行rehash操作,并在此过程中不断扩大rehash的范围
    • 每次用户访问都会迁移少量数据,将整个迁移过程平摊至访问用户请求过程中

List

可以用list来做消息队列

QuickList使用双向链表和listpack实现

  • 高效:quicklist比单链表存储的双向链表更高效,因为它利用了空间局部性原理,将数据预先存储在一起,可以提高读写效率。
  • 空间高效:quicklist通过设置节点的大小,最大限度地利用了空间,可以更有效地使用内存。
  • 易于扩展:quicklist的数据结构允许动态扩展,并且可以根据需求调整存储空间大小。

zskiplist

zset数据结构使用了跳跃表(Skip List)来实现。zset数据结构是一种有序的集合,其中的元素附带有一个权重值,用来决定元素在有序集合中的排列顺序

限流

  • 使用Lua脚本:可以使用Redis的脚本功能在服务端执行一段限流脚本,控制对特定资源的访问频率。

  • 使用Redis的HyperLogLog:可以统计特定时间内的请求数量,如果超过限制的请求数,则拒绝请求。

  • 使用Redis的Bitmap:可以将每一秒的请求数都存储在一个bitmap中,然后根据bitmap的值来判断当前是否允许请求。

  • 使用Redis的原子计数器:可以对每一秒的请求数进行计数,如果超过限制的请求数,则拒绝请求。

分布式锁

并发场景,要求一次只能由一个协程执行,执行完成后,其他等待中的协程才能执行

可以使用redis的setnx实现

  • 单线程执行命令
  • setnx只有未设置过才能执行

3.实践注意事项

大Key

Value大于10KB就是大Key,复杂数据类型元素大于5000或者总value字节数大于10MB

  • 读取成本高
  • 容易慢查询
  • 主从复制异常,服务阻塞无法响应正常请求
  • 请求redis会报错

消除大Key

  • 拆分
  • 压缩
  • 区分冷热

热Key

一个Key的QPS特别高,将导致Redis实例出现负载突增,负责均衡流量不均的情况。导致单实例故障

热Key没有明确标准,QPS超500有可能就算热Key

解决热Key

  • 设置Localcache
  • 拆分
  • 使用redis访问代理

慢查询

容易导致慢查询的操作

  • 批量一次性传入过多的Key/Value
  • zset大小超过5k以上
  • 操作的单个value过大,即操作大key
  • 对大Key的delete/expire操作也有可能导致

缓存穿透、缓存雪崩

缓存穿透

当请求一个不存在的数据时,这个请求仍然会访问后端数据库,如果请求频繁,则会对后端数据库造成巨大的压力

缓存雪崩

当大量的缓存同时失效,大量的请求同时请求后端数据库,导致后端数据库压力突然猛增,从而导致数据库宕机

解决

  • 使用布隆过滤器对不存在的数据进行识别

  • 缓存空值

  • 设置缓存数据的超时时间,避免同时失效

  • 使用一致性哈希算法对缓存服务器进行负载均衡

  • 使用缓存集群

4.课后总结

  • redis是重要组件,需要熟练掌握
  • redis的底层数据结构是重点
  • redis的源码非常的优雅

5.引用

字节直播课:Redis - 大厂程序员是怎么用的

稀土掘金-后端学习资料