微博宕机背后,高并发有哪些常见问题?

上周,赵丽颖、冯绍峰结婚官宣造成微博宕机,那么回归技术,面对如此大的高并发流量和屡次崩溃的系统,作为程序员是否有较好的方法来应对及解决?在此,技术专家丁浪为我们分享了一篇缓存在高并发场景下的常见问题的文章,希望对大家有所启发:

一、缓存一致性问题

当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象。

这就比较依赖缓存的过期和更新策略。一般会在数据发生更改时,主动更新缓存中的数据或者移除对应的缓存。

二、缓存并发问题

缓存过期后将尝试从后端数据库获取数据,这是一个看似合理的流程。但是,在高并发场景下,有可能多个请求并发的去从数据库获取数据,对后端数据库造成极大的冲击,甚至导致 “雪崩”现象。

此外,当某个缓存 key 在被更新时,同时也可能被大量请求在获取,这也会导致一致性的问题。那如何避免类似问题呢?

我们会想到类似“锁”的机制,在缓存更新或者过期的情况下,先尝试获取到锁,当更新或者从数据库获取完成后再释放锁,其他的请求只需要牺牲一定的等待时间,即可直接从缓存中继续获取数据。

三、缓存穿透问题

缓存穿透在有些地方也称为“击穿”。很多朋友对缓存穿透的理解是:由于缓存故障或者缓存过期导致大量请求穿透到后端数据库服务器,从而对数据库造成巨大冲击。

这其实是一种误解。真正的缓存穿透应该是这样的:

在高并发场景下,如果某一个 key 被高并发访问,没有被命中,出于对容错性考虑,会尝试去从后端数据库中获取,从而导致了大量请求达到数据库,而当该 key 对应的数据本身就是空的情况下,这就导致数据库中并发的去执行了很多不必要的查询操作,从而导致巨大冲击和压力。

可以通过下面的几种常用方式来避免缓存传统问题:

1、缓存空对象

对查询结果为空的对象也进行缓存,如果是集合,可以缓存一个空的集合(非 null),如果是缓存单个对象,可以通过字段标识来区分。这样避免请求穿透到后端数据库。

同时,也需要保证缓存数据的时效性。这种方式实现起来成本较低,比较适合命中不高,但可能被频繁更新的数据。

2、单独过滤处理

对所有可能对应数据为空的 key 进行统一的存放,并在请求前做拦截,这样避免请求穿透到后端数据库。这种方式实现起来相对复杂,比较适合命中不高,但是更新不频繁的数据。

四、缓存颠簸问题

缓存的颠簸问题,有些地方可能被成为“缓存抖动”,可以看做是一种比“雪崩”更轻微的故障,但是也会在一段时间内对系统造成冲击和性能影响。一般是由于缓存节点故障导致。业内推荐的做法是通过一致性 Hash 算法来解决。

五、缓存的雪崩现象

缓存雪崩就是指由于缓存的原因,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难。

导致这种现象的原因有很多种,上面提到的“缓存并发”,“缓存穿透”,“缓存颠簸”等问题,其实都可能会导致缓存雪崩现象发生。这些问题也可能会被恶意攻击者所利用。

还有一种情况,例如某个时间点内,系统预加载的缓存周期性集中失效了,也可能会导致雪崩。为了避免这种周期性失效,可以通过设置不同的过期时间,来错开缓存过期,从而避免缓存集中失效。

从应用架构角度,我们可以通过限流、降级、熔断等手段来降低影响,也可以通过多级缓存来避免这种灾难。

此外,从整个研发体系流程的角度,应该加强压力测试,尽量模拟真实场景,尽早的暴露问题从而防范。

六、缓存无底洞现象

该问题由 Facebook 的工作人员提出的, Facebook 在 2010 年左右,memcached 节点就已经达 3000 个,缓存数千 G 内容。

他们发现了一个问题---memcached 连接频率,效率下降了,于是加 memcached 节点,添加了后,发现因为连接频率导致的问题,仍然存在,并没有好转,称之为”无底洞现象”。

目前主流的数据库、缓存、Nosql、搜索中间件等技术栈中,都支持“分片”技术,来满足“高性能、高并发、高可用、可扩展”等要求。

有些是在 client 端通过 Hash 取模(或一致性 Hash)将值映射到不同的实例上,有些是在 client 端通过范围取值的方式映射的。当然,也有些是在服务端进行的。

但是,每一次操作都可能需要和不同节点进行网络通信来完成,实例节点越多,则开销会越大,对性能影响就越大。

主要可以从如下几个方面避免和优化:

1、数据分布方式

有些业务数据可能适合 Hash 分布,而有些业务适合采用范围分布,这样能够从一定程度避免网络 IO 的开销。

2、IO 优化

可以充分利用连接池,NIO 等技术来尽可能降低连接开销,增强并发连接能力。

3、数据访问方式

一次性获取大的数据集,会比分多次去获取小数据集的网络 IO 开销更小。

当然,缓存无底洞现象并不常见。但无论是职场面试和高并发高流量系统的实现都离不开并发编程。因此,能够真正掌握并发编程的人正是市场迫切需求的。

原文发布于微信公众号 - GitChat精品课(CSDN_Tech)

原文发表时间:2018-10-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java工会

15个顶级Java多线程面试题及答案,快来看看吧

1615
来自专栏腾讯移动品质中心TMQ的专栏

腾讯TMQ在线沙龙回顾|接口测试用例设计

活动介绍 TMQ第四十期在线沙龙分享活动圆满结束啦! 本次分享的主题:接口测试用例设计 共有470位测试小伙伴报名参加活动。 想知道活动分享了啥吗? 请往下看吧...

4698
来自专栏程序员互动联盟

【专业技术】Node.js 究竟是什么?

简介 如果您听说过 Node,或者阅读过一些文章,宣称 Node 是多么多么的棒,那么您可能会想:“Node 究竟是什么东西?” 即便是在参阅 Node 的主页...

3317
来自专栏张善友的专栏

从APM角度上看:NoSQL和关系数据库并无不同

Michael Kopp拥有十年以上C++、Java/JEE的架构及开发经验,现Compuware技术策略师,专攻大规模产品部署的架构和性能。 以下为译文: 传...

2378
来自专栏子勰随笔

SDK设计心得之架构和资源

5164
来自专栏有趣的django

Flask构建微电影(一) 第一章、项目介绍第二章、环境搭建

2370
来自专栏cloudskyme

众推平台架构——分布式爬虫

分布式爬虫架构 经过新一轮的投票,项目的范围已经基本确定。 ? 大家决定 全力以付,集中攻克“分布式爬虫”。 分布式爬虫架构1 使用队列,即生产者,消费都模式。...

3495
来自专栏转载gongluck的CSDN博客

python笔记:#006#程序执行原理

程序执行原理(科普) 目标 计算机中的 三大件 程序执行的原理 程序的作用 01. 计算机中的三大件 计算机中包含有较多的硬件,但是一个程序要运行,有 三个 核...

41810
来自专栏编程坑太多

『高级篇』docker之微服务间如何通讯(六)

在 Web 应用中处理来自客户端的请求时,通常只考虑 GET 和 POST 这两种 HTTP 请求方法。实际上,HTTP 还有 HEAD、PUT、DELETE ...

3603
来自专栏猿学

猿学-使用Pabot并行运行RF案例

在做接口自动化时随着案例增多,特别是流程类案例增多,特别是asp.net的webform类型的项目,再加上数据库校验也比较耗时,导致RF执行案例时间越来越长,就...

970

扫码关注云+社区

领取腾讯云代金券