系统设计指南

开发一个强大的、可扩展的、高效的系统可能是令人生畏的。然而,了解关键的概念和组件可以使这个过程更容易管理。在这篇博文中,我们将探讨基本的系统设计组件,如DNS、负载平衡、API网关等,以及一份简洁的小抄,可以帮助开发者设计不同复杂度的系统。

系统设计指南
System Design Blueprint: The Ultimate Guide — Full Resolution: https://drive.google.com/file/d/1OGC55KQqTpeUnpiT6glq_6mNpRfl4rD2/view?usp=sharing

开发一个强大的、可扩展的、高效的系统可能是令人生畏的。然而,了解关键的概念和组件可以使这个过程更容易管理。在这篇博文中,我们将探讨基本的系统设计组件,如DNS、负载平衡、API网关等,以及一份简洁的小抄,可以帮助开发者设计不同复杂度的系统。

系统设计蓝图 / Cheatsheet

一本全面的视觉指南,为开发者提供了一个快速和简单的参考,以了解系统设计中的关键概念和最佳实践。这个方便的作弊表或蓝图涵盖了基本的主题,如DNS、负载平衡、API网关、视频和图像处理、缓存、数据库、唯一的ID生成、标准组件如支付和推荐服务,以及聊天和流媒体协议。有了这个宝贵的资源,你将有能力应对设计和实施可扩展、高效和可靠系统的挑战。

第一部分: 系统设计原则

1.1: 模块化 — Modularization

将系统划分为较小的、可管理的模块有助于降低复杂性,提高可维护性,并增加可重用性。

1.2: 抽象 — Abstraction

隐藏实现细节,只显示基本特征,有助于简化复杂的系统,促进模块化。

1.3: 分层 — Layering

将系统分为几层,每层提供一组特定的功能,促进了关注点的分离,增强了可维护性。

1.4: 扩展性 — Scalability

设计系统,通过增加更多的资源(横向扩展)或优化系统的容量(纵向扩展)来处理增加的负载。

1.5: 性能 — Performance

优化系统的响应时间、吞吐量和资源利用率是成功设计的关键。

1.6: 安全 — Security

通过实施适当的安全措施和做法,确保系统的保密性、完整性和可用性。

1.7: 容错性和冗余 Fault Tolerance and Resilience

设计系统以抵御故障并从错误中优雅地恢复,确保可靠性和可用性。

第二部分: 系统设计的关键构成

2.1: DNS (Domain Name System)

DNS是一个分层和分散的命名系统,用于连接到互联网或私人网络的计算机、服务或其他资源。它将人类可读的域名(例如,www.example.com)翻译成IP地址,使用户能够更有效地访问网站和服务。

2.2: 负载均衡 — Load Balancing

负载平衡是指将网络流量分配到多个服务器上,以确保没有一个服务器被压垮。这种方法提高了系统的可用性、可靠性和性能。标准的负载平衡算法包括圆周率、最小连接和IP哈希。

2.3: API 网关 — API Gateway

API网关是一个服务器,在分布式系统中充当客户和微服务之间的中介。它管理和路由请求,执行安全策略,并可能提供额外的功能,如缓存、日志和监控。

2.4: Content Delivery Network (CDN)

CDN是一个分布在不同地点的服务器网络,旨在以更低的延迟和更高的带宽向用户提供内容。CDN将内容缓存在靠近终端用户的边缘服务器上,提高系统性能,减少源服务器的负载。

2.5: 消息队列 — Message Queue

消息队列通过在队列中临时存储消息来促进分布式系统组件之间的通信。它们实现了异步处理,有助于解耦组件,提高系统的可扩展性和容错性。

2.6: 通信协议 — Communication Protocols

系统设计中使用了不同的通信协议,如HTTP/HTTPS、WebSocket和gRPC。这些协议有优点,也有取舍,选择取决于延迟、安全和数据传输要求等因素。

2.7: 缓存 — Cache

缓存是一种用于存储数据副本的临时技术,允许在未来的请求中快速检索。它有助于减少延迟、服务器负载和带宽消耗。流行的缓存机制包括内存中的缓存、分布式缓存和浏览器缓存。

2.8: 数据库 — Database

为一个系统选择合适的数据库,取决于数据结构、可扩展性、一致性和延迟性。常见的数据库类型包括关系型数据库(如MySQL、PostgreSQL)、NoSQL数据库(如MongoDB、Cassandra),以及NewSQL数据库(如Cockroach DB、Google Spanner)。

2.9: 复制 — Replication Techniques

复制是在不同的节点上维护数据的多个副本,以提高可靠性、可用性和容错性。标准的复制技术包括同步复制、异步复制和半同步复制。

2.10: 分布式UUID生成 — Distributed Unique ID Generation

在分布式系统中创建唯一的标识符可能具有挑战性,但对于保持数据的一致性和完整性至关重要。

第三部分: 使用签名的URL分块上传视频和图片

