我们先来看一个 use case 流程:
下面我们来详细说说,图中的各个部分是用来干什么的
DNS 是域名服务器。它类似于一个 hash table,把域名映射到 IP 地址。类比一下我们常见的通讯录,是把人名映射到电话号码一样。
当然,很多大公司的域名会被映射到很多不同的 IP 地址。现在不展开讲解。
中文里一般叫做 负载均衡。在讲这个之前,我们需要来说说 horizontal vs. vertical scaling。
Scaling 是指扩展,当网站的需求量大于了网站的接纳能力时,网站需要 scale out。Vertical scaling(纵向扩展),是通过扩大一台服务器的硬件能力来扩展,比如加硬盘,加内存,加 CPU。但它的问题在于,它很容易达到上限。想象现在单块硬盘的容量才多大。而 horizontal scaling(横向扩展),是通过增加服务器的数量来扩展。这显然比 vertical scaling 的上限要高得多。以 Storyblocks 为例,现在有 150 - 400 台 AWS EC2 在运行。而这不可能由一台巨大的服务器来完成。
在网站架构中,一个稍微大点的网站肯定会做 horizontal scaling。这还有助于避免 single point of failure(也就是当一台服务器挂了的时候,网站不会整个挂掉)。换句专业术语说,网站变得 fault tolerant。
Horizontal scaling 的另一点好处是,可以 decouple server 之间的职能。网站可以按照 web server, database, cache, service X 等来划分。(而且,还可以由不同的 team 来管理不同的 server,从而影响公司的组织结构,译者注)。
Load balancing 简单说就是把请求合理的分配给服务器,比如不让某台服务器特别忙而其他的特别闲。这就要求 load balancer 所管理的这些 server 要能按照完全一样的工作方式工作。一个 request 不管被分配到哪台 server,它所返回的结果应该完全一样。
另外,有些 request 是跟用户相关的。同一类型请求来自不同用于,所返回的结果也不同。这时 load balancer 该如何处理?这样的问题叫 sticky session problem
Web server 可以说是用户做业务逻辑请求的入口。所以一般 web server 会和后端 services 进行通讯。为了避免 single point of failure,一般再小的网站,web server 也应该至少两台,如果预算允许的话。
web server 所使用的技术,一般是 MVC 或者 MVP web framework。常见的 web framework 所使用的语言可以是 node.js, ruby, php, python, java, c# .NET 等等。
Database 提供对数据的增删查改,一般称为 CRUD(create, read, update, delete)。在 microservices 架构中,很多 service 会有属于自己的 database。这样做的原因也是为了 decouple。
这里主要提两个技术:不严谨的说叫做 SQL vs. NoSQL。严谨一些,应该叫做 relational database vs. non-relational database
SQL 是 relational database 最流行的语言,所以一般也用来代指了这类 database。它擅长处理 data entities 之间的关系,比如一对一,一对多,多对多。
更多关于 SQL 的细节,我个人推荐 W3Cschools 的 SQL 教程。
而 NoSQL,泛指所有 non-relational database,其实是有很多不同类型的。它们很多都不擅长处理 data entities relation。但它们有自己擅长的。有的是能存储更大量的数据,比如 mongodb,有的是擅长处理 key value storage,比如 redis,有的擅长处理地理数据,比如 neo4j。所以 relational database 并不是架构中 database 的唯一选择。
Cache (缓存) 就是将常用的数据存储在一个单独的地方,这个地方一般来说提供了更快速的硬件,可能比硬盘快 10 倍以上。而 database 一般存储在硬盘上,所以 cache 的读取速度远快于 database。
Cache 理论上可以存储任何类型的数据,不过一般大家经常存储的是 key value pair、文件、渲染好的 page、复杂的 data query 的结果等等。
一些例子:
Job 是指在后台异步处理的工作。Job 出现的原因是,比如按照 request 压缩一张图片。这个任务可能需要 1 秒。如果在 web server 上进行,那么这台 web server 可能在 1 秒内不能接受其他 request,或者至少是影响 web server 的性能。这对于流量很大的网站是不可接受的。所以有了 job server 来异步处理 job。当 job 完成后,job server 会以某种方式通知其他 server。
再举个例子,google 每时每刻都要关注世界上其他网站每天发布的新的页面,抓取页面并 index。这些都是在他的 job server 上进行的。
Job queue 一般由两个部分组成,一个部分是 queue 本身,另一个是 worker,用于执行 job。
最简单的 job queue 就是一个 FIFO 的数据结构。你也可以使用 priority queue 来实现,如果你的 job 有 priority 的话。
这个技术是,用户提供一个 text query,service 返回相关结果。它们一般通过一个 inverted index(反向索引) 技术 来实现。
比如说,我们在网站的搜索条里输入 man
,网站应该返回所有含有词语 man
的网页。
确实,我们可以使用 database 自带的 full-text search 功能实现,比如 mysql 和 postgres 都支持。但是更多时候我们会使用专门做 full-text search 的工具来实现,比如 elasticsearch, sphinx 或 apache solr。
一般当网站大到一定规模后会发现,把所有业务逻辑放在一起并不方便开发、部署、管理。近年来流行的 microservices architecture 就是把不同类型的业务服务切分到不同的 services 里面,各自开发管理。各个 services 之间可以进行数据交流。
比如在 Storyblocks,我们有这些 services:
数据对于公司来说,在当下就是命根子。data pipeline 负责搜集、存储、分析数据。
一个典型的 data pipeline 的有 3 个阶段:
云存储,是指把一些原本放在比如 web server 上的文件放到云端,比如 AWS S3 上。通常静态不怎么修改的文件都会放在 cloud storage,比如 video, photo, audio, css, javascript 等等
CDN 的基本原理是,通过将文件在世界各个不同地区的服务器 ( edge server ) 上,来提高在不同地区加载文件的速度。用户在加载文件时,CDN 服务会自动选择从最近的服务器上加载。而文件,一般是由网站主动式的将文件传到 CDN 上。
这篇文章更详细的讲解了 CDN。