高并发系统设计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问
登录|注册

14 | 缓存的使用姿势(二):缓存如何做到高可用?

唐扬 2019-10-18
你好,我是唐扬。
前面几节课,我带你了解了缓存的原理、分类以及常用缓存的使用技巧。我们开始用缓存承担大部分的读压力,从而缓解数据库的查询压力,在提升性能的同时保证系统的稳定性。这时,你的电商系统整体的架构演变成下图的样子:
我们在 Web 层和数据库层之间增加了缓存层,请求会首先查询缓存,只有当缓存中没有需要的数据时才会查询数据库。
在这里,你需要关注缓存命中率这个指标(缓存命中率 = 命中缓存的请求数 / 总请求数)。一般来说,在你的电商系统中,核心缓存的命中率需要维持在 99% 甚至是 99.9%,哪怕下降 1%,系统都会遭受毁灭性的打击。
这绝不是危言耸听,我们来计算一下。假设系统的 QPS 是 10000/s,每次调用会访问 10 次缓存或者数据库中的数据,那么当缓存命中率仅仅减少 1%,数据库每秒就会增加 10000 * 10 * 1% = 1000 次请求。而一般来说我们单个 MySQL 节点的读请求量峰值就在 1500/s 左右,增加的这 1000 次请求很可能会给数据库造成极大的冲击。
命中率仅仅下降 1% 造成的影响就如此可怕,更不要说缓存节点故障了。而图中单点部署的缓存节点就成了整体系统中最大的隐患,那我们要如何来解决这个问题,提升缓存的可用性呢?
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《高并发系统设计40问》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(35)

  • 👽
    大概总结了一下:
    实现高可用的核心依旧是集群。多个缓存节点,提高容错率。
    客户端实现:由客户端的策略决定如何写缓存,如何读缓存。性能高,但是逻辑复杂,无法跨平台。
    中间件实现:所有客户端先访问中间件,然后中间件决定了缓存策略。因为引入了中间件,所以性能较差,但是可以跨平台,并且有能力的公司还可以自研中间件。
    服务端实现:主从切换由服务端实现。最大的缺点是增加了运维成本。
    不知道我的理解是否正确。

    作者回复: 是的👍

    2019-10-22
    4
  • longslee
    打卡。 老师好,提问:一致性Hash中,比如存在A(k1)、B(k2)、C(k3),3个节点,括号中为分配的Key,假如B节点剔除了,那么k2会漂移到C节点。 那么此时客户端请求get k2的时候,是被计算好从C节点获取呢,还是完全就拿不到需要去数据库查?如果是从C节点获取,那感觉命中率完全没有下降。 这一点确实没搞清楚,忘老师解惑,谢谢🙏

    作者回复: 1. 如果B节点剔除,那么K2的读写都会到C节点上
    2. 命中率会下降,因为B节点没有被删除的时候,C节点上是没有K2数据的。B节点剔除后,第一次从C节点获取K2数据是要穿透的

    2019-10-18
    2
    4
  • Hwan
    回答一下问题,如果缓存的高可用做的不够好的话,一旦线上发生故障,导致缓存直接崩了,再加上并发量比较大的话,可能会直接去访问数据库了,对数据库的压力比较大,严重的话,会导致数据库崩溃,然后就是各种丢数据,然后关于如何做的话,建议之前做好关于一些流量的评估,以Redis为例,现在有现成的哨兵和集群方案可以使用,当然也可以Codis,还有一点就是部署线上的时候可以先演练下
    2019-11-03
    2
  • 👽
    另外就客户端和服务端的理解:
    老实说一开始我也一脸懵逼。以为客户端就是用户端。
    但是后来想通了。
    应用服务器为用户提供数据接口,用户就是客户端,应用就是服务端。
    但是缓存为应用服务器提供缓存服务,这时候对于缓存服务器来说应用服务器就是客户端,而缓存就是服务端。

    作者回复: 是的 :)

    2019-10-22
    2
  • 阿卡牛
    老师,这个客户端方案中的客户端指哪里。一般我理解的客户端是浏览器或手机app...

    作者回复: 指的是你的应用服务器,是缓存的使用者

    2019-10-29
    1
  • 蓝魔丶
    老师,memcached的主从机制会考虑分片实现多个主吗,还是单机全量?多副本方案中提到会选用一个主从作为一个副本组,是一个master多个slave的结构吗?但是画图没有标示这种结构

    作者回复: 1. 会考虑分片
    2. 是的

    2019-10-25
    1
  • tyul
    老师,repcached 算不算 memcached 的服务端高可用方案

    作者回复: 算是吧~

    2019-10-18
    1
  • 张德
    老师 最近学习 这里还有一个问题 在Redis的sentinal方案中 读缓存是读Slave结点吗?? 感觉只有读Slave结点 才能实现更高的读请求性能 但是读Slave节点时 Master中的数据还没有同步过来 没有读到结果 或者读到旧数据脏数据的话 这个应该怎么解决 ??? 还是说 读请求也只能读Master结点
    2019-12-05
  • overland
    老师,那个多副本那块,是每个副本里面存着三个缓存的的热点数据还是,对应的缓存有个副本

    作者回复: 每个副本里面都有热数据

    2019-11-28
  • 布小丫学编程
    老师,Redis没有部署哨兵之前,使用集群部署。当单台服务器出现故障时,造成部分片区不可用,Redis是怎么解决这个问题的?还是根本就没解决呢?

    按老师的思路我觉得会有几种方案:
    第一种方案:Redis设置该片区不可用,然后顺延到下一个片区。
    第二种方案:运维手工解决,把这个片区划分到其他片区,也就是重新分片。
    2019-11-23
  • 天青
    老师您好,文中的多副本可以解决缓存的热点数据的问题吗?我的理解是在应用服务和缓存服务之间加本地缓存层存储热点数据,起这样吗?还有没有其他解决缓存的热点数据的方式?

    作者回复: 多副本应该可以一定程度上缓解热点数据的问题,因为它的一个主要作用就是抗流量

    本地缓存确实可以解决热点的问题

    2019-11-13
  • fdconan
    请教下,中间层代理方案和服务端方案有什么不同吗?文中没有详细说明哦。

    作者回复: 服务端方案是组件自带的,代理层是在组件之上的

    2019-11-12
  • Fourty Seven
    它将一个缓存节点计算多个 Hash 值分散到圆环的不同位置,这样既实现了数据的平均,而且当某一个节点故障或者退出的时候,它原先承担的 Key 将以更加平均的方式分配到其他节点上,从而避免雪崩的发生。
    老师,这句话啥意思了?是说把一个节点分布到多个位置?

    作者回复: 是的,因为虚拟了多个节点,这些节点会分布在圆环的多个位置

    2019-11-11
  • 张德
    老师请教一下 客户端一致性哈希算法 四到六个结点 如果四个结点的话 删除一个结点 依然会有四分之一的请求无法命中缓存 感觉这个一直性哈希算法和普通的哈希算法 没有太大区别呀 老师能不能再仔细简介一下这个地方 看不出一致性哈希算法的优势

    作者回复: 在一致性hash下,如果删除一个节点,比如在一个环上有a,b,c三个节点,b故障,那么只有b的数据会迁移到c上;但是普通hash会重新计算hash值,理论上会影响所有的数据

    2019-11-07
    1
  • 海罗沃德
    分享一個踩過的坑,在AWS上,產品經理要做一個增加搜索速度的功能,要求把最近搜過的關鍵字跟結果緩存起來,於是就通過AWS elastic cache做了一盒緩存層,然後產品經理提出我們的項目是跨region訪問的,我在A region更改數據後在瞬間開另一個瀏覽器用deep link方式從B region再訪問,都要看到數據,然而AWS的緩存不支持跨region的數據拷貝,於是這個story的failure就變成我來背鍋
    2019-11-06
  • 无形
    还没看完就想说一下我之前的做法,我们有两级缓存,服务器应用程序自身有一个内存缓存,再有Redis缓存,如果内存缓存没有命中,应用程序会创建一个单机的资源锁(go语言,用map+chan实现),大量请求进来,只有第一个请求会获取锁,其他请求获取锁失败,调用wait方法,等待第一个请求获取数据,第一个请求先从Redis中获取数据写入到内存缓存,Redis没有命中再读取MySQL,写会到Redis,执行结束后会通过close chan的方式广播消息,通知其他请求拿到了数据,从内存中读取数据,再释放锁。这样就解决了缓存穿透的问题,同一时刻,不论多大的并发量,真正到存储查询数据的请求只会有一个。

    作者回复: 其实更多的会在redis和mysql之间增加并发的控制,因为redis还是可以扛很好的并发的

    2019-11-04
    3
  • 胖胖虎
    看到老师最后的总结:
    总体而言,分布式缓存的三种方案各有所长,有些团队可能在开发过程中已经积累了 Smart Client 上的一些经验;而有些团队在 Redis 运维上经验丰富,就可以推进 Sentinel 方案;有些团队在存储研发方面有些积累,就可以推进中间代理层方案,甚至可以自研适合自己业务场景的代理层组件,具体的选择还是要看团队的实际情况而定。

    如果产品是从0开始,各方面没有太多积累,合理的选择是什么?之前我自己选的是Redis-Sentinel,因为这是官方支持的高可用模式,但是看到老师说对运维要求比较高,想了解一下需要重点关注哪些方面。
    2019-10-28
    1
  • 长期规划
    老师,我认为从另一个角度来讲,本篇分为两部分:缓存分片,主从机制。缓存分片可以客户端分,中间件分,服务端分,实现的原理我理解差不多,只是功能在的位置不同。主从机制,只能在服务端实现。
    2019-10-26
  • 扬一场远远的风
    您好,文章中有说MySql的峰值读请求是1500,请问一下这是在什么样的机器配置下?如果硬盘是Ssd,CPU也是多核,且Mysql的buffer能设置好几个G,万兆网卡的机器配置下是否还是不能超过1500?

    作者回复: 大概4核8G,机械硬盘
    如果机器配置更好,肯定能撑的读请求更高

    2019-10-25
  • 长期规划
    老师,您之前说4核8G的机器上,MySQL最高支撑QPS为1万,怎样本文开头又说MySQL读峰值才1500/s呢

    作者回复: 1万是基准测试的结果,在实际中sql更复杂,达不到这个性能

    2019-10-24
收起评论
35
返回
顶部