分享好友 资讯首页 资讯分类 切换频道

从1到1100万用户的架构演变

2016-05-31 17:3743390
  如果你是资深AWS用户,那场演讲不适合你,但如果你刚接触AWS,刚接触云计算,或者无力跟上亚马逊不断推出的一大批新功能,这不失为一篇入门指南。

  你可能也料到了,由于这是亚马逊人的演讲,亚马逊服务始终是解决任何问题的最主要办法。亚马逊的平台架构令人叹为观止,颇有启发性。从各部分彼此整合的情况来看,很显然,亚马逊在这方面做很到位:识别用户要求,然后确保拿出满足要求的产品。

  一些值得关注的心得如下:

  从SQL开始入手,只在确有必要时迁移到NoSQL。

  一个一致的主题是,拿来组件后将它们分开来。这让那些组件可独立扩展,出现故障后不影响其他组件。这个原则适用于分解各层、构建微服务。

  只致力于从事为贵公司带来差异化优势的任务,不做重复性工作。

  可扩展性和冗余性不是两个独立的概念,这两方面常常可以同时做到。

  基本概况

  AWS服务全球各地的12个地区

  地区是指亚马逊有多个可用性区域(Availability Zones)的物理位置。地区范围覆盖:北美、南美、欧洲、中东、非洲和亚太。

  可用性区域(AZ)通常是单单一个数据中心,不过它们可能由多个数据中心构成。

  每个AZ彼此分得很开,各自有独立的电力和互联网连接。

  AZ之间的唯一连接就是低延迟网络。比如说,两个AZ可能相隔5英里或15英里。低延迟网络的速度很快,快得应用程序运行起来如同所有AZ都在同一个数据中心。

  每个地区有至少2个可用性区域。总共有32个AZ。

  使用AZ,有可能为你的应用程序构建高可用性架构。

  2016年会新增至少9个可用性区域和4个地区。

  AWS在全球共有53个边缘位置

  边缘位置被亚马逊的内容分发网络(CDN):CloudFront和亚马逊的托管DNS服务器:Route53使用。

  边缘位置让用户能够访问内容,延迟非常低,不管用户在世界上的什么地方。

  模块构建服务

  AWS已构建了许多服务,这些服务在内部使用多个AZ,确保高可用性和高容错性。这里(https://aws.amazon.com/cn/about -aws/global-infrastructure/regional-product-services/)列出了在各地可使用什么样的服务(http://docs.aws.amazon.com/general/latest/gr/rande.html)。

  你可以将这些服务用在你的应用程序中,要付费,没必要为自行确保高可用性而担心。

  AZ里面存在一些服务:CloudFront、Route 53、S3、DynamoDB、弹性负载均衡(Elastic Load Balancing)、EFS、 Lambda、SQS、SNS、SES和SWF。

  即便服务存在于单一AZ里面,也可以使用这些服务来构建高可用性架构。

  1个用户

  在这种场景下,你只有1个用户,你想让网站运行起来。

  你的架构看起来就像这样:

  在单一实例(可能是类型t2.micro)上运行。实例类型包括:不同组合的处理器、内存、存储和网络资源,让你可以灵活地选择适合具体应用的资源组合。

  单一实例将运行整个Web堆栈,比如说:Web应用程序、数据库和管理等。

  使用亚马逊Route 53作为DNS服务器。

  将单一的Elastic IP地址连接到该实例。

  在一段时间里,运行顺畅。

  纵向扩展

  你需要更庞大的系统。最简单的扩展方法就是选择一个更大类型的实例。比如说,可能是c4.8xlarge或m3.2xlarge。

  这种方法名为纵向扩展(vertical scaling)。

  只要停止运行实例,选择一个新的实例类型,就可以运行起来,拥有更强的处理能力。

  诸多组合的不同硬件配置可供选择。你可能拥有配备244GB内存的系统(2TB内存类型很快会推出),或者配备40个核心的系统。有High I/O实例、High CPU实例和High storage实例可供使用。

  一些亚马逊服务随带Provisioned IOPS选项,以保证性能。其想法是,你可能为自己的服务使用比较小的实例类型,充分利用能提供可扩展服务的亚马逊服务(比如DynamoDB),那样你没必要操心。

  纵向扩展有个大问题:没有故障切换机制,没有冗余性。如果实例有问题,你的网站就完蛋了。好比你的所有鸡蛋都放在一只篮子里。

  最终,单一实例支持的规模很有限。你需要采取别的做法。

  用户数量> 10

  把单一主机分成多个主机:

  一个主机用于网站。

  一个主机用于数据库。运行你需要的任何数据库,但是你得负责数据库管理。

  使用独立的主机让网站和数据库可以完全彼此独立扩展。比如说,也许数据库需要的机器比网站需要的来得庞大。

  你可以使用数据库服务,而不是运行自己的数据库。

  你是数据库管理员吗?你果真要想为备份操心吗?高可用性?补丁?操作系统?

  使用服务的一大优点是,只要点击一下鼠标,就能设置好一套多可用性区域数据库。没必要为复制或任何这种事务操心。你的数据库将具有高可用性和高可靠性。

  正如你所料,亚马逊在出售几种全面托管的数据库服务:

  亚马逊RDS(关系数据库服务)。有好多选择:微软SQL Server、Oracle、MySQL、PostgreSQL、MariaDB和亚马逊Aurora。

  亚马逊DynamoDB:一种NoSQL托管数据库。

  亚马逊Redshift:PB级数据仓库系统。

  亚马逊Aurora方面的详情:

  存储容量可自动扩展至64TB。你再也不必为数据配置存储容量。

  多达12个读取副本(read-replica)。

  持续(增量)备份到S3。

  横跨3个AZ的6路复制。这可以帮助你处理故障。

  与MySQL兼容。

  从SQL数据库开始入手,而不是NoSQL数据库。

  建议从SQL数据库开始入手。

  这项技术很成熟。

  有许多的现成代码、社区、支持组织、图书和工具。

  你的头1000万个用户不会搞坏SQL数据库。根本不会(除非你的数据很庞大)。

  清晰的可扩展模式。

  你什么时候需要从NoSQL数据库开始入手?

  如果你在一年内需要存储超过5 TB的数据,或者面临数据超密集型的工作负载。

  应用程序要求超低的延迟。

  需要很高的吞吐量。你需要改动在读取和写入操作方面获得的输入/输出。

  你没有任何关系数据。

  用户> 100

  使用单独的主机用于Web层。

  将数据库存储在亚马逊RDS上。它会处理一切事务。

  你要做的就这些。

  用户> 1000

  设计架构时,你的应用程序就存在可用性问题。如果用于Web服务的主机出现故障,你的网站就瘫痪。

  所以,你需要在另一个可用性区域的另一个Web实例。这没问题,因为AZ之间的延迟很低:只有几毫秒,就好像这些AZ几乎彼此相邻。

  你还需要RDS的从属数据库在另一个AZ中运行。要是主数据库出了问题,应用程序就会自动切换到从属数据库。故障切换时没有必要更改应用程序,因为应用程序始终使用同一个端点。

  弹性负载均衡器(ELB)被添加到配置中,在位于两个AZ的两个Web主机实例之间实现用户负载均衡。

  弹性负载均衡器(ELB):

  ELB是一种高可用性的托管负载均衡器。ELB存在于所有AZ中。它是面向你应用程序的单一DNS端点。只要把它放入到Route 53,它就会跨Web主机实例实现负载均衡。

  ELB会进行健康检查(Health Checks),确保流量没有传送到出现故障的主机。

  它能自动扩展,你啥都不用做。如果它看到额外流量,会在后台进行横向扩展和纵向扩展。你没必要管理它。你的应用程序扩展时,ELB也会随之扩展。

  用户> 10,000 -100,000

  前一种配置在ELB后面有2个实例,实际上你可以在ELB后面有1000个实例。这是横向扩展。

  你需要为数据库和RDS添加更多的读取副本。这将为写入主数据库卸掉负载。

  将一部分流量移到别处,从而为你的Web层服务器减轻负载,从而提高性能和效率。将你Web应用程序中的静态内容转移到亚马逊S3和亚马逊CloudFront。CloudFront是亚马逊的CDN,负责将数据存储在全球各地的53个边缘位置。

  亚马逊S3是一种基于对象的存储系统

  它不像EBS,也不是连接到EC2实例的存储系统,它是一种对象存储系统,不是块存储系统。

  它很适合存储静态内容,比如javascript 、css、图像和视频。这种内容不需要放在EC2实例上。

  高度耐用,可用性达到99.999999999%。

  可无限扩展,你想添加多少数据就可以添加多少。客户将数PB数据存储在S3中。

  支持最大为5TB的对象。

  支持加密。你可以使用亚马逊的加密、你自己的加密技术或加密服务。

  亚马逊CloudFront缓存你的内容。

  它在边缘位置缓存内容,为用户提供延迟最低的访问服务。

  没有CDN,用户访问内容时会遇到更高的延迟。服务器也会面临更高的负载,因为它们不仅要处理Web请求,还要提供内容。

  一个客户需要以60 Gbps的速度提供内容。CloudFront处理一切,Web层甚至不知道发生了什么。

  你还可以将会话状态从Web层转移出去,以此减轻负载。

  将会话状态存储在ElastiCache或DynamoDB中。

  这种方法还让系统可以在将来支持自动扩展。

  你还可以将来自数据库的数据缓存到ElasticCache中,减轻负载。

  你的数据库不需要处理所有的数据获取。缓存能处理许多这方面的工作,让数据库处理更重要的流量。

  亚马逊DynamoDB:托管型NoSQL数据库

  你配置所需的吞吐量。可以增加想要支付相应费用的读取和写入性能。

  支持快速、稳定的性能。

  完全分布式和容错。它存在于多个可用性区域中。

  它是键值存储系统。支持JS ON。

  支持最大为400KB的文档。

  亚马逊Elasticache:托管型Memcached或Redis

  管理memcached集群并不让你赚更多钱,所以让亚马逊为你做这件事。这是亚马逊的营销口号。

  集群自动为你扩展。它是自愈合基础设施,如果节点出现故障,就会自动启动新节点。

  你还可以将动态内容转移到CloudFront,以此减轻负载。

  许多人知道CloudFront能处理文件之类的静态内容,但它也能处理动态内容。这个话题在本演讲中没有作进一步探讨,不过这里有个链接(https://aws.amazon.com/cloudfront/dynamic-content/)。

  自动扩展

  如果你配置足够的容量,以便始终处理峰值流量负载(比如黑色星期五),无异于在浪费钱财。

  更明智的是,让计算能力与需求相一致。这就是自动扩展(Auto Scaling)让你能做到的事,即自动调整计算集群的大小。

  你可以定义资源池的最大值和最小值。用户得决定集群中最小数量的实例和最大数量的实例分别是多少。

  CloudWatch是一种嵌入到所有应用中的管理服务。

  CloudWatch事件驱动扩展。

  想在处理器利用率方面进行扩展吗?想在延迟方面扩展吗?想在网络流量方面扩展吗?

  你还可以将自己的自定义衡量指标纳入到CloudWatch中。如果你想在针对特定应用的方面进行扩展,可以把该衡量指标纳入到CloudWatch中,然后告诉自动扩展机制你想在该衡量指标方面进行扩展。

  用户> 500,000+

  与前一个配置相比增添的是,自动扩展组添加到Web层。自动扩展组包括2个AZ,但可以扩展到3个AZ,不仅提供可扩展性,还提供可用性。

  一个例子是在每个AZ中有3个Web层实例,但可以是数千个实例。你可以说想要最少10个实例,最多1000个实例。

  ElastiCache用来卸载来自数据库的常见读取。

  DynamoDB用来卸载会话数据。

  你需要添加监控、衡量和日志机制。

  主机层衡量指标。看一下自动扩展组里面的单一处理器实例,查清楚什么出了岔子。

  总计衡量指标。看一下弹性负载均衡器上的衡量指标,了解整批实例的性能。

  日志分析。使用CloudWatch日志,看一看应用程序告诉你了什么。CloudTrail可帮助你分析和管理日志。

  外部站点性能。从最终用户的角度了解客户看到什么样的性能。使用New Relic或Pingdom之类的服务。

  你要了解客户有什么样的评价。延迟很差劲?他们在访问网页时遇到了错误?

  从你的配置获得尽量高的性能。自动扩展在这方面有所帮助。你不希望系统的处理器利用率只有20%。

  自动化

  基础设施变得庞大,它可以扩展到上千个实例。我们有读取副本,有横向扩展,但需要某种自动化工具来帮助管理这一切,我们可不想管理每一个实例。

  自动化工具有层次结构:

  自己动手:亚马逊 EC2和AWS CloudFormation。

  更高层服务:AWS Elastic Beanstalk和AWS OpsWorks

  AWS Elastic Beanstalk:为你的应用程序自动管理基础设施。它使用方便,但没有太多的控制。

  AWS OpsWorks:这是一种种环境,你可以在其中构建层次化的应用程序,可使用Chef配方(recipe)来管理应用程序的层次。

  另外启用进行持续集成和持续部署的功能。

  AWS CloudFormation:历史最久。

  提供最大的灵活性,因为它为你的堆栈提供了模板化视图。它可以用来构建你的整个堆栈,或者只构建堆栈的部分。

  如果你想更新堆栈,只要更新Cloud Formation模板,它会更新你应用程序的某一个部分。

  很大的控制度,但不太方便。

  AWS CodeDeploy:将代码部署到一批EC2实例。

  可部署到1个或上千个实例。

  Code Deploy可指向自动扩展配置,那样代码可以部署到一组实例。

  还可以与Chef和Puppet结合使用。

  解耦/分离基础设施

  使用SOA/微服务。从你的诸层拿来组件后,把它们分开来。比如将Web层与数据库层分开来时,构建独立的服务。

  单个服务随后可以独立扩展。这为你在扩展方面提供了极大的灵活性,还有高可用性。

  SOA是亚马逊构建的架构的一个重要部分。

  松散耦合(Loose coupling)彻底解放了你。

  可以让组件独立扩展,出现故障后不影响其他组件。

  如果某个worker节点没有从SQS获取work,这严重吗?没啥关系,只要启动另一个节点。难免会出现故障,不妨构建一种可处理故障的架构。

  将一切设计为黑盒子。

  解耦/分离交互关系。

  偏爱内置冗余性和可扩展性的服务,而不是构建自己的服务。

  不做重复性工作

  只致力于从事为贵公司带来差异化优势的任务。

  亚马逊有许多服务天生具有容错性,因为它们横跨多个AZ。比如说:队列、电子邮件、转码、搜索、数据库、监控、衡量、日志和计算。你没必要自行构建这些服务。

  SQS:队列服务。

  提供的第一种亚马逊服务。

  它横跨多个AZ,所以具有容错性。

  它具有可扩展、安全又简单等优点。

  队列可帮助你在基础设施的不同部分之间传输消息,从而帮助基础设施。

  以照片内容管理系统(CMS)为例。收集并处理照片的系统应该是两个不同的系统。它们应该能够独立扩展。它们应该松散耦合。获取照片后放入到队列中,worker就能从队列中获取照片,并进行相应处理。

  AWS Lambda:让你不用配置或管理服务器,就可以运行代码。

  让你可以解耦/分离应用程序的出色工具。

  在照片CMS这个例子中,Lambda可以响应S3事件,那样S3文件添加后,Lam

  bda的处理功能就自动被触发。

  我们丢弃了EC2。它可以为你向外扩展,没有操作系统要管理。

  用户> 1,000,000+

  获得超过100万个用户需要所有上述几点:

  多个AZ

  层与层之间的弹性负载均衡。不仅仅在Web层上,还要在应用层、数据层及拥有的其他任何层上。

  自动扩展

  面向服务的架构(SOA)

  使用S3和CloudFront,智能化提供内容

  把缓存放在数据库前面

  从Web层移走状态

  使用亚马逊SES发送电子邮件。

  使用CloudWatch来监控。

  用户> 10,000,000+

  随着规模变得更大,我们会在数据层遇到问题。你可能会开始遇到数据库方面的问题:与负责写入的主数据库争夺资源,这基本上意味着你向一台服务器发送的写入流量很有限。

  你如何解决这个问题?

  联合(federation)

  切分(sharding)

  把某种功能移到其他类型的数据库(NoSQL和图形数据库等)

  联合:根据功能分成多个数据库

  比如说,构建论坛数据库、用户数据库和产品数据库。之前你可能把这些功能统统都放在一个数据库中,现在将它们分开来。

  不同的数据库可以彼此独立扩展。

  缺点:你无法执行跨数据库查询;这就引出了下一个策略:切分。

  切分-横跨多个主机来分割一个数据集

  应用层更为复杂,但可扩展性方面实际上没有限制。

  比如说,在用户数据库中,三分之一的用户可能被派到一个分片,三分之一被派到另一个分片,剩下三分之一被派到另一个分片。

  将某种功能移到其他类型的数据库

  开始考虑NoSQL数据库

  如果你的数据不需要复杂的合并,比如说选手积分榜、快速获取点击流/日志数据、临时数据、热表、元数据/查询表,那么可以考虑改用NoSQL数据库。

  这意味着,它们可以彼此独立地扩展。

  用户> 1100万

  扩展是个迭代过程。你规模变大后,总是能够做更多的事情。

  对应用程序进行微调。

  用更多的SOA来处理特性/功能。

  从多AZ进入到多地区。

  开始构建自定义解决方案,以解决你面临的、别人之前没有遇到过的特定问题。如果你需要服务于10亿个客户,就需要自定义解决方案。

  深入分析整个堆栈。

  回顾

  使用多AZ基础设施来确保可靠性。

  充分利用自扩展服务,比如ELB、S3、SQS、SNS和DynamoDB等。

  在每个层面融入可靠性。可扩展性和冗余性不是两个独立的概念,这两方面常常可以同时实现。

  从传统的关系SQL数据库开始入手。

  基础设施内外的数据都要缓存。

  在基础设施中使用自动化工具。

  确保已落实了良好的衡量/监控/日志机制。确保弄清楚客户从你的应用程序得到什么样的体验。

  将诸层分成单个服务(SOA),那样它们就能彼此独立地扩展,出现故障后不影响其他服务。

  一旦作好准备,就使用自动扩展。

  不做重复性工作,使用托管服务,而不是自行编写服务,除非绝对有必要这么做。

  如果有必要的话,改用NoSQL。
举报
收藏 0
打赏 0
评论 0