中午吃饭刷着刷着微博发现微博忽然挂了。我一开始觉得是家里网很差,后来换了流量刷仍是刷不出内容,而且报error,我就知道微博应该是挂了。往朋友圈一看,原来是鹿晗和关晓彤微博互圈“宣布恋情”了。要不是之前看过《好先生》这部剧没准我还真不认识关晓彤。陆地cp前几天不是还在炒着吗?怎么这么忽然?诶..贵圈贼乱啊。程序员
做为一名程序员,我更感兴趣的是微博如何应对瞬时涌来的高并发大流量。从好久好久之前文章马伊琍的“周一见”,到后来“出轨队”、“吸毒队”的争相夺分,再到前段时间的郭敬明事件、薛之谦事件,再到今天的鹿晗宣布恋情......微博看似每次都在挂,一直都没有进步,你们每次遇到热点事件刷不出内容的时候都会吐槽微博的应用平台很辣鸡。可是呢,微博的后台系统确定一直在重构升级优化,我以为可以作到今天这种水平已经很不错了。算法
从用户的角度(主要是个人角度hhhhh)来看数据库
遇到热点事件的时候微博大几率在短期内(大约10~15)可能会彻底刷不出内容,过了一段时间以后(大约半小时)进行间隔刷新(间隔10秒左右),有可能某些时候会看到5xx的error,5开头的http状态码表明服务器或者是网关存在问题,好比说服务器拒绝链接、网关超时或者是应用代码存在bug等都会致使5xx的错误。在热点事件发生1小时内,系统应该能够恢复正常的服务。缓存
从网站开发、运维人员的角度来看服务器
- 运维:卧槽?怎么访问流量这么高?是出啥bug了吗?卧槽!不会是又有人出轨吸毒了吧?emmmm....个人国庆假期可还没结束啊!
- 运维:兄弟们,快醒醒!快加机器啊!系统要崩了!
- 开发:别催!再催自杀!
- leader:测试在扩容以后赶忙拉出来测测!
- 测试:人在家中躺,锅从天上来!
上面都是我乱说的!cookie
为何我以为微博在高并发大流量访问方面的表现已经很不错了呢?举个例子吧:淘宝每一年在双11购物节的时候也要应对高并发的场景,可是这是能够提早作不少准备的,好比说提早购买带宽资源、增长服务器资源、进行完备的异地容灾等等,不少都是可预测的。而微博呢?热点事件随时均可能发生,因此这对于微博的运维工程师来讲是很大的考验。固然,如今的运维平台也是很是的智能了,能够对各项指标进行实时监控,一有异常,立刻进行短信或者邮件报警,以后就是各个岗位的工程师人肉上场调配各种资源了。网络
那微博在平时为何不增长一些服务器资源呢?session
服务器资源、网络带宽资源等既重要,又昂贵。因为并非每时每刻都必须应对高并发的场景,所以若是说在平时增长了冗余的服务器资源致使大量机器空载,也是一种很大的浪费。咱们在考虑提供可用服务的同时,也必须考虑一下成本。架构
原本我开始写这篇博客的时候就是想回顾一下本身之前学习过的大型网站高可用架构相关知识。可是因为高性能、伸缩性、拓展性与高可用性密不可分,因此我写着写着就感受写不下去了。想写的东西太多了,有点不知道从哪里开始写。因此下面我就针对高可用性架构中常常会提到的几个点来说讲。并发
不论是对于小型网站仍是大型网站来讲,分层都是必须的:粗粒度的分层通常为应用层、业务层和数据层。横向分层以后,可能还会根据模块的不一样对每一层进行纵向的分割。拿微博举例,我以为它的评论模块和点赞模块应该是解耦的。越是复杂的系统,横向和纵向的分层分割粒度就会越细。不少时候你用起来觉得它就是一个系统,其实后面多是由几百上千个独立部署的系统对外提供服务。
集群在大型网站架构中是一个很是很是重要的概念。因为服务器(不论是应用服务器仍是数据服务器)容易发生单点问题,一旦一台服务器gg了,就必须进行失效转移。
通常来讲,应用服务器必须是无状态的。什么叫无状态服务器呢?在介绍它以前,咱们先来讲一下状态服务器:状态服务器通常会保存请求相关的信息,每一个请求会默认地使用之前的请求信息。这样就很容易致使会话粘滞问题:若是一台状态服务器宕机了,那么它保存的请求信息(例如session)就丢失了,可能会致使不可预知的问题。
那么相对的,无状态服务器就不保存请求信息,它处理的客户信息必须由请求本身携带,或者是从其余服务器集群获取。所以无状态服务器相对于状态服务器来讲更加地健壮,就算是重启服务器甚至是服务器宕机都不会丢失状态。由此引伸出来的另外一个优势就是方便扩容:只要在增长的服务器上部署相同的应用并作好反向代理就能对外提供正常的服务。
既然应用服务器是无状态的,那么用户的登陆信息(session)如何管理呢?比较常见的有下面四种方式。可是因为前三种都有很大的局限性,这里只聊聊基于集群的session服务器管理方式。
咱们在这里是将服务器的状态进行分离:分为无状态的应用服务器和有状态的session服务器。固然,这里说的session服务器确定说的是session服务器集群。咱们能够借助分布式缓存或者是关系型数据库来存储session。对于微博来讲,这里确定得用分布式缓存了:由于用关系型数据库的话数据库链接资源容易成为瓶颈,而且I/O操做也很耗时间。比较常见的K-V内存数据库有Redis。我以为微博内容中的赞数、用户的关注数和粉丝数用Redis来存应该算是比较合适的。
既然提到了集群,确定得说说负载均衡。可是感受负载均衡应该能够归类到可伸缩性里面去,因此这里就不详细讲啦,就简单说说有哪些常见的负载均衡的方式以及负载均衡算法。
忽然想到一个比较有意思的东西:在微博的架构中,应该采用的是异步拉模型而不是同步推模型。什么意思呢?咱们举个例子:鹿晗的粉丝有3000多万,关晓彤的粉丝有1000多万。假如他俩发了条微博的同时须要往这4000万粉丝的内容列表中(假设这里用的是关系型数据库)推送过去,这就是简化的同步推模型。
那这样有什么缺点呢?首先,这样会消耗大量的数据库链接资源,更重要的是这样不太符合软件设计规范:由于对于两人的粉丝来讲,分别由有3000多万和1000多万的数据是冗余的。假如说陈赫、邓超在第一时间对他俩的微博进行了点赞,此时瓶颈就来了:刚才往数据库里插入4000多万感受还能够接受,可是如今四人的粉丝数加起来好几亿了,同时往数据库插这么多数据是否是感受不太合适?
不要紧,咱们如今换一种内容推送方式:咱们如今不用同步推了,而是用异步拉。咱们每次在手机上刷微博的时候,若是想要看到更新的内容是否是都要下拉刷新获取?没错这就是异步拉。异步拉有什么好处呢?很明显的一个好处就是能够将热点数据进行集中管理,而且不用进行大量的数据插入冗余操做。另外对系统资源的消耗也较少。那么微博内容从哪里拉呢?主流的解决方案是把热点内容放到缓存中,每次都去查缓存,这样能够减小I/O操做而且避免发生因资源枯竭形成的超时问题。
PS:写到这里的时候我开始水群了,如今回过头来继续写感受无法儿写下去了。过久没写博客了,不少知识略有遗忘。不过今天算是在脑海中把相关的东西梳理了一下,由于毕业设计也打算作高并发大流量相关的东西。今天算是蹭蹭热点顺便复习一下之前学过的知识吧~
其实高可用性架构还包括服务升级、服务降级、数据备份、失效转移等等。关于网站高可用、高性能、高拓展方面感受其实还有不少不少东西来写。可是有些知识没有必定的实践经验呢,又不能很好的掌握。那么就等我后面再慢慢聊吧~
最后,打个广告:以前一直在简书上写技术博客,可是慢慢地感受简书杂七杂八的内容太多了,一点也不纯粹。打算之后休闲娱乐的东西就放到简书上写吧,技术博客慢慢会转移到掘金的阵地上来了。关注简书做者-EakonZhao