可伸缩架构简短系列

采取什么办法可以让一个Web服务可大规模可扩展?相信你会对这个问题感兴趣。

克隆

通常来说,公共服务器上的一个可伸缩的web服务总是隐藏在一个Load Balancer(负载均衡器)之后。这个负载均衡器会将负载(来自用户的请求)均匀的分配到一组服务器或者服务器集群。那意味着什么?举个例子:某个用户访问你的服务,他第一次的请求可能会由第二台服务器提供,第二次请求由第9台服务器提供,第3次请求又再次由第二台服务器提供。

对于该用户而言,他每次得到的结果应该是一样的,不依赖服务到底是哪台服务器提供的。这个正是可伸缩性的第一个黄金法则:每个服务器都包含完全相同的代码库,不在本地磁盘或内存存储任何与用户相关的数据,如session或用户信息。Session需要集中存储,使得每一台服务器都可以访问到它。它可以是一个外部数据库或外部持久缓存,比如Redis。相比外部数据库,在持久化的缓存中存放session将会有更好的性能。这里提到的“外部”指的是数据存储不放置在这些应用服务器上,而是在接近您的应用程序服务器的数据中心。

但是这要怎么部署呢?你如何确定当应用代码发生了改变能够发送到所有的服务器而没有一台服务器依旧使用之前的代码?幸运的是,这个棘手的问题已经被一个很好的工具capistrano解决了,你需要稍微学习了解下。

在解决了session和多台服务器上新版本的同步更新问题之后,你需要做的就是克隆你的机器镜像了,然后将你最新的代码部署上去。可以参考Amazon提供的AMI服务(Amazon Machine Image)

现在你的服务器可以水平扩展,并且处理成千上万的并发请求了。

数据库

但是你发现应用程序变得越来越来最终崩溃。问题的原因:是MySql,不是吗?
现在不是增加更多的机器可以解决的问题了,你有两种办法:

  • 1,坚持使用MySql,并且让它运行良好。做主从复制(从服务器负责读取,主服务器负责写入),并且升级主服务器,不断加入更多的内存。随着不断优化,你会使用数据库分片、反规模化、SQL调优等常用手段。这时,对于数据库的任何一个操作成本都会变得相当昂贵。
  • 2,切换到一个更加容易扩展的NoSQL数据库,比如 MongoDB或CouchDB,连接查询现在需要在应用代码层里去进行了。

现在,你的数据库有了一个可扩展的解决方案了,你再也不用担心存储TB级的数据,世界看起来那么的美好。

缓存

当大量的数据请求发往到数据库,你发现又变慢了,解决办法是增加缓存。
这里说的缓存指的是内存缓存,比如常见的内存数据库Memcached或者Redis ,千万不要使用文件缓存,它会让你服务器的克隆和自动伸缩很痛苦。

但是回到内存缓存,缓存是一个简单的键值存储并且应该介于应用程序和数据存储。任何时候当你的应用程序需要去读取数据时,它首先应该尝试从缓存里面获取数据,只有无法从缓存中读取数据时,才会尝试从数据库中读到。为什么要这么做呢?因为缓存快如闪电,它将数据集存放在内存中,并且可以快速的被处理。举个例子:Redis没秒钟可以处理成千上万的读操作。

访问流程:第一次访问绿色,第二次和之后的蓝色:

有两种缓存数据的模式,一种是老的方式,一种是新的方式:

  • 1,缓存数据库查询,这个仍然是最普遍的缓存方式,当你做一次查询时,将数据集进行缓存,通过哈希后查询串作为键。下一次查询时,检查缓存中是否有结果。这种方式存在一些问题,最主要的问题就是过期。当数据表中的一块数据发生变化时,你需要删除所有包含这个数据块的查询串的缓存。
  • 2,缓存对象,我强烈推荐使用这种方式,这也是我经常使用的。

一些适合缓存的对象:

  • 用户Session(永远不存放在数据库中)
  • 完全呈现的博客文章
  • 活动流
  • 用户<- -> 朋友 之类的关系

异步

