English ∙ 日本语 ∙ 简体中文 ∙ 繁体中文 | ∙ বাংলা ∙ 巴西葡萄牙语 ∙ 德语 ∙ ελληνικά ∙ עברйת ∙ 意大利语 ∙ 한국어 ∙ فר ∙ 波兰语 ∙ русский язык ∙ 西班牙语 ∙ ภาษาไทย ∙ 土耳其语 ∙ tiếng 越南语 ∙ 法语 |添加翻译
帮忙翻译一下这个指南!
了解如何设计大型系统。
准备系统设计面试。
学习如何设计可扩展的系统将帮助您成为一名更好的工程师。
系统设计是一个广泛的话题。网络上分布着大量有关系统设计原理的资源。
该存储库是一个有组织的资源集合,可帮助您学习如何大规模构建系统。
这是一个不断更新的开源项目。
欢迎贡献!
除了编码面试之外,系统设计也是许多科技公司技术面试过程中必需的组成部分。
练习常见的系统设计面试问题,并将您的结果与示例解决方案进行比较:讨论、代码和图表。
面试准备的其他主题:
提供的 Anki 抽认卡组使用间隔重复来帮助您保留关键的系统设计概念。
非常适合在旅途中使用。
正在寻找资源来帮助您准备编码面试?
查看姐妹存储库Interactive Coding Challenges ,其中包含额外的 Anki 套牌:
向社区学习。
请随时提交拉取请求来帮助:
需要一些润色的内容正在开发中。
查看贡献指南。
各种系统设计主题的总结,包括优点和缺点。一切都是一个权衡。
每个部分都包含指向更深入资源的链接。
根据您的面试时间线(短、中、长)建议复习的主题。
问:对于面试,我需要知道这里的一切吗?
A:不,你不需要知道这里的一切来准备面试。
您在面试中被问到的问题取决于以下变量:
经验丰富的候选人通常应该了解更多有关系统设计的知识。架构师或团队领导可能需要比个人贡献者了解更多。顶级科技公司可能会进行一轮或多轮设计面试。
从广泛的领域入手,然后在几个领域进行深入研究。了解一些关键的系统设计主题会有所帮助。根据您的时间表、经验、您要面试的职位以及您要面试的公司来调整以下指南。
短的 | 中等的 | 长的 | |
---|---|---|---|
通读系统设计主题,广泛了解系统的工作原理 | ? | ? | ? |
阅读您正在面试的公司的公司工程博客中的几篇文章 | ? | ? | ? |
通读一些现实世界的架构 | ? | ? | ? |
回顾如何处理系统设计面试问题 | ? | ? | ? |
解决系统设计面试问题及其解决方案 | 一些 | 许多 | 最多 |
解决面向对象设计面试问题及其解决方案 | 一些 | 许多 | 最多 |
查看其他系统设计面试问题 | 一些 | 许多 | 最多 |
如何解决系统设计面试问题。
系统设计面试是一个开放式的对话。您应该领导它。
您可以使用以下步骤来指导讨论。为了帮助巩固此过程,请使用以下步骤完成系统设计面试问题和解决方案部分。
收集需求并确定问题范围。提出问题以澄清用例和限制。讨论假设。
概述包含所有重要组件的高级设计。
深入了解每个核心组件的详细信息。例如,如果您被要求设计一个 url 缩短服务,请讨论:
考虑到限制,识别并解决瓶颈。例如,您是否需要以下内容来解决可扩展性问题?
讨论潜在的解决方案和权衡。一切都是一个权衡。使用可扩展系统设计原则解决瓶颈。
您可能会被要求手工进行一些估计。请参阅附录以获取以下资源:
查看以下链接以更好地了解预期内容:
常见的系统设计面试问题,包含示例讨论、代码和图表。
链接到
solutions/
文件夹中内容的解决方案。
问题 | |
---|---|
设计 Pastebin.com(或 Bit.ly) | 解决方案 |
设计 Twitter 时间线和搜索(或 Facebook 提要和搜索) | 解决方案 |
设计一个网络爬虫 | 解决方案 |
设计 Mint.com | 解决方案 |
设计社交网络的数据结构 | 解决方案 |
为搜索引擎设计键值存储 | 解决方案 |
按品类特征设计亚马逊销售排名 | 解决方案 |
设计一个可在 AWS 上扩展到数百万用户的系统 | 解决方案 |
添加系统设计问题 | 贡献 |
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
查看练习和解决方案
常见的面向对象设计面试问题,包含示例讨论、代码和图表。
链接到
solutions/
文件夹中内容的解决方案。
注:此部分正在开发中
问题 | |
---|---|
设计一个哈希图 | 解决方案 |
设计最近最少使用的缓存 | 解决方案 |
设计一个呼叫中心 | 解决方案 |
设计一副纸牌 | 解决方案 |
设计一个停车场 | 解决方案 |
设计一个聊天服务器 | 解决方案 |
设计一个圆形阵列 | 贡献 |
添加面向对象的设计问题 | 贡献 |
系统设计新手?
首先,您需要对常见原则有基本的了解,了解它们是什么、如何使用以及它们的优缺点。
哈佛大学可扩展性讲座
可扩展性
接下来,我们将看看高层的权衡:
请记住,一切都是一个权衡。
然后我们将深入探讨更具体的主题,例如 DNS、CDN 和负载均衡器。
如果服务以与添加的资源成比例的方式提高性能,则该服务是可扩展的。一般来说,提高性能意味着服务更多的工作单元,但也可以处理更大的工作单元,例如当数据集增长时。 1
另一种看待性能与可扩展性的方法:
延迟是执行某些操作或产生某些结果的时间。
吞吐量是每单位时间此类操作或结果的数量。
一般来说,您应该以可接受的延迟为目标实现最大吞吐量。
资料来源:CAP 定理重温
在分布式计算机系统中,只能支持以下保证中的两个:
网络并不可靠,因此您需要支持分区容错。您需要在软件一致性和可用性之间进行权衡。
等待分区节点的响应可能会导致超时错误。如果您的业务需要原子读写,CP 是一个不错的选择。
响应返回任何节点上可用数据的最容易获得的版本,该版本可能不是最新的。解析分区后,写入可能需要一些时间才能传播。
如果业务需要实现最终一致性,或者系统需要在外部错误的情况下继续工作,那么 AP 是一个不错的选择。
对于相同数据的多个副本,我们面临着如何同步它们的选择,以便客户端拥有一致的数据视图。回想一下 CAP 定理中一致性的定义 - 每次读取都会收到最近的写入或错误。
写入后,读取可能会也可能看不到它。采取尽力而为的方法。
这种方法常见于 memcached 等系统中。弱一致性在 VoIP、视频聊天和实时多人游戏等实时用例中效果很好。例如,如果您正在打电话,但信号中断了几秒钟,那么当您重新获得连接时,您将听不到连接中断期间所说的内容。
写入后,读取最终会看到它(通常在几毫秒内)。数据是异步复制的。
这种方法常见于 DNS 和电子邮件等系统中。最终一致性在高可用系统中效果很好。
写入后,读取会看到它。数据同步复制。
这种方法常见于文件系统和 RDBMS 中。强一致性在需要事务的系统中效果很好。
有两种互补的模式可以支持高可用性:故障转移和复制。
通过主动-被动故障转移,心跳在主动和备用服务器之间发送。如果心跳中断,被动服务器将接管主动服务器的 IP 地址并恢复服务。
停机时间的长短取决于无源服务器是否已经在“热”备用状态下运行,或者是否需要从“冷”备用状态启动。只有活动服务器处理流量。
主动-被动故障转移也可以称为主从故障转移。
在主动-主动模式下,两台服务器都在管理流量,在它们之间分散负载。
如果服务器面向公众,则 DNS 需要了解两台服务器的公共 IP。如果服务器面向内部,应用程序逻辑将需要了解这两个服务器。
主动-主动故障转移也可以称为主-主故障转移。
该主题将在数据库部分进一步讨论:
可用性通常通过正常运行时间(或停机时间)来量化,作为服务可用时间的百分比。可用性通常以 9 的数量来衡量——可用性为 99.99% 的服务被描述为有四个 9。
期间 | 可接受的停机时间 |
---|---|
每年停机时间 | 8小时45分57秒 |
每月停机时间 | 43m 49.7s |
每周停机时间 | 10m 4.8s |
每天的停机时间 | 1m 26.4s |
期间 | 可接受的停机时间 |
---|---|
每年停机时间 | 52分35.7秒 |
每月停机时间 | 4米23秒 |
每周停机时间 | 1米5秒 |
每天的停机时间 | 8.6秒 |
如果一项服务由多个容易出现故障的组件组成,则该服务的整体可用性取决于这些组件是顺序排列还是并行排列。
当可用性 < 100% 的两个组件按顺序排列时,总体可用性会降低:
Availability (Total) = Availability (Foo) * Availability (Bar)
如果Foo
和Bar
可用性均为 99.9%,则它们的总可用性依次为 99.8%。
当可用性 < 100% 的两个组件并行时,总体可用性会提高:
Availability (Total) = 1 - (1 - Availability (Foo)) * (1 - Availability (Bar))
如果Foo
和Bar
都具有 99.9% 的可用性,那么它们并行的总可用性将为 99.9999%。
来源:DNS 安全演示
域名系统 (DNS) 将域名(例如 www.example.com)转换为 IP 地址。
DNS 是分层的,顶层有一些权威服务器。您的路由器或 ISP 提供有关在进行查找时要联系哪些 DNS 服务器的信息。较低级别的 DNS 服务器缓存映射,这些映射可能会因 DNS 传播延迟而变得过时。 DNS 结果也可以由您的浏览器或操作系统缓存一段时间,具体时间由生存时间 (TTL) 决定。
CNAME
(example.com 到 www.example.com)或A
记录。CloudFlare 和 Route 53 等服务提供托管 DNS 服务。一些 DNS 服务可以通过各种方法路由流量:
来源:为什么使用 CDN
内容分发网络 (CDN) 是一个全球分布式代理服务器网络,从更靠近用户的位置提供内容。通常,静态文件(例如 HTML/CSS/JS、照片和视频)由 CDN 提供,但某些 CDN(例如 Amazon 的 CloudFront)支持动态内容。该站点的 DNS 解析将告诉客户端要联系哪个服务器。
从 CDN 提供内容可以通过两种方式显着提高性能:
每当您的服务器发生更改时,推送 CDN 都会收到新内容。您对提供内容、直接上传到 CDN 以及重写 URL 以指向 CDN 承担全部责任。您可以配置内容何时过期以及何时更新。仅当内容是新的或更改时才上传,从而最大限度地减少流量,但最大限度地提高存储空间。
流量较小的网站或内容不经常更新的网站可以很好地使用推送 CDN。内容一次性放置在 CDN 上,而不是定期重新拉取。
当第一个用户请求内容时,拉取 CDN 从您的服务器获取新内容。您将内容保留在服务器上并重写 URL 以指向 CDN。这会导致请求速度变慢,直到内容缓存在 CDN 上。
生存时间 (TTL) 决定内容的缓存时间。拉取 CDN 最大限度地减少了 CDN 上的存储空间,但如果文件过期并在实际更改之前被拉取,则可能会产生冗余流量。
流量大的网站可以很好地使用拉式 CDN,因为流量分布得更均匀,CDN 上仅保留最近请求的内容。
来源:可扩展系统设计模式
负载均衡器将传入的客户端请求分发到应用程序服务器和数据库等计算资源。在每种情况下,负载均衡器都会将响应从计算资源返回到适当的客户端。负载均衡器可以有效地:
负载均衡器可以使用硬件(昂贵)或使用 HAProxy 等软件来实现。
其他好处包括:
为了防止出现故障,通常会以主动-被动或主动-主动模式设置多个负载均衡器。
负载均衡器可以根据各种指标路由流量,包括:
第 4 层负载均衡器查看传输层的信息来决定如何分发请求。通常,这涉及标头中的源、目标 IP 地址和端口,但不涉及数据包的内容。第 4 层负载均衡器将网络数据包转发到上游服务器或从上游服务器转发网络数据包,执行网络地址转换 (NAT)。
第 7 层负载均衡器查看应用程序层来决定如何分发请求。这可能涉及标头、消息和 cookie 的内容。第 7 层负载均衡器终止网络流量,读取消息,做出负载均衡决策,然后打开与所选服务器的连接。例如,第 7 层负载均衡器可以将视频流量定向到托管视频的服务器,同时将更敏感的用户计费流量定向到安全强化的服务器。
以灵活性为代价,第 4 层负载平衡所需的时间和计算资源比第 7 层更少,尽管对现代商用硬件的性能影响可能很小。
负载均衡器还可以帮助水平扩展,提高性能和可用性。与在更昂贵的硬件上扩展单个服务器相比,使用商用机器进行扩展更具成本效益,并且可带来更高的可用性,称为垂直扩展。与专门的企业系统相比,雇用从事商品硬件工作的人才也更容易。
资料来源:维基百科
反向代理是一种集中内部服务并向公众提供统一接口的Web服务器。在反向代理将服务器的响应返回给客户端之前,来自客户端的请求将转发到可以满足请求的服务器。
其他好处包括:
来源:规模化系统架构简介
将 Web 层与应用程序层(也称为平台层)分离允许您独立扩展和配置这两个层。添加新的 API 会导致添加应用程序服务器,而无需添加额外的 Web 服务器。单一责任原则提倡小型且自治的服务协同工作。拥有小型服务的小型团队可以更积极地规划以实现快速增长。
应用程序层的工作人员也有助于实现异步。
与此讨论相关的是微服务,它可以被描述为一套可独立部署的小型模块化服务。每个服务都运行一个独特的流程,并通过定义明确的轻量级机制进行通信,以服务于业务目标。 1
例如,Pinterest 可以具有以下微服务:用户个人资料、关注者、提要、搜索、照片上传等。
Consul、Etcd 和 Zookeeper 等系统可以通过跟踪注册名称、地址和端口来帮助服务找到彼此。运行状况检查有助于验证服务完整性,通常使用 HTTP 端点完成。 Consul 和 Etcd 都有一个内置的键值存储,可用于存储配置值和其他共享数据。
来源:扩展到前 1000 万用户
像 SQL 这样的关系数据库是按表组织的数据项的集合。
ACID是关系数据库事务的一组属性。
有许多技术可以扩展关系数据库:主从复制、主主复制、联合、分片、非规范化和SQL 调优。
主服务器提供读取和写入服务,将写入复制到一个或多个仅提供读取服务的从服务器。从属设备还可以以树状方式复制到其他从属设备。如果主设备离线,系统可以继续以只读模式运行,直到从设备升级为主设备或配置新的主设备。
来源:可扩展性、可用性、稳定性、模式
两个主机都提供读取和写入服务,并在写入时相互协调。如果任一主设备出现故障,系统可以继续进行读写操作。
来源:可扩展性、可用性、稳定性、模式
来源:扩展到前 1000 万用户
联合(或功能分区)按功能分割数据库。例如,您可以拥有三个数据库,而不是单个整体数据库: forums 、 users和products ,从而减少每个数据库的读写流量,从而减少复制延迟。较小的数据库会导致内存中可以容纳的数据更多,进而由于缓存局部性的改进而导致更多的缓存命中。由于没有单个中央主控串行写入,您可以并行写入,从而提高吞吐量。
来源:可扩展性、可用性、稳定性、模式
分片将数据分布在不同的数据库中,使得每个数据库只能管理数据的子集。以用户数据库为例,随着用户数量的增加,集群中会添加更多的分片。
与联合的优点类似,分片会导致更少的读写流量、更少的复制和更多的缓存命中。索引大小也减少了,这通常可以通过更快的查询提高性能。如果一个分片出现故障,其他分片仍然可以运行,尽管您需要添加某种形式的复制以避免数据丢失。与联合一样,没有单个中央主控器序列化写入,因此您可以并行写入并提高吞吐量。
对用户表进行分片的常见方法是通过用户的姓氏首字母或用户的地理位置。
非规范化试图以牺牲部分写入性能为代价来提高读取性能。数据的冗余副本写入多个表中以避免昂贵的连接。一些 RDBMS(例如 PostgreSQL 和 Oracle)支持物化视图,该视图处理存储冗余信息和保持冗余副本一致的工作。
一旦数据通过联合和分片等技术进行分布,管理跨数据中心的连接就会进一步增加复杂性。非规范化可能会避免这种复杂连接的需要。
在大多数系统中,读取数量远多于写入数量,比例为 100:1 甚至 1000:1。导致复杂数据库连接的读取可能非常昂贵,会在磁盘操作上花费大量时间。
SQL 调优是一个广泛的主题,并且已经编写了许多书籍作为参考。
进行基准测试和分析以模拟和发现瓶颈非常重要。
基准测试和分析可能会指导您进行以下优化。
CHAR
而不是VARCHAR
。CHAR
有效地允许快速、随机访问,而使用VARCHAR
时,您必须找到字符串的结尾才能移动到下一个字符串。TEXT
用于大文本块,例如博客文章。 TEXT
还允许布尔搜索。使用TEXT
字段会导致在磁盘上存储一个用于定位文本块的指针。INT
。DECIMAL
以避免浮点表示错误。BLOBS
,而是存储获取对象的位置。VARCHAR(255)
是 8 位数字中可以计数的最大字符数,通常在某些 RDBMS 中最大化字节的使用。NOT NULL
约束以提高搜索性能。 SELECT
、 GROUP BY
、 ORDER BY
、 JOIN
)使用索引可能会更快。NoSQL 是在键值存储、文档存储、宽列存储或图形数据库中表示的数据项的集合。数据是非规范化的,连接通常在应用程序代码中完成。大多数 NoSQL 存储缺乏真正的 ACID 事务并倾向于最终一致性。
BASE通常用于描述 NoSQL 数据库的属性。与 CAP 定理相比,BASE 选择可用性而不是一致性。
除了在 SQL 或 NoSQL 之间进行选择之外,了解哪种类型的 NoSQL 数据库最适合您的用例也很有帮助。我们将在下一节中回顾键值存储、文档存储、宽列存储和图形数据库。
抽象:哈希表
键值存储通常允许 O(1) 读取和写入,并且通常由内存或 SSD 支持。数据存储可以按字典顺序维护键,从而可以有效检索键范围。键值存储可以允许存储带有值的元数据。
键值存储提供高性能,通常用于简单的数据模型或快速变化的数据,例如内存缓存层。由于它们仅提供有限的操作集,因此如果需要其他操作,复杂性就会转移到应用程序层。
键值存储是更复杂系统的基础,例如文档存储,在某些情况下是图形数据库。
抽象:键值存储,文档存储为值
文档存储以文档(XML、JSON、二进制等)为中心,其中文档存储给定对象的所有信息。文档存储提供 API 或查询语言来根据文档本身的内部结构进行查询。请注意,许多键值存储都包含用于处理值元数据的功能,从而模糊了这两种存储类型之间的界限。
根据底层实现,文档按集合、标签、元数据或目录进行组织。尽管文档可以组织或分组在一起,但文档可能具有彼此完全不同的字段。
一些文档存储(例如 MongoDB 和 CouchDB)还提供类似 SQL 的语言来执行复杂的查询。 DynamoDB 支持键值和文档。
文档存储提供了高度的灵活性,通常用于处理偶尔变化的数据。
资料来源:SQL 和 NoSQL,简史
抽象:嵌套映射
ColumnFamily<RowKey, Columns<ColKey, Value, Timestamp>>
宽列存储的基本数据单位是列(名称/值对)。列可以按列族进行分组(类似于 SQL 表)。超级柱族进一步对柱族进行分组。您可以使用行键独立访问每一列,具有相同行键的列形成一行。每个值都包含用于版本控制和冲突解决的时间戳。
Google 推出了 Bigtable 作为第一个宽列存储,影响了 Hadoop 生态系统中常用的开源 HBase,以及 Facebook 的 Cassandra。 BigTable、HBase 和 Cassandra 等存储按字典顺序维护键,从而允许高效检索选择性键范围。
宽列存储提供高可用性和高可扩展性。它们通常用于非常大的数据集。
来源:图数据库
抽象:图
在图数据库中,每个节点是一条记录,每条弧是两个节点之间的关系。图数据库经过优化,可以表示具有许多外键或多对多关系的复杂关系。
图数据库为具有复杂关系的数据模型(例如社交网络)提供高性能。它们相对较新,尚未广泛使用;寻找开发工具和资源可能会更加困难。许多图表只能通过 REST API 访问。
来源:从 RDBMS 过渡到 NoSQL
SQL的原因:
使用NoSQL的原因:
非常适合 NoSQL 的示例数据:
来源:可扩展系统设计模式
缓存可以缩短页面加载时间,并减少服务器和数据库的负载。在这个模型中,调度程序将首先查找之前是否已经发出过请求,并尝试找到之前的结果来返回,以节省实际执行。
数据库通常受益于跨分区的均匀读写分布。热门商品可能会扭曲分布,导致瓶颈。将缓存放在数据库前面可以帮助吸收不均匀的负载和流量峰值。
缓存可以位于客户端(操作系统或浏览器)、服务器端或不同的缓存层中。
CDN 被视为一种缓存。
反向代理和缓存(例如 Varnish)可以直接提供静态和动态内容。 Web 服务器还可以缓存请求,返回响应,而无需联系应用程序服务器。
您的数据库通常在默认配置中包含某种级别的缓存,并针对通用用例进行了优化。针对特定使用模式调整这些设置可以进一步提高性能。
内存缓存(例如 Memcached 和 Redis)是应用程序和数据存储之间的键值存储。由于数据保存在 RAM 中,因此它比数据存储在磁盘上的典型数据库要快得多。 RAM 比磁盘受到更多限制,因此最近最少使用 (LRU) 等缓存失效算法可以帮助使“冷”条目无效并将“热”数据保留在 RAM 中。
Redis 还有以下附加功能:
您可以缓存多个级别,这些级别分为两大类:数据库查询和对象:
一般来说,您应该尽量避免基于文件的缓存,因为它会使克隆和自动缩放变得更加困难。
每当您查询数据库时,都会将查询哈希为键并将结果存储到缓存中。这种方法存在过期问题:
将您的数据视为一个对象,类似于您对应用程序代码所做的操作。让您的应用程序将数据库中的数据集组装成类实例或数据结构:
关于缓存内容的建议:
由于您只能在缓存中存储有限数量的数据,因此您需要确定哪种缓存更新策略最适合您的用例。
来源:从缓存到内存数据网格
应用程序负责从存储中读取和写入。缓存不直接与存储交互。该应用程序执行以下操作:
def get_user ( self , user_id ):
user = cache . get ( "user.{0}" , user_id )
if user is None :
user = db . query ( "SELECT * FROM users WHERE user_id = {0}" , user_id )
if user is not None :
key = "user.{0}" . format ( user_id )
cache . set ( key , json . dumps ( user ))
return user
Memcached一般都是这样使用的。
添加到缓存的数据的后续读取速度很快。缓存也称为懒惰加载。仅将请求的数据缓存,该数据避免使用未请求的数据填充缓存。
来源:可扩展性、可用性、稳定性、模式
该应用程序将缓存用作主要数据存储,将数据读取和写入数据,而缓存负责读取和写入数据库:
申请代码:
set_user ( 12345 , { "foo" : "bar" })
缓存代码:
def set_user ( user_id , values ):
user = db . query ( "UPDATE Users WHERE id = {0}" , user_id , values )
cache . set ( user_id , user )
由于写操作,写入是一个缓慢的总体操作,但随后仅书面数据的读取很快。更新数据时,用户通常比阅读数据更宽容。缓存中的数据不是建立的。
来源:可扩展性、可用性、稳定性、模式
在写作中,该应用程序执行以下操作:
资料来源:从缓存到内存数据网格
您可以将缓存配置为在其到期之前自动刷新任何最近访问的缓存条目。
如果缓存能够准确预测将来可能需要哪些项目,则刷新预先批准可能会导致延迟与读取。
资料来源:规模的架构系统介绍
异步工作流程有助于减少昂贵操作的请求时间,否则将在线执行。他们还可以通过提前进行耗时的工作来提供帮助,例如数据的定期聚合。
消息队列接收,保留和传递消息。如果操作太慢而无法执行内联,则可以使用以下工作流程的消息队列:
用户没有被阻止,并且在后台处理了作业。在此期间,客户可能会选择进行少量处理,以使其看起来好像已经完成。例如,如果发布一条推文,则可以立即将Tweet发布到您的时间轴上,但是可能需要一些时间才能真正将推文交付给所有关注者。
REDIS可用作简单的消息经纪人,但可能会丢失消息。
RabbitMQ很受欢迎,但要求您适应“ AMQP”协议并管理自己的节点。
Amazon SQS托管了,但可以具有很高的延迟,并且有可能发送两次消息。
任务队列接收任务及其相关数据,运行它们,然后提供结果。他们可以支持调度,可以在后台运行计算密集型工作。
芹菜支持调度,主要得到Python的支持。
如果队列开始显着增长,队列的大小可能会比内存大,从而导致缓存错过,磁盘读取甚至性能较慢。背压可以通过限制队列大小来帮助您,从而保持高吞吐量率和排队已经在队列中的工作时间良好。队列填充后,客户端会使服务器繁忙或HTTP 503状态代码以后再试。客户可以在以后的时间重试该请求,也许可以通过指数退回。
资料来源:OSI 7层模型
HTTP是一种编码和传输客户端和服务器之间数据的方法。这是一个请求/响应协议:客户端发出请求和服务器发出有关请求的相关内容和完成状态信息的响应。 HTTP是独立的,允许请求和响应流经许多执行负载平衡,缓存,加密和压缩的中间路由器和服务器。
基本的HTTP请求由动词(方法)和资源(端点)组成。以下是常见的HTTP动词:
动词 | 描述 | divempotent* | 安全的 | 可缓存 |
---|---|---|---|---|
得到 | 读取资源 | 是的 | 是的 | 是的 |
邮政 | 创建资源或触发处理数据的过程 | 不 | 不 | 是的,如果响应包含新鲜信息 |
放 | 创建或替换资源 | 是的 | 不 | 不 |
修补 | 部分更新资源 | 不 | 不 | 是的,如果响应包含新鲜信息 |
删除 | 删除资源 | 是的 | 不 | 不 |
*可以被称为多次,而没有不同的结果。
HTTP是一种应用程序层协议,依赖于较低级别的协议,例如TCP和UDP 。
资料来源:如何制作多人游戏
TCP是IP网络上面向连接的协议。建立连接并使用握手终止。所有发送的数据包都可以保证以原始顺序到达目的地,而不会通过:
如果发件人没有收到正确的响应,则将重新发送数据包。如果有多个超时,则将删除连接。 TCP还实施了流量控制和拥塞控制。这些保证会导致延迟,通常导致的传输效率低于UDP。
为了确保高吞吐量,Web服务器可以保持大量的TCP连接打开,从而导致高内存使用。在Web服务器线程之间拥有大量的开放连接并说是一个备用的服务器可能会很昂贵。连接池除了在适用的情况下切换到UDP外,还可以帮助您。
TCP对于需要高可靠性但至关重要的时间较少的应用程序很有用。一些示例包括Web服务器,数据库信息,SMTP,FTP和SSH。
当以下时间使用UDP上的TCP
资料来源:如何制作多人游戏
UDP是无连接的。数据报(类似于数据包)仅在数据报级别保证。数据报可能会到达目的地,或者根本无法达到目的地。 UDP不支持拥塞控制。没有保证TCP支持,UDP通常更有效。
UDP可以广播,将数据报发送到子网上的所有设备。这对DHCP很有用,因为客户端尚未收到IP地址,从而阻止了TCP在没有IP地址的情况下流式传输的方法。
UDP的可靠性较差,但在实时用例中效果很好,例如VoIP,视频聊天,流媒体和实时多人游戏。
当以下方式使用TCP上的UDP
资料来源:破解系统设计采访
在RPC中,客户端会导致一个过程在不同的地址空间(通常是远程服务器)上执行。该过程被编码,好像是本地程序调用一样,将如何与客户端程序与服务器通信的详细信息抽象。远程呼叫通常比本地呼叫较慢且可靠性较低,因此将RPC呼叫与本地呼叫区分开是有帮助的。流行的RPC框架包括Protobuf,Thrift和Avro。
RPC是一个请求响应协议:
示例RPC调用:
GET /someoperation?data=anId
POST /anotheroperation
{
"data":"anId";
"anotherdata": "another value"
}
RPC专注于暴露行为。 RPC经常出于性能原因与内部通信有关,因为您可以手工制作的本机呼叫以更好地适合您的用例。
选择一个本地库(又称SDK):
REST之后的HTTP API倾向于将其用于公共API。
REST是一种实施客户端/服务器模型的体系结构样式,客户端在服务器管理的一组资源上作用。该服务器提供了可以操纵或获得新资源表示的资源和动作的表示。所有沟通都必须无状态且可缓存。
静止界面有四个素质:
示例休息电话:
GET /someresources/anId
PUT /someresources/anId
{"anotherdata": "another value"}
REST专注于公开数据。它最小化客户端/服务器之间的耦合,通常用于公共HTTP API。 REST使用一种更通用和统一的方法通过URI来揭示资源,通过标头表示以及通过诸如GET,POST,PUT,PUT,DELETE和PATCH之类的动词进行操作。无状态,休息非常适合水平缩放和分区。
手术 | 远程过程调用 | 休息 |
---|---|---|
报名 | 发布/注册 | 邮寄/人员 |
辞职 | 邮寄/辞职 { “ persyid”:“ 1234” } | 删除/人 /1234 |
读一个人 | 获取/读取者?personid = 1234 | 获取/人 /1234 |
阅读一个人的物品清单 | 获取/readuserSitemslist?persyid = 1234 | get /person/1234/项目 |
将项目添加到一个人的物品 | 发布/additemtouserSitemslist { “ persyid”:“ 1234”; “ itemid”:“ 456” } | POST /Persons/1234/项目 { “ itemid”:“ 456” } |
更新一个项目 | 发布/修改 { “ itemid”:“ 456”; “键”:“值” } | PUT /项目 /456 { “键”:“值” } |
删除一个项目 | 张贴/删除ITITEM { “ itemid”:“ 456” } | 删除/项目 /456 |
资料来源:您真的知道为什么您更喜欢休息而不是RPC
本节可以使用一些更新。考虑贡献!
安全是一个广泛的话题。除非您有丰富的经验,安全背景或申请需要安全知识的职位,否则您可能不需要比基本知识更多:
有时您会被要求进行“后面”的估计。例如,您可能需要确定从磁盘生成100个图像缩略图或数据结构所需的数量所需的时间。每个程序员应该知道的两个表和延迟号的功能是方便的参考。
Power Exact Value Approx Value Bytes
---------------------------------------------------------------
7 128
8 256
10 1024 1 thousand 1 KB
16 65,536 64 KB
20 1,048,576 1 million 1 MB
30 1,073,741,824 1 billion 1 GB
32 4,294,967,296 4 GB
40 1,099,511,627,776 1 trillion 1 TB
Latency Comparison Numbers
--------------------------
L1 cache reference 0.5 ns
Branch mispredict 5 ns
L2 cache reference 7 ns 14x L1 cache
Mutex lock/unlock 25 ns
Main memory reference 100 ns 20x L2 cache, 200x L1 cache
Compress 1K bytes with Zippy 10,000 ns 10 us
Send 1 KB bytes over 1 Gbps network 10,000 ns 10 us
Read 4 KB randomly from SSD* 150,000 ns 150 us ~1GB/sec SSD
Read 1 MB sequentially from memory 250,000 ns 250 us
Round trip within same datacenter 500,000 ns 500 us
Read 1 MB sequentially from SSD* 1,000,000 ns 1,000 us 1 ms ~1GB/sec SSD, 4X memory
HDD seek 10,000,000 ns 10,000 us 10 ms 20x datacenter roundtrip
Read 1 MB sequentially from 1 Gbps 10,000,000 ns 10,000 us 10 ms 40x memory, 10X SSD
Read 1 MB sequentially from HDD 30,000,000 ns 30,000 us 30 ms 120x memory, 30X SSD
Send packet CA->Netherlands->CA 150,000,000 ns 150,000 us 150 ms
Notes
-----
1 ns = 10^-9 seconds
1 us = 10^-6 seconds = 1,000 ns
1 ms = 10^-3 seconds = 1,000 us = 1,000,000 ns
基于上述数字的方便指标:
通用系统设计访谈问题,并链接到有关如何解决每个问题的资源。
问题 | 参考) |
---|---|
设计文件同步服务,例如Dropbox | youtube.com |
设计像Google这样的搜索引擎 | queue.acm.org stackexchange.com ardendertat.com stanford.edu |
设计一个像Google这样的可扩展网络爬网 | quora.com |
设计Google文档 | code.google.com neil.fraser.name |
设计像Redis这样的钥匙值商店 | 幻灯片共享网 |
设计像Memcached这样的缓存系统 | 幻灯片共享网 |
设计像亚马逊这样的推荐系统 | 葫芦网 ijcai13.org |
设计一个像Bitly这样的Tinyurl系统 | n00tc0d3r.blogspot.com |
设计一个像WhatsApp这样的聊天应用程序 | HighScalibality.com |
设计图像共享系统等Instagram | HighScalibality.com HighScalibality.com |
设计Facebook新闻提要功能 | quora.com quora.com 幻灯片共享网 |
设计Facebook时间轴功能 | 脸书网 HighScalibality.com |
设计Facebook聊天功能 | erlang-factory.com 脸书网 |
设计图形搜索功能,例如Facebook的 | 脸书网 脸书网 脸书网 |
设计诸如CloudFlare之类的内容交付网络 | figshare.com |
设计像Twitter这样的趋势主题系统 | Michael-Noll.com Snikolov .Wordpress.com |
设计一个随机的ID生成系统 | blog.twitter.com github.com |
在时间间隔内返回最高的K请求 | cs.ucsb.edu wpi.edu |
设计一个提供来自多个数据中心数据的系统 | HighScalibality.com |
设计在线多人卡游戏 | indieflashblog.com buildnewgames.com |
设计垃圾收集系统 | suffwithstuff.com 华盛顿教育网 |
设计API速率限制器 | https://stripe.com/blog/ |
设计证券交易所(例如纳斯达克或二元) | 简街 Go 语言实现 实施 |
添加系统设计问题 | 贡献 |
有关现实世界系统如何设计的文章。
资料来源:Twitter时间表规模
不要专注于以下文章的细节细节:
类型 | 系统 | 参考) |
---|---|---|
数据处理 | MAPREDUCE-从Google发出的分布式数据处理 | 研究.google.com |
数据处理 | SPARK-从数据映射的分布式数据处理 | 幻灯片共享网 |
数据处理 | 风暴- 来自Twitter的分布式数据处理 | 幻灯片共享网 |
数据存储 | BigTable-从Google发出的分布式列的数据库 | 哈佛教育网 |
数据存储 | HBASE-笨拙的开源实施 | 幻灯片共享网 |
数据存储 | Cassandra-从Facebook分发了面向列的数据库 | 幻灯片共享网 |
数据存储 | DynamoDB - 来自 Amazon 的面向文档的数据库 | 哈佛教育网 |
数据存储 | MongoDB - 面向文档的数据库 | 幻灯片共享网 |
数据存储 | Spanner - 来自 Google 的全球分布式数据库 | 研究.google.com |
数据存储 | Memcached - 分布式内存缓存系统 | 幻灯片共享网 |
数据存储 | Redis - 具有持久性和值类型的分布式内存缓存系统 | 幻灯片共享网 |
文件系统 | Google 文件系统 (GFS) - 分布式文件系统 | 研究.google.com |
文件系统 | Hadoop 文件系统 (HDFS) - GFS 的开源实现 | apache.org |
杂项 | Chubby - 来自 Google 的松耦合分布式系统的锁定服务 | 研究.google.com |
杂项 | Dapper - 分布式系统跟踪基础设施 | 研究.google.com |
杂项 | Kafka - 来自 LinkedIn 的发布/订阅消息队列 | 幻灯片共享网 |
杂项 | Zookeeper - 集中式基础设施和服务,支持同步 | 幻灯片共享网 |
添加架构 | 贡献 |
公司 | 参考) |
---|---|
亚马逊 | 亚马逊架构 |
辛奇广播 | 每天制作 1,500 小时的音频 |
数据筛选 | 实时数据挖掘每秒 120,000 条推文 |
Dropbox | 我们如何扩展 Dropbox |
ESPN | 以每秒 100,000 duh nuh nuhs 的速度运行 |
谷歌 | 谷歌架构 |
1400万用户,图片 什么力量为Instagram | |
Justin.tv | Justin.Tv 的视频直播架构 |
在Facebook上缩放模因 陶:Facebook的社交图的分布式数据存储 Facebook的照片存储 Facebook直播如何同时流到80万观众 | |
弗利克 | Flickr 架构 |
邮箱 | 6 周内从 0 到 100 万用户 |
Netflix | 整个Netflix堆栈的360度视图 Netflix:当你按下播放键时会发生什么? |
兴趣 | 每月的0到十亿页的0到10秒 1800万游客,10倍增长,12名员工 |
嬉戏鱼 | 每月有 5000 万用户并且还在不断增长 |
大量的鱼 | PlentyOfFish 架构 |
销售人员 | 他们如何每天处理 13 亿笔交易 |
堆栈溢出 | 堆栈溢出架构 |
到到网 | 4000 万访客、2 亿动态页面浏览量、30TB 数据 |
豆瓣 | 每月 150 亿次页面浏览量 |
叽叽喳喳 | 更快地使Twitter 10000% 使用MySQL每天存储2.5亿条推文 150m活跃的用户,300k QPS,22 MB/S FireHose 时间表的时间表 Twitter上的大小数据 Twitter的操作:扩展超过1亿用户 Twitter如何处理每秒3,000张图像 |
优步 | Uber如何扩展其实时市场平台 从缩放Uber到2000个工程师,1000个服务和8000个GIT存储库中学到的经验教训 |
Facebook斥资190亿美元收购的WhatsApp架构 | |
YouTube | YouTube可伸缩性 YouTube架构 |
您正在面试的公司的架构。
您遇到的问题可能来自同一域。
想要添加博客?为了避免重复工作,请考虑将您的公司博客添加到以下存储库:
有兴趣添加一个部分或帮助完成一个正在进行的部分吗?贡献!
本存储库中提供了积分和来源。
特别感谢:
请随时与我联系讨论任何问题、疑问或意见。
我的联系信息可以在我的GitHub页面上找到。
我根据开源许可证向您提供此存储库中的代码和资源。因为这是我的个人存储库,所以您收到的我的代码和资源的许可证来自我,而不是我的雇主 (Facebook)。
Copyright 2017 Donne Martin
Creative Commons Attribution 4.0 International License (CC BY 4.0)
http://creativecommons.org/licenses/by/4.0/