在本节中,我们将探讨如何使用签名的URL分块上传大型视频和图像文件。这种方法可以显著提高文件上传的效率和可靠性,特别是在网络条件不理想的情况下。

3.1: 什么是签名的URL?

签名的URL是特别制作的URL,它允许临时、安全地访问一个特定的资源,如云存储中的一个对象。这些URL包含一个认证签名,允许用户在有限的时间内执行一个特定的动作,如上传或下载文件。亚马逊S3和谷歌云存储等流行的云存储供应商支持生成签名的URL。下面是一个有签名的URL可能看起来的例子:

https://example-bucket.s3.amazonaws.com/my-file.txt?\ 
  X-Amz-Algorithm=AWS4-HMAC-SHA256& 
  X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20220407%2Fus-east-1%2Fs3%2Faws4_request&\ 
  X-Amz-Date=20220407T123456Z&\ 
  X-Amz-Expires=3600&\ 
  X-Amz-SignedHeaders=host&\ 
  X-Amz-Signature=a9c8a7d1644c7b351ef3034f4a1b4c9047e891c7203eb3a9f29d8c7a74676d88

3.2: 分块上传

在单个请求中上传大文件可能导致超时、高内存消耗,以及由于网络不稳定而增加失败的风险。相反,将大文件分成小块,并按顺序或平行上传,可以提高上传效率和可靠性。这种方法被称为 “分块 “或 “多部分 “上传。

3.3: 结合签名的URL和分块上传

要使用签名的URL分块上传视频和图像文件,请遵循以下一般步骤:

  1. 将文件分成小块:在客户端将大文件分成小块,通常使用JavaScript。块的大小可以不同,但必须平衡请求的数量和每个块的大小以优化上传性能。
  2. 请求为每个分块提供签名的URL: 向你的服务器发送一个请求,为每个分块生成一个签名的URL。服务器应该创建一个具有适当权限和过期时间的签名URL,并将其返回给客户端。
  3. 使用签名的URL上传块: 使用签名的URL,将每个块上传到云存储服务。根据所需的并发水平和网络条件,这些上传可以按顺序或并行进行。
  4. 确认成功上传并重新组合: 一旦所有块被成功上传,通知服务器以确认上传过程的完成。然后,服务器可以将这些块重新组合成原始文件,并进行任何必要的处理或验证。
  5. 处理上传失败: 如果任何块状物上传失败,使用一个新的签名URL重试上传,或实施错误处理策略,以确保顺利的用户体验。

通过使用签名的URL和分块上传,开发人员可以有效和安全地处理大型视频和图像上传,提高他们系统的可靠性和性能。

第四部分: 聊天和流媒体协议

本节将讨论各种聊天和流媒体协议,促进客户端和服务器之间的实时通信和数据流。了解这些协议可以帮助开发者建立响应性和互动性的应用程序。

4.1: RTMP (Real-Time Messaging Protocol)

RTMP是由Adobe Systems公司开发的专有协议,用于在互联网上传输音频、视频和数据。它通常用于视频流应用,并在客户端和服务器之间提供低延迟的通信。然而,由于它对Flash播放器的依赖,近年来它的受欢迎程度已经减弱了。

4.2: WebRTC (Web Real-Time Communication)

WebRTC是一个开源项目,在网络浏览器和移动应用程序中实现实时音频、视频和数据通信。它支持点对点连接,减少延迟和服务器负载。WebRTC被广泛用于视频会议、在线游戏和其他需要实时通信的应用。

4.3: WebSocket

WebSocket是一种通信协议,能够在客户端和服务器之间通过单一的长期连接进行双向、全双工通信。由于其低延迟和高效的通信能力,WebSocket经常被用于聊天、通知和实时更新等实时应用。

4.4: SSE (Server-Sent Events)

服务器发送事件(SSE)是一项技术,使服务器能够通过HTTP连接推送客户端更新。它被设计为从服务器到客户端的单向实时通信,使其适用于实时更新、新闻推送和通知等应用。

4.5: HTTP Short Polling

短期轮询涉及到客户重复向服务器发送HTTP请求以检查新的更新。虽然实现起来很简单,但由于持续的轮询,特别是在更新不频繁的情况下,短轮询会导致服务器的高负载和延迟的增加。

4.6: HTTP Long Polling

长轮询是对短轮询的一种改进,在短轮询中,客户端向服务器发送请求,而服务器保持请求开放,直到有新的数据。这种方法减少了请求的数量和服务器的负载,但它仍然可能受到延迟问题的影响,并且需要仔细管理服务器资源。

4.7: Webhook

Webhooks是用户定义的由系统中特定事件触发的HTTP回调。当一个事件发生时,源站点向为Webhook配置的URL发出一个HTTP请求。这种方法允许不同的系统或服务之间进行有效的、事件驱动的通信。

4.8: Stream API

流API使客户能够从服务器上消费一个连续的数据流,通常使用HTTP或WebSocket连接。这些API是为需要实时更新的应用而设计的,如社交媒体信息、股票市场数据或实时分析。

通过了解和利用这些聊天和流媒体协议,开发人员可以建立响应式的实时应用程序,以满足各种使用情况,并提供有吸引力的用户体验。

第五部分: 系统设计中的常见组件

本节将探讨现代系统设计中经常出现的一些标准组件。了解这些组件可以帮助开发者将它们无缝地集成到他们的系统中,并增强整体功能。

5.1: 支付服务 — Payment Service

支付服务处理客户和企业之间的交易。整合一个可靠的支付服务对电子商务和基于订阅的平台至关重要。流行的支付服务提供商包括Stripe、PayPal和Square。这些服务通常提供API,以促进安全交易和管理经常性付款、退款等。

5.2: 分析服务 — Analytic Service

分析服务实现了数据收集、处理和可视化,以帮助企业做出明智的决策。这些服务可以跟踪用户行为,监测系统性能,并分析趋势。标准的分析服务提供者包括谷歌分析、Mixpanel和Amplitude。将分析服务整合到一个系统中,可以帮助企业优化他们的产品,改善用户体验。

5.3: 推送服务 — Notification

通知服务让用户了解更新、警报和重要信息。这些服务可以通过各种渠道提供通知,如电子邮件、短信和推送通知。通知服务提供商的例子包括Firebase Cloud Messaging(FCM)、Amazon Simple Notification Service(SNS)和Twilio。

对于拥有大量数据或内容的系统来说,集成一个强大的搜索组件是必不可少的。搜索服务应该提供快速、相关、可扩展的搜索功能。Elasticsearch、Apache Solr和Amazon CloudSearch是实现搜索功能的流行选择。这些服务通常支持全文搜索、分面搜索和过滤,使用户能够快速有效地找到他们正在寻找的信息。

5.5: 推荐服务 — Recommendation Service

推荐服务使用算法,根据用户的喜好、行为和其他因素向他们提供个性化的建议。这些服务可以显著提高用户的参与度和满意度。产生建议的技术包括协作过滤、基于内容的过滤和混合方法。机器学习算法,如矩阵分解和深度学习,也可用于生成更复杂的建议。

By incorporating these standard components into their system designs, developers can enhance the functionality of their applications and provide a more seamless and engaging experience for users.

第六部分: 系统设计最佳实践

6.1: 需求收集 — Requirement Gathering

在开始设计过程之前,彻底了解并记录系统需求。

6.2: 设计模式 — Design Patterns

利用成熟的设计模式来解决反复出现的设计问题并改善整体架构。

6.3: 文档 — Documentation

记录你的设计决定、假设和理由,以确保更好的沟通和可维护性。

6.4: 迭代设计 — Iterative Design

通过多次迭代和反馈来完善你的设计,使其不断发展和完善。

6.5: 测试和验证 — Testing and Validation

根据需求验证你的设计,并进行测试以识别和解决潜在的问题。

总结

总之,系统设计是一个多方面的复杂过程,需要深入了解各种组件、协议和技术。这篇博文概述了一些基本主题,如DNS、负载平衡、API网关、视频和图像处理、缓存、数据库、唯一ID生成、支付和推荐服务等标准组件,以及聊天和流媒体协议。

通过利用这些知识,开发人员可以创建可扩展、高效和可靠的系统,以满足不同的要求并提供无缝的用户体验。关键是要记住,系统设计是一个迭代的过程,持续改进对建立和维护成功的应用程序至关重要。有了这些核心概念的坚实基础和对适应性的关注,开发人员可以自信地应对设计和实施强大系统的挑战。

— —

翻译自:

System Design Blueprint: The Ultimate Guide
Developing a robust, scalable, and efficient system can be daunting. However, understanding the key concepts and…

推荐阅读:

现代软件工程 — 第一部分:系统设计
在80年代末和90年代初长大的我,对电脑的接触几乎仅限于游戏机(我认为是Atari 800和Commodore 64游戏机,因为我只看到过在它们上面运行的游戏)或早期的X86系统。直到2000年我上了大学,我才掌握了一台Sun…
现代软件工程 — 第二部分:测试
“如果调试是清除软件缺陷的过程,那么编程一定是把它们放进去的行为”。- Edsger Djikstra
现代软件工程 — 第三部分:文档
文档是一个常年有争议的话题,因为根据我的经验,软件工程非常注重像源代码和运输功能这样的人工制品的商业价值,而不是其他。我经常听到有人说,我们应该只写敏捷实践中需要的文档,或者说写设计文档不是一个好的时间利用。这些说法有一定的道理,而且通常是…
如何成为一名DevOps工程师 2023
在本指南中,我分享了我作为DevOps工程师在不同组织中的经验以及成为DevOps工程师的技巧。这是一份开始DevOps工程职业的全面路线图。由于DevOps领域具有高薪和职业发展的潜力,目前在IT行业是一个非常受欢迎的选择。我经常被问及如…
如何成为一个优秀的软件开发人员
在这个快节奏的发展世界中,软件工程师被期望快速完成工作。