发布者:上海IT外包来源:http://www.lanmon.net点击数:1152
蓝盟IT小贴士,来喽!
2010年9月23日,全球最大的社交平台项目facebook遭遇最严重的停机故障之一,facebook网站于4小时后重新启动。 而且这次事故非常极端,工程师在恢复之前必须在脸书上下线。 10年前的facebook虽然没有现在这么大,但仍有10亿多用户,去推特抱怨,嘲笑这个故障。
那么,是什么原因导致了这次facebook宕机呢?
todaywemadeachangetothepersistentcopyofaconfigurationvaluethatwasinterpretedasinvalid.thismeantthateverysingleclientsawthine alidvalueandattemptedtofixit.becausethefixinvolvesmakingaquerytoaclusterofdatabases,thatclusterwasquicklyoverwhelmedbundatases,thatcluerwasquicklyoverwhelmedbundattes
由于错误的配置更改,大量的请求破坏了缓存,直接到达了数据库。 这种现象称为缓存stampede,维基地址: https://en .维基百科. org /维基/缓存_ stampede。 这在技术行业是一个非常普遍的问题,很多公司发生了同样的事故,很多工程师为了不让自己的项目遇到这样的问题做了很多工作。
1、什么是高速缓存踩踏
cache stampede是指许多线程试图并行访问缓存。 如果不存在要访问缓存的数据,线程通常会请求获取数据库所需的数据(因此,cache stampede可以翻译为缓存的踩踏)。 与缓存透明略有不同,Cache Stampede的重点是许多线程透明缓存)。
高速缓存踩踏破坏的主要原因是故障雪崩,也就是故障和下一个故障。这些请求将落到数据库中,因为大量的线程并发请求没有从缓存中获取数据。
数据库因恐怖的CPU故障而发生大量超时错误。
请求线程在收到超时后,继续重试请求,造成了新的灾害。
重复,无限。
另外,即使没有Facebook那样的规模,无论规模如何都会面临这个问题。 这个问题一直困扰着初创公司和科技巨头。
2、阻止缓存踏入的方法
这是个好问题。 在这篇文章中,我们将探索各种各样的战略来缓解或阻止缓存的踩踏发生。 毕竟,在自己的服务出现问题之后,我不想学习如何预防。
2.1添加缓存
一个简单的方法是添加更多的缓存。 其原理类似于操作系统的多级缓存。 操作系统使用缓存层(L1、L2、L3 )以实现更快的访问。 参考操作系统,你也可以在你的应用程序中引入多级缓存。
在高并发系统中,阻止共享资源冲突的方法通常是锁定。 虽然锁定通常是同一台计算机上使用的不同线程,但也可以使用分布式锁定来应对不同计算机上共享资源的冲突(redis分布式锁定: 3358 redis.cn/topics/dist lock.h 。
通过锁定缓存密钥,同时只有一个调用方可以访问争夺缓存。 如果KEY不存在或已经过期,调用方将获得锁定。 此时,其他冲突的处理线程必须等待释放该锁定。
如果通过锁定解决此问题,还会引入另一个问题,即系统如何处理等待锁定释放的所有线程。
您是否想尝试旋转锁定(spinlock )并继续轮询这些线程以获取锁定? 这出现了非常busy的场景,会消耗大量的CPU。 或者,在检查锁定是否可用之前让线程随机等待? 这样的话,你又会遇到惊人的群体效应问题(thundering herd problem )。
引入退避和抖动机制,防止惊讶吗? 这可能行得通,但还有一个问题。 具有锁定的线程必须重新计算值,并在释放锁定之前更新缓存密钥。 这个过程可能需要时间。 特别是在计算成本较高或存在网络问题的情况下,如果可用于计算高速缓存的连接池耗尽,则可能会发生停机。
2.3 Promises防止旋转的方法
引用instagram工程师博客(Thundering Herds Promises )的内容:instagram,启用新集群,集群内的缓存为空,因此会遇到缓存stampede的问题。 届时,我们将通过promises解决这个问题。 其中心思想是缓存最终提供所需值的promise,而不是缓存实际值。 使用缓存时,如果遇到不存在的密钥,不立即对数据库进行查询,而是创建promise并将其放入缓存。 此高速缓存中的promise查询数据库,其他并发请求发现此promise不发送请求到数据库,然后等待带有第一个线程的promise查询数据库。
文/上海蓝盟 IT外包专家
分享到: