缓存机制以及Redis,Redis的数据结构,缓存使用模式和经常遇到的问题。
什么是缓存?为什么要使用缓存?
主要讨论内存缓存,常见的有Redis和Memcached
- 缓解关系型数据库并发访问的压力: 热点数据。
- 减少响应时间:内存IO速度比磁盘快。
- 提升吞吐量: Redis等内存型数据库单机就可以支持很大的并发。
Redis和Memcached的区别
Redis的常用数据类型和使用场景
- 字符串(String):用来实现简单的KV键值对存储,比如计数器。
- 链表(List):实现双向链表,比如用户的关注、粉丝列表。
- 哈希(Hash):用来存储彼此相关信息的键值对。
- 集合(Set):存储不重复元素,比如用户的关注者。
- 有序集合(Sorted Set):实时信息排行榜。
Redis 数据结构内置实现
实现Redis数据类型的底层C数据类型。
字符串:整数或者sds(Simple Dynamic String 这个是Redis自己实现的一种字符串数据结构)。
链表:ziplist(压缩链表)或者double linked list。
哈希:ziplist或者hashtable(哈希表)。
集合: inset或者hashtable。
有序集合:skiplist 跳跃表。
跳跃表结构:
更多细节可以看 《Redis设计与实现》
Redis持久化
- 快照方式:把数据快照放在磁盘二进制文件中,dump.rdb 可以用来恢复数据库的状态。
- AOF(Append Only File): 每一个写命令追加到appendonly.aof中(缺点:文件比较大)
- 通过修改Redis配置来选择上述两个持久化方式。
Redis事务
和mysql事务有什么不同? mysql事务:可以看做多个SQL语句,要么全部执行成功,要么全部执行失败(回滚)
- 将多个请求打包,一次性,按序执行多个命令的机制。
- Redis 通过 MULIT(添加), EXEC(执行), WATCH等命令实现事物功能。
- python中 Redis.py pipline=conn.pipline(transaction=True)
Redis如何实现分布式锁
Redis服务器设置一个k v值,访问redis的时候,查看kv是否存在,不存在就进行操作,存在就等待或者重试。
- 使用setnx实现加锁,可以通过expire添加超时时间。
- 锁的value值可以使用一个随机的uuid或者特定的命名。
- 释放锁的时候,通过uuid判断是否是该锁,是则执行delete释放锁。
Redis缓存模式
- Cache Aside: 同时更新缓存和数据库。
- Read/Write Through: 先更新缓存,缓存负责同步更新数据库。
- Write Behind Caching: 先更新缓存,缓存定期异步更新数据库。
Redis常见问题
- 缓存穿透问题:大量查不到数据的请求落到后端数据库,数据库压力增大:比如很多无脑爬虫通过自增id的方式爬取网站,但是数据id不是自增的,Redis和mysql都没有相关的数据。
- 解决:对于没查到的返回None,None这个数据也缓存到Redis里。 插入数据的时候,删除掉缓存或者这个缓存本身设置较短时间。
- 缓存击穿问题:某些非常热点的数据Key过期,大量请求打到后端数据库(比如微博热点之类的)。
- 解决: 分布式锁,获取到锁的线程从数据库拉取数据然后更新缓存,其他线程等待。
- 解决: 异步后台更新异步任务定期对快要过期的key自动更新,然后刷新过期时间。
- 缓存的雪崩问题:大量缓存不可用或者大量Key同时失效, Redis数据库挂掉 -> 大量缓存不可用。
- 解决: 多级缓存, 不同级别的key设置不同的超时时间
- 解决: key的超时时间随机设置,防止同时超时。
- 结构层:提升系统的可用性。监控、报警完善。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2020-03-02 python的传参方式,哪些是可变对象,哪些是不可变对象?