请想象一下,你想在你最喜欢的面包店买面包,所以你走进面包店,向一个店员询问购买面包,但是面包都卖光了。你被告知2个小时之后你订的面包可以好,这个很恼人,不是吗?
为了避免这种“请等片刻”的场景,需要采取异步。比如什么时候有面包了,店员会将面包派送给你的家里。通常来说,有两种异步的范例:

  • 1,让我们回到普通的买面包的场景,第一种异步处理流程是:“晚上把面包都烹制好,第二天早上卖”,这个对于顾客来说不需要等待。对于一个web应用程序,这意味着提前做耗时的工作,这样就可以在短时间处理完工作。通常这种模式用来将动态的内容转换为静态内容。比如提前渲染好CMS里面的一些网页,并且本地存储这些HTML文件。采用定时任务,可能是通过脚本叫做每小时的计划。这种对通用数据预先计算可以极大的提升网站和web app的可伸缩性和性能。可以通过脚本将这些预先渲染好的HTML页面发布至CDN。你的网站将能做到响应超快并且每小时可以处理成千上万的游客!
  • 2,回到面包店,有的时候顾客可能会有一些特殊的需求,不然在面包上加上“生日快乐”等装饰。面包店并不能提前知道这种顾客类型的需求,所以当顾客来到店里后,必须马上开启一个任务并且告诉他:”你明天再来吧!“ 对于web而言,这意味着异步任务。这里有一个典型的工作流:一个用户来到你的网站,开始一项计算密集型任务,这个任务需要花费几分钟来完成,所以网站前端会往任务队列里面发送一个任务,并且告诉用户你的任务已经在处理中了,你可以继续浏览网页了。一个任务队列会不断的被处理任务的workers 检查处理。如果有一个新任务,work会处理这个任务,过了几分钟之后会发送一个处理完毕的消息信号。前端会不断的检查(比如轮询)这个任务是否已经处理完,一旦处理完则通知用户。如果你想更深入了解,推荐你去看看RabbmitMQ),Rabbit MQ是一个实现了异步消息队列的优秀中间件。你也可以使用ActiveMQ或者一个简单的Redis list,异步消息队列看起来很复杂,但是它值得你花时间去学习和实现。

如果你做一些耗时的操作,试着采用异步。

时间: 2024-08-28 06:13:48

可伸缩架构简短系列的相关文章

我也要谈谈大型网站架构之系列(3)——死了都要说的缓存

说到缓存,我想大家跟我一样都很兴奋,当我们遭遇网站性能瓶颈的时候,缓存是一剂强心针,也是一粒紧急妈富隆,从而在优化网站 性能方面冠上了第一定律的帽子,我们前年在做淘应用的时候,就遭遇了性能瓶颈,短时间内采用缓存紧急优化,给我们大优化之前争取了 宝贵的时间. 一:缓存的种类 要说缓存有多少种,太多了,比如浏览器缓存,文件缓存,片段缓存,数据库缓存等等,合理利用这些缓存则能大幅度的提高系统性能, 利用不好反而会偷鸡不成蚀把米,给服务器造成巨大的压力,所以这里就存在一个缓存的使用原则的问题. 二:合理

MVVM架构~knockoutjs系列之扩展ajax验证~验证输入数据是否与后台数据相等

返回目录 在看这篇文章之前,你有必要先看我之前的文章,之前文章是将一个方法以参数的形式传给KO,然后返回一个真假值,去做验证,这类似于面向对象语言里的委托,在JS里我们叫它回调方法,本篇文章与前一文章不同,需要有两个参数,其一是远程方法的签名(JS方法),其二是已知要比较的数据(可能是加密后的密码数据),当用户输入文字后,它将会调用JS方法获取远程数据,以比较原数据与你输入的数据是否匹配. 知识点:以对象作为参数进行传递 ko.validation.js的扩展 //ajax相等验证 kv.rul

七牛李道兵:高可用可伸缩架构实用经验谈

七牛李道兵:高可用可伸缩架构实用经验谈 移动互联网.云计算和大数据的成熟和发展,让更多的好想法得以在很短的时间内实现为产品.此时,如果用户需求抓得准,用户数量将很可能获得爆发式增长,而不需要像以往一样需要精心运营几年的时间.然而用户数量的快速增长(尤其是短时间内的爆发式增长),通常会让应用开发者有些吃不消,不得不面临一些严峻的技术挑战:如何避免因为单台机器当机导致服务不可用:如何避免在服务容量不足时,用户体验下降,等等.在系统构建之初就采用高可用和可伸缩架构,将能有效避免这些问题. 如何构建高可

【PC网站前端架构探讨系列】关于中小型PC网站前端架构方案的讨论与实践

 说在前面 好几天没更新这个系列文章了,这段时间还是在研究这块东西,遇到的各种奇葩问题,最后写完,只是调试就花了两天,果然发现在和大神之间的距离越来越远,在加上大部分时间在追求自己的梦想,梦想同样也是遥遥无期啊!一直在思考星星的那句话,人到底该不该追求梦想,做个咸鱼到底好不好的,吃吃喝喝睡睡的,反正最近感悟挺多,抽时间写个文章,好好和大家聊聊,把我的心里话告诉大家,程序员不容易,寻梦者更难啊!比如,这个所谓的pc网站的前端框架,这对一个做后台而且还是多年一直在做C#.JAVA没怎么写脚本的我来说

OAF_OAF架构MVC系列 - Control的概述(概念)

2014-06-18 BaoXinjian 一.摘要 Control层位于Model层和View层的中间,连接了Model层和View层, 主要存在两个功能 操作/初始化UI和数据 接受和处理页面上的用户的各种事件,并进行分发 本文的基本结构 Designand Create an OA Controller - 基本概念和建立 Handling an HTTP GET - 如何处理HTTP GET请求 Data层面 - 进行初始化 WebBean层面 WebBean层面 - 动态修改WebBe

OAF_OAF架构MVC系列 - View的概述(概念)

2014-06-18 BaoXinjian 一.摘要 上文介绍在OAF按MVC的架构,分为三层,即Model-View-Contorl, 对OAF 的View层的一下基本概念和一些小案例 Page - 页面概述 Page的关键属性 Item的关键属性 Reusable Components - 可重用组件 控件的继承Extend 控件的共享Shared Attribute Sets - 控件属性组 通过Item的Attribute Set 属性手工设定 通过attrSet.setAttribut

我也要谈谈大型网站架构之系列(4)——分布式中的异步通信

我也要谈谈大型网站架构之系列(4)--分布式中的异步通信 我们知道在面向对象编程中,总会想着各种办法来实现代码的解耦,从而让项目中的各种人员面对自己熟悉的业务进行开发, 做到术业有专攻,比如大家非常熟悉的三层架构,MVC,MVP以及MVVM模式,让前端设计专注于html的制作,让后端开发人员 更加专注于业务逻辑的编写,可以看到,我们这么做的目的就是想最大程度的做到系统的可扩展和可维护性,那么我们的大型网站 是不是也要遵守这种模式呢? 一:分层和分割 1:分层 对于分层,我们可能非常熟知了,数据访

我也要谈谈大型网站架构之系列(2)——纵观历史演变(下)

这篇文章本来准备前几天就得写的,谁也没想到这段时间公司的RC太多了,含酸苦逼的加班,加班...所以在大一点的公司上班, 写代码的责任心一定要强,或许就因为你的一些小bug,给公司带来不少损失...这在以前公司真的没多大体会的. 好了,继续说说架构的演变,从第四代架构中可以看到,我们通过做应用程序层的负载均衡可以比较完美的解决了在整个架构中让应 用程序层不再成为瓶颈,通过A10,我们可以让用户的访问请求分发到集群中的任何一台服务器上,当访问量继续膨胀的时候,我们就可 以继续在集群中增加服务器来解决

高可用可伸缩架构实用经验谈

移动互联网.云计算和大数据的成熟和发展,让更多的好想法得以在很短的时间内实现为产品.此时,如果用户需求抓得准,用户数量将很可能获得爆发式增长,而不需要像以往一样需要精心运营几年的时间.然而用户数量的快速增长(尤其是短时间内的爆发式增长),通常会让应用开发者有些吃不消,不得不面临一些严峻的技术挑战:如何避免因为单台机器当机导致服务不可用:如何避免在服务容量不足时,用户体验下降,等等.在系统构建之初就采用高可用和可伸缩架构,将能有效避免这些问题. 如何构建高可用和可伸缩架构呢?七牛云存储首席架构师李