缓存技术
比较表格
特性 | Memcached | Redis |
---|---|---|
数据类型 | 仅支持简单的key-value存储 | 支持String、Hash、List、Set、Sorted Set等复杂的数据结构 |
持久性 | 不支持持久化 | 支持RDB和AOF两种持久化方式 |
分布式存储 | 需要客户端实现 | 支持主从模式、哨兵模式、集群模式 |
多线程支持 | 单线程架构 | 多线程支持(Redis 6.0+) |
内存管理 | 自动内存管理,LRU淘汰策略 | 提供多种内存淘汰算法,如volatile-lru, allkeys-lru等 |
事务支持 | 不支持 | 支持MULTI/EXEC命令 |
数据容灾 | 数据丢失风险高 | 可通过持久化机制减少数据丢失风险 |
缓存与数据库的数据一致性问题解决方案
- 写后立即删除缓存:当更新数据库时,先删除对应的缓存项,下次读取时再从数据库加载并更新缓存。
- 延迟双删策略:在更新数据库之后立即删除缓存,然后设置一个小的延迟再次删除缓存,防止并发情况下旧数据被缓存。
- 异步队列同步:使用消息队列异步处理数据库更新后的缓存刷新。
Redis 分布式存储方案
- 主从模式:一主多从,主节点负责写操作,从节点负责读操作,提升读性能。
- 哨兵模式:监控主从节点健康状态,自动故障转移。
- 集群模式:多个主节点分片存储数据,提高可用性和扩展性。
Redis集群切片方式
- 客户端分片:由客户端自行决定数据分布到哪个节点。
- 中间件实现分片:如Twemproxy等中间件处理数据分片逻辑。
- 客户端服务端协作分片:Redis Cluster自动管理数据分片。
Redis数据分片方案
- 范围分片:根据键值范围进行划分。
- 哈希分片:基于哈希函数对键进行均匀分布。
- 一致性哈希分片:改进了普通哈希分片,减少了节点增减时数据迁移量。
Redis 数据类型
- String:最基本的数据类型,用于存储字符串或整数。
- Hash:类似Java中的Map,适合存储对象。
- List:链表结构,支持两端插入和删除。
- Set:无序不重复集合。
- Sorted Set (Zset):有序集,每个元素关联一个分数,按分数排序。
Redis 数据淘汰算法
- volatile-lru:从设置了过期时间的键中选择最近最少使用的键进行淘汰。
- allkeys-lru:从所有键中选择最近最少使用的键进行淘汰。
- volatile-ttl:从设置了过期时间的键中选择即将过期的键进行淘汰。
- volatile-random:从设置了过期时间的键中随机选择键进行淘汰。
- allkeys-random:从所有键中随机选择键进行淘汰。
- noeviction:不淘汰任何键,当内存不足时返回错误。
Redis 持久化:RDB vs AOF
特性 | RDB | AOF |
---|---|---|
文件大小 | 文件紧凑,适合备份 | 文件较大,包含所有写操作命令 |
恢复速度 | 快 | 较慢,需要重放日志 |
可靠性 | 不如AOF可靠,可能丢失最后一次快照前的数据 | 更高,可以配置fsync策略来控制可靠性 |
性能影响 | 对性能影响小 | 写操作频繁时可能影响性能 |
常见缓存问题及解决方案
-
缓存雪崩
- 描述:大量缓存同时失效导致请求直接打到数据库,造成系统崩溃。
- 解决方案:
- 随机化过期时间:为每个缓存设置不同的过期时间,避免集中失效。
- 使用互斥锁:在缓存失效时,使用互斥锁控制只有一个线程去重建缓存。
- 热点数据永不过期:对于一些关键的热点数据,设置其永不过期。
-
缓存穿透
- 描述:查询不存在的数据导致每次都要查询数据库。
- 解决方案:
- 布隆过滤器:预先过滤掉不存在的键,减少无效查询。
- 缓存空结果:对于查询不到的结果也进行缓存,并设置较短的有效期。
-
缓存预热
- 描述:系统刚启动时缓存为空,导致大量请求直接打到数据库。
- 解决方案:
- 提前加载常用数据:系统启动前预先加载常用数据到缓存中。
- 增量加载:根据访问频率逐步加载数据到缓存中。
-
缓存更新
- 描述:如何保证缓存与数据库的一致性。
- 解决方案:
- 写后立即删除缓存:更新数据库后立即删除对应的缓存项。
- 异步队列同步:使用消息队列异步处理数据库更新后的缓存刷新。
-
缓存降级
- 描述:当缓存不可用时,如何保证系统仍然能正常运行。
- 解决方案:
- 设置合理的超时时间和重试机制:当缓存服务不可用时,直接访问数据库,并记录异常日志。
- 本地缓存:在应用服务器上维护一份本地缓存,作为远程缓存的补充。
实际项目示例:在线教育平台
假设我们要开发一个“在线教育平台”,该平台需要高效地处理大量的课程内容请求、用户登录验证等操作。为了提高响应速度和减轻数据库压力,我们可以采用Redis作为缓存层:
- 使用Redis的主从模式来提升读性能,确保即使主节点发生故障也能快速切换到从节点继续提供服务。
- 针对缓存穿透问题,可以利用Redis的布隆过滤器插件(如RedisBloom)预先过滤无效请求。
- 实施合理的缓存更新策略,比如使用写后立即删除缓存的方式,确保缓存与数据库的一致性。
- 在遇到突发流量时,启用缓存降级策略,当Redis不可用时,直接访问数据库,并记录异常日志以便后续分析。
- 对于热门课程的内容,可以通过缓存预热策略,在系统启动前预先加载这些数据到缓存中,以减少启动初期的数据库负载。
通过这些措施,可以有效地提升系统的稳定性和响应速度,为用户提供更好的体验。例如,在高峰期,当大量学生同时观看同一门课程时,缓存能够显著降低数据库的压力,保证视频播放流畅,用户体验良好。此外,Redis的高级功能如事务支持、数据结构多样性等也为在线教育平台提供了更多的灵活性和优化空间。
备注:
《系统架构设计师》专栏精心整理了成为系统架构师所需的核心知识体系,涵盖以下12大关键主题:
核心特色
- 全面覆盖:本专栏内容广泛,涵盖了从基础理论到前沿技术的各个方面,确保读者能够全面掌握系统架构设计所需的各项技能。
- 精简易懂:每个主题模块经过精心优化,概念清晰、易于理解,帮助读者快速构建坚实的知识基础框架。
- 实用性强:无论是复习备考还是解决学习过程中的难点问题,专栏内容均能提供有力支持,助力读者在实际工作中灵活应用所学知识。
目标受众
本专栏专为准备软考的考生及希望入门系统架构设计领域的初学者量身打造。无论你是希望系统性学习相关知识的新手,还是需要巩固和提升已有技能的专业人士,都能从中受益。
持续更新与反馈机制
- 持续更新:专栏内容将根据最新的技术和行业趋势进行持续更新优化,确保读者始终获取最前沿的信息。
- 互动反馈:我们鼓励读者在使用过程中提出宝贵意见和建议,指出任何错误或不准确的内容。您的反馈将帮助我们不断提升资料的质量和准确性,共同提升学习体验。
通过本专栏的学习,你不仅能掌握系统架构设计的核心知识,还能在实际项目中灵活运用这些知识,助力你在系统架构设计的职业道路上不断进步。