高并发系统设计40问
唐扬
美图公司技术专家
立即订阅
9202 人已学习
课程目录
已更新 38 讲 / 共 40 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 为什么你要学习高并发系统设计?
免费
基础篇 (6讲)
01 | 高并发系统:它的通用设计方法是什么?
02 | 架构分层:我们为什么一定要这么做?
免费
03 | 系统设计目标(一):如何提升系统性能?
04 | 系统设计目标(二):系统怎样做到高可用?
05 | 系统设计目标(三):如何让系统易于扩展?
06 | 面试现场第一期:当问到组件实现原理时,面试官是在刁难你吗?
演进篇 · 数据库篇 (5讲)
07 | 池化技术:如何减少频繁创建数据库连接的性能损耗?
08 | 数据库优化方案(一):查询请求增加时,如何做主从分离?
09 | 数据库优化方案(二):写入数据量增加时,如何实现分库分表?
10 | 发号器:如何保证分库分表后ID的全局唯一性?
11 | NoSQL:在高并发场景下,数据库和NoSQL如何做到互补?
演进篇 · 缓存篇 (6讲)
12 | 缓存:数据库成为瓶颈后,动态数据的查询要如何加速?
13 | 缓存的使用姿势(一):如何选择缓存的读写策略?
14 | 缓存的使用姿势(二):缓存如何做到高可用?
15 | 缓存的使用姿势(三):缓存穿透了怎么办?
16 | CDN:静态资源如何加速?
加餐 | 数据的迁移应该如何做?
演进篇 · 消息队列篇 (6讲)
17 | 消息队列:秒杀时如何处理每秒上万次的下单请求?
18 | 消息投递:如何保证消息仅仅被消费一次?
19 | 消息队列:如何降低消息队列系统中消息的延迟?
20 | 面试现场第二期:当问到项目经历时,面试官究竟想要了解什么?
用户故事 | 从“心”出发,我还有无数个可能
期中测试 | 10道高并发系统设计题目自测
演进篇 · 分布式服务篇 (9讲)
21 | 系统架构:每秒1万次请求的系统要做服务化拆分吗?
22 | 微服务架构:微服务化后,系统架构要如何改造?
23 | RPC框架:10万QPS下如何实现毫秒级的服务调用?
24 | 注册中心:分布式系统如何寻址?
25 | 分布式Trace:横跨几十个分布式组件的慢请求要如何排查?
26 | 负载均衡:怎样提升系统的横向扩展能力?
27 | API网关:系统的门面要如何做呢?
28 | 多机房部署:跨地域的分布式系统如何做?
29 | Service Mesh:如何屏蔽服务化系统的服务治理细节?
演进篇 · 维护篇 (5讲)
30 | 给系统加上眼睛:服务端监控要怎么做?
31 | 应用性能管理:用户的使用体验应该如何监控?
32 | 压力测试:怎样设计全链路压力测试平台?
33 | 配置管理:成千上万的配置项要如何管理?
34 | 降级熔断:如何屏蔽非核心系统故障的影响?
高并发系统设计40问
登录|注册

12 | 缓存:数据库成为瓶颈后,动态数据的查询要如何加速?

唐扬 2019-10-14
你好,我是唐扬。
通过前面数据库篇的学习,你已经了解了在高并发大流量下,数据库层的演进过程以及库表设计上的考虑点。你的垂直电商系统在完成了对数据库的主从分离和分库分表之后,已经可以支撑十几万 DAU 了,整体系统的架构也变成了下面这样:
从整体上看,数据库分了主库和从库,数据也被切分到多个数据库节点上。但随着并发的增加,存储数据量的增多,数据库的磁盘 IO 逐渐成了系统的瓶颈,我们需要一种访问更快的组件来降低请求响应时间,提升整体系统性能。这时我们就会使用缓存。那么什么是缓存,我们又该如何将它的优势最大化呢?
本节课是缓存篇的总纲,我将从缓存定义、缓存分类和缓存优势劣势三个方面全方位带你掌握缓存的设计思想和理念,再用剩下 4 节课的时间,带你针对性地掌握使用缓存的正确姿势,以便让你在实际工作中能够更好地使用缓存提升整体系统的性能。
接下来,让我们进入今天的课程吧!

