这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天
1.主要内容
- 为什么要用redis
- 基本原理
- 使用时候的注意事项
2.详细内容
什么是Redis
Redis (Remote Dictionary Server) 是一个开源的,基于内存的键值对存储系统
为什么需要
- 数据从单表,演进出了分库分表
- MySQL从单机演进出了集群
- 数据量增长
- 读写数据压力不断的增加
- 数据分为冷热数据,热数据即为热点数据,经常被访问到的数据
- 将数据存储到内存之中将大大降低数据库的压力
- redis的优势有很多,决定性的是redis的高性能和丰富的数据类型
基本工作原理
-
存储:Redis 将数据存储在内存中,并提供多种数据结构,例如字符串、列表、集合、散列、有序集合等,这使得 Redis 可以存储复杂的数据结构。
-
哈希:Redis 将所有的数据存储在内存中,因此它需要对数据进行快速的检索和存储。它采用哈希表的方式,通过对键进行哈希映射,找到相应的数据。
-
多线程:Redis 是单进程单线程的,但它使用了多路 I/O 复用,这意味着它可以同时处理多个客户端的请求。
-
序列化: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 - 大厂程序员是怎么用的
稀土掘金-后端学习资料