什么是缓存

缓存,是一种存储数据的组件,它的作用是让对数据的请求更快地返回。
我们经常会把缓存放在内存中来存储, 所以有人就把内存和缓存画上了等号,这完全是外行人的见解。作为业内人士,你要知道在某些场景下我们可能还会使用 SSD 作为冷数据的缓存。比如说 360 开源的 Pika 就是使用 SSD 存储数据解决 Redis 的容量瓶颈的。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《高并发系统设计40问》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(22)

  • 饭团
    老师,工作中用到了redis 一旦涉及到缓存和数据库,因为涉及到2个系统,操作中就会存在谁先谁后的问题!比如写的时候是先写数据库还是redis!同理更新和删除也是类似!老师有没有什么好的方案?

    作者回复: cache aside 先写db,再删缓存

    2019-10-14
    7
    7
  • 高志强
    老师,热点本地缓存使用组件 Guava Cache ,这个东西能存多大量呢,感觉像一个数据库,还有个问题一直困扰我,像股票之类的app页面数据时时刷新,这个是怎么做到的,是否用了缓存如何使用的缓存呢,希望老师能给解答,谢谢~

    作者回复: 1.guava cache本身没有限制,注意看存大量是否对gc有影响
    2. 股票的话,应该有分布式缓存,但是这个缓存更新频率高,需要用队列削峰填谷

    2019-10-15
    3
    4
  • 布小丫学编程
    感谢老师的分享,让我知道了Java中可以使用Guava cache和Ehcache实现缓存过期的,也是对HashMap的一种补充吧。
    有个问题问一下:缓存的命中率一般怎么统计的?有什么开源工具或者框架吗?

    作者回复: guava cache可以打印统计信息的

    2019-11-19
    2
  • 长期规划
    老师,我理解分布式缓区中,每个key只有一份,无备份,对于热点查询,key所在节点的压力大。热点本地缓存相当于key在每台应用服务器都有,分散了压力,对吗

    作者回复: 不是的 热点缓存在本地,没有网络交互,会支撑更高的并发

    2019-10-24
    1
    1
  • 小喵喵
    1.多个数据库节点,指的是多台数据库服务器,每台数据库服务器部署的同一个数据库,只是每个数据库存的数据不一样吗?
    2.缓存监控如何做呢?有什么业内第三方工具或者组件吗?

    作者回复: 1. 是的
    2. 缓存有stats工具,可以接入open-falcon

    2019-10-14
    1
  • Keep-Moving
    #### 缓存的分类
    * 静态缓存
    * 分布式缓存
    * 热点本地缓存

    #### 缓存的不足
    * 适用手读多写入的场景,并且数据最好有一定的热点属性
    * 缓存会使系统更复杂,并且带来数据不一致的风险
    * 缓存通常使用内存作为存储介质,但内存是有限的
    * 缓存会增加运维的成本

    作者回复: 👍

    2019-10-14
    1
  • 被过去推开
    方便面那个比喻好评。缓存和缓冲区对应的英语是cache和buffer,buffer的存在是为了解决数据不能一次性读写完成或某次的数据量太小,io成本又太高的折中方案

    作者回复: 谢谢~

    2019-11-27
  • yuan
    老师,如果写DB完了以后,服务挂了,没有更新缓存,那也也会造成不一致,这种不一致有方法避免吗? 难不成只能等缓存失效
    2019-11-26
  • 乘坐Tornado的线程魔法师
    对于下面这段话:

    由于本地缓存是部署在应用服务器中,而我们应用服务器通常会部署多台,当数据更新时,我们不能确定哪台服务器本地中了缓存,更新或者删除所有服务器的缓存不是一个好的选择,所以我们通常会等待缓存过期。因此,这种缓存的有效期很短,通常为分钟或者秒级别,以避免返回前端脏数据。

    数据更新是指的request请求将数据库里面的数据更新吗?每个请求过来时都会带着ip地址,就算是多台服务器负载均衡的话,应该是可以根据ip确定服务器的。为什么我们无法确定哪台服务器本地中了缓存呢?这个中了缓存是指?

    作者回复: 中了缓存是指命中了缓存

    2019-11-16
  • 大卫
    老师,当调用第三方接口时,该接口是分众的,会根据mac、uid等跟用户绑定的参数去查询数据,如果并发量非常高,全部穿透到第三方接口导致访问很慢,或者第三方直接限流了,影响调用方,如果限流,只能返回一个兜底数据,算是降级了。
    这样的场景该如何优化呢?

    作者回复: 可否依据uid做一层缓存?

    2019-11-05
    1
  • 星空123
    我们项目用的全局变量。没有引入老师说的‘热点本地缓存使用组件 Guava Cache’。我们去了解下然后在项目中使用、谢谢老师
    2019-11-04
  • helloworld
    接@饭团的疑问,当涉及到更新数据库时,如何保证数据库和缓存的一致性?通过在代码中加入逻辑判断或者是异常捕获从而确认当第一步更新成功后,再进行第二步?希望老师能给出稍微具体一点点的建议。感谢

    作者回复: 可以参考一下缓存的cache aside使用方式,或者保证最终一致性

    2019-10-28
  • 👽
    没有达到需要引用缓存需要的情况下,尽量不要过早使用缓存。
    缓存的坑很多,并且维护成本极高。在处理缓存的适合需要多考虑很多问题。
    曾经碰到这样的情况:
    调用别人写的查询服务,但是查找到的数据却迟迟无法更新为最新数据。最后,重新写了直接查库的接口,才解决问题。
    并且,缓存如果频繁更新,频繁失效 反而会带来性能的消耗。

    再带上杨晓峰老师的一句话:“过早的优化是万恶之源"

    作者回复: 是的

    2019-10-17
  • 岁寒
    redis简直是中小公司的开发利器~~
    2019-10-16
  • 下面这段话的hashmap 应该是memcache

    那么我们会在代码中使用一些本地缓存方案,如 HashMap,Guava Cache 或者是 Ehcache 等,它们和应用程序部署在同一个进程中,优势是不需要跨网络调度,速度极快,所以可以来阻挡短时间内的热点查询。

    作者回复: memcache不是部署在本地的,确实是hashmap,hashmap可以作为简单的本地缓存

    2019-10-16
  • longslee
    打卡。老师好,请问服务在运行期的时候,如何临时向本地缓存HashMap里添加热点数据呢?如何在JVM中拿到这个HashMap的句柄? MyBatis算不算带被动式缓存?
    踩过的坑:缓存一定要设置TTL,55555血与泪的控诉,曾经以为自己写的清理程序可以保证,结果有bug,果断时刻发现redis内存爆炸了。

    作者回复: 其实不用监控热点数据,可以监控命中率就好了

    2019-10-15
  • 啊啊啊哦哦
    老师web层是指web服务器nginx还是应用服务器对这个概念有点模糊

    作者回复: 是指应用服务器,这个我之后注意区分

    2019-10-15
  • jc9090kkk
    感谢老师的分享,对于缓存的应用在工作中碰过这样的情况,想问下老师有没有可以推荐的建议:
    在搜索系统中,业务会将搜索的关键词+分类id+分页(前10页)+其他的筛选参数组成一个唯一key缓存到redis中,但是有时候会碰到业务变更导致当前的数据结构需要升级或者清理,所以就需要被迫的清理缓存数据,我使用的方式是升级缓存key的版本号,比如v1到v2,但是这样的方案有时候会导致服务器抖动,而且由于旧版本的缓存key非常多不好维护,只能等待旧的缓存数据自动过期同时也存在内存资源浪费的情况,对于这样的情况老师有什么好的建议或者解决办法吗?

    作者回复: 可以给缓存项设置比较小的过期时间,比如1天
    否则就要手动清理了,scan + delete
    而且缓存的内存最好是可以扩展,起码增加新的字段不需要变更key

    但是不建议这么设置缓存,不知道你这么使用的话,命中率会有多少

    2019-10-14
  • 斐波那契
    对于思考题:oracle里面的oracle instance是不是就是类似缓存的思想?或者大部分关系新数据库里“视图”的作用就有点缓存的意思

    作者回复: 嗯,可以这么说~

    2019-10-14
  • jack
    老师,分布式缓存热key的处理有好的落地方案吗?

    作者回复: 下一讲中的缓存多副本的方案可以使用,或者增加本地缓存

    2019-10-14
收起评论
22
返回
顶部