要想在系统设计领域中脱颖而出,深入理解一些基础的系统设计概念是必不可少的,这些概念包括负载均衡、缓存、分区、复制、数据库和代理等。
依据我自己的经验,我总结出了18个关键概念,如果能掌握这些,将极大地提升你处理系统设计问题的能力。这些概念包含了:理解API网关的微妙之处、熟练掌握负载均衡技术、领会CDN的重要性,以及认识到缓存在现代分布式系统中所扮演的角色。读完这篇博客后,你将对这些核心理念有全面的理解,并有足够的信心在下一次面试中运用这些知识。
系统设计面试通常并无固定结构。在面试过程中,跟踪所有内容并确保你已经覆盖到设计的所有重要环节可能会有些挑战。为了简化这个过程,我制定了一份系统设计大纲,这份大纲可以帮助你回答任何系统设计面试问题。你可以查看附图,以获取关于可能涉及的系统设计关键组件的启示。
牢记这份大纲,我们来讨论一下这18个关键的系统设计概念,每个概念的简要描述如下:
1、域名系统(DNS)
域名系统(DNS)是互联网基础设施的基本组成部分,它负责将用户友好的域名转换为相应的IP地址。它就像互联网的电话簿,让用户通过输入容易记忆的域名,例如https://minorstone.com/,而不是计算机用来识别彼此的数字IP地址,如"192.0.2.1",就能访问网站和服务。
当你在浏览器中输入一个域名时,DNS负责找到相关的IP地址,并将你的请求指向适当的服务器。这个过程从你的电脑发送一个查询到递归解析器开始,然后通过一系列的DNS服务器,从根服务器开始,然后到顶级域(TLD)服务器,最后到权威名称服务器。一旦找到IP地址,递归解析器将其返回给你的电脑,从而让你的浏览器能够与目标服务器建立连接并访问想要的内容。
2、负载均衡器
负载均衡器是一种网络设备或软件,设计用于将传入的网络流量分发到多个服务器,以确保资源的最优使用,降低延迟,并保持高可用性。它在扩展应用程序和有效管理服务器工作负载方面起着关键作用,特别是在流量突然激增或服务器之间请求分配不均的情况下。
负载均衡器采用各种算法来确定传入流量的分配。一些常见的算法包括:
- 轮询法:请求以循环方式依次均匀地分发到所有可用服务器。
- 最少连接法:负载均衡器将请求分配给活动连接最少的服务器,优先考虑较不繁忙的服务器。
- IP哈希法:对客户端的IP地址进行哈希,结果值用于确定请求应被指向哪个服务器。此方法确保特定客户端的请求始终路由到同一台服务器,有助于保持会话的持久性。
3、API网关
API网关是作为服务器或服务的角色,充当外部客户端与应用程序内部微服务或基于API的后端服务之间的中介。在现代架构中,特别是在基于微服务的系统中,它是一个重要的组成部分,它简化了通信过程,并为客户端提供了一个访问各种服务的单一入口。
API网关的主要功能包括:
- 请求路由:根据预定义的规则和配置,API网关将来自客户端的API请求指向适当的后端服务或微服务。
- 身份验证和授权:API网关管理用户身份验证和授权,确保只有经过授权的客户端能够访问服务。它在将请求路由到后端服务之前,会验证API密钥、令牌或其他凭证。
- 限速和节流:为了保护后端服务免受过度负载或滥用,API网关会根据预定义的策略对客户端的请求进行限速或节流。
- 缓存:为了最小化延迟和后端负载,API网关会缓存经常使用的响应,并直接服务于客户端,无需查询后端服务。
- 请求和响应转换:API网关可以修改请求和响应,如转换数据格式、添加或删除头部,或改变查询参数,以确保客户端和服务之间的兼容性。
4、CDN
内容分发网络(CDN)是一个分布式服务器网络,它将内容(如图片、视频、样式表和脚本)存储并从地理位置上离用户更近的地方传送给用户。CDN的设计目的是提高向终端用户传输内容的性能、速度和可靠性,无论他们相对于源服务器的位置如何。以下是CDN的工作方式:
- 当用户从网站或应用程序请求内容时,请求会被指向最近的CDN服务器,也称为边缘服务器。
- 如果边缘服务器已经缓存了请求的内容,它会直接将内容提供给用户。这个过程减少了延迟并提高了用户体验,因为内容传输的距离更短。
- 如果边缘服务器上没有缓存内容,CDN会从源服务器或另一个近在咫尺的CDN服务器上获取它。一旦获取了内容,它就会被缓存在边缘服务器上并提供给用户。
- 为了确保内容保持最新状态,CDN会定期检查源服务器的变化,并相应地更新其缓存。
5、正向代理与反向代理
正向代理,也被称为"代理服务器"或简单的"代理",是放置在一个或多个客户端机器前的服务器,充当客户端和互联网之间的中介。当客户端机器请求互联网上的资源时,请求首先发送到正向代理。然后,正向代理代表客户端机器将请求转发到互联网,并将响应返回给客户端机器。
另一方面,反向代理是放置在一个或多个Web服务器前的服务器,作为Web服务器和互联网之间的中介。当客户端请求互联网上的资源时,请求首先发送到反向代理。然后,反向代理将请求转发到其中一台Web服务器,该服务器将响应返回给反向代理。最后,反向代理将响应返回给客户端。
6、缓存
缓存是位于应用程序和原始数据源(如数据库、文件系统或远程网络服务)之间的高速存储层。当应用程序请求数据时,首先检查缓存。如果数据存在于缓存中,它就会被返回给应用程序。如果在缓存中找不到数据,那么数据就会从原始源获取,存储在缓存中以备将来使用,然后返回给应用程序。在分布式系统中,缓存可以出现在多个位置,包括客户端、DNS、CDN、负载均衡器、API网关、服务器、数据库等。
7、数据分区
在数据库中,水平分区常被称为分片,它包括将表的行分割成更小的表,并将它们存储在不同的服务器或数据库实例上。这种方法被用来将数据库负载分散到多个服务器,从而提高性能。
相反,垂直分区涉及到将表的列分割成独立的表。这种技术旨在减少表中的列数,并提高只访问有限数目列的查询的性能。
8、数据库复制
数据库复制是一种用于在各种服务器或位置上维护相同数据库的多份副本的方法。数据库复制的主要目标是提高数据的可用性、冗余度和容错性,确保在硬件故障或其他问题发生时系统仍能保持运行。
在复制的数据库配置中,一个服务器作为主(或主)数据库,其他的则作为副本(或从)。此过程涉及同步主数据库和副本之间的数据,确保所有服务器都拥有相同的最新信息。数据库复制提供了多种优点,包括:
- 提高性能:通过在多个副本间分发读取查询,可以减轻主数据库的负载,从而提高查询响应时间。
- 高可用性:如果主数据库遇到故障或停机,副本可以继续提供数据,确保应用程序的访问不间断。
- 增强数据保护:在不同位置维护数据库的多份副本有助于防止由于硬件故障或其他灾难导致的数据丢失。
- 负载均衡:副本可以处理读取查询,从而实现更好的负载分配并减少对主数据库的整体压力。
9、分布式消息系统
分布式消息系统为众多可能地理分散的应用、服务或组件之间的消息交换提供了一种可靠、可扩展且容错性强的方式。这些系统通过解耦发送者和接收者组件来促进通信,使它们能够独立地开发和运行。在大规模或复杂系统中,如微服务架构或分布式计算环境中,分布式消息系统显得尤为重要。这些系统的例子包括Apache Kafka和RabbitMQ。
10、微服务
微服务代表了一种架构风格,其中应用程序被组织成一组小型、松散耦合且能自主部署的服务。每个微服务负责应用程序中的一个特定功能或领域,并通过定义明确的API与其他微服务进行通信。这种方法与传统的单体架构有所不同,后者将应用程序构建为一个紧密耦合的单一单位。
微服务的主要特性包括:
- 单一职责:遵循单一职责原则,每个微服务专注于特定的功能或领域,使服务更易于理解、开发和维护。
- 独立性:微服务可以独立开发、部署和扩展,为开发过程提供了更大的灵活性和敏捷性。团队可以同时开发各种服务,而不会影响整个系统。
- 分散化:通常,微服务是分散的,每个服务都有自己的数据和业务逻辑。这种方法促进了关注点分离,使团队能够根据自己的特殊需求做出决策并选择技术。
- 通信:微服务使用轻量级协议(如HTTP/REST、gRPC或消息队列)进行交互。这有助于互操作性,并便于集成新服务或替换现有服务。
- 容错性:由于微服务是独立的,一个服务的失败不一定导致整个系统崩溃,从而提高了应用程序的整体弹性。
11、NoSQL 数据库
NoSQL数据库,或称为“非仅仅是SQL”的数据库,是非关系型数据库,设计用于存储、管理和检索非结构化或半结构化数据。它们提供了对传统关系型数据库的替代,后者依赖于结构化数据和预定义的模式。由于NoSQL数据库的灵活性、可扩展性以及处理大量数据的能力,使其在现代应用程序、大数据处理和实时分析中越来越受欢迎。
NoSQL数据库可以分为四种主要类型:
- 文档型:这类数据库将数据存储在类似于文档的结构中,如JSON或BSON。每个文档都是自包含的,可以有自己独特的结构,使其适合处理异构数据。文档型NoSQL数据库的例子包括MongoDB和Couchbase。
- 键值对:这类数据库将数据以键值对形式存储,其中键作为唯一标识符,值则保存相关的数据。键值对数据库对于简单的读写操作非常高效,并且它们可以容易地进行分区并水平扩展。键值对NoSQL数据库的例子包括Redis和亚马逊的DynamoDB。
- 列族型:这类数据库将数据存储在列族中,列族是相关列的集合。它们设计用来处理写入密集型的工作负载,对于已知行和列键的数据查询非常高效。列族型NoSQL数据库的例子包括Apache Cassandra和HBase。
- 图形型:这类数据库设计用于存储和查询具有复杂关系和互联结构的数据,例如社交网络或推荐系统。图数据库使用节点、边和属性来表示和存储数据,从而更易于执行复杂的遍历和基于关系的查询。图形型NoSQL数据库的例子包括Neo4j和亚马逊的Neptune。
12、数据库索引
数据库索引是一种数据结构,能提高数据库查询操作的速度和效率。它们的功能类似于书籍中的索引,使数据库管理系统(DBMS)能迅速定位与特定值或值组相关的数据,无需搜索表中的每一行。通过提供更直接的数据查找路径,索引可以显著减少从数据库检索信息所需的时间。
索引通常建立在数据库表的一个或多个列上。B树索引是最常见的类型,它以分层树状结构组织数据,允许快速的搜索、插入和删除操作。其他类型的索引,如位图索引和哈希索引,也存在各自的使用场景和优势。
尽管索引可以显著提高查询性能,但也涉及到一定的权衡:
- 存储空间:索引需要额外的存储空间,因为它们在原始表数据旁边生成和维护独立的数据结构。
- 写性能:当在表中插入、更新或删除数据时,相应的索引也必须被更新,这可能会减慢写操作的速度。
13、分布式文件系统
分布式文件系统是一种设计用来在多个服务器、节点或机器(经常是跨网络分布)之间管理和授权访问文件和目录的存储系统。它们让用户和应用程序可以访问和修改文件,就像这些文件是位于本地文件系统上一样,尽管实际的文件可能物理上位于各种远程服务器上。分布式文件系统常用于大规模或分布式计算环境,以提供容错能力、高可用性和增强性能。
14、通知系统
这些功能用于向用户发送通知或警报,比如电子邮件、推送通知或短信。
15、全文检索
全文搜索允许用户在应用程序或网站中搜索特定的单词或短语。当接收到用户查询时,应用程序或网站会提供最相关的结果。为了快速有效地完成这个过程,全文搜索使用了一种称为倒排索引的数据结构,该结构将单词或短语与出现它们的文档进行关联。Elastic Search就是这样一种系统的例子。
16、分布式协调服务
分布式协调服务是一种旨在以可靠、高效和容错的方式调控和同步分布式应用、服务或节点行为的系统。它们帮助维护一致性,处理分布式同步,并在分布式环境中监控各种组件的配置和状态。在大规模或复杂的系统中,例如微服务架构、分布式计算环境或集群数据库,分布式协调服务尤其有价值。Apache ZooKeeper、etcd和Consul就是这样服务的例子。
17、心跳
在分布式环境中,工作/数据在服务器之间分布。为了在这样的设置中高效地路由请求,服务器需要知道系统中的其他服务器。此外,服务器应该知道其他服务器是否还在正常运作。在去中心化系统中,每当一个请求到达服务器时,该服务器应该有足够的信息来决定哪个服务器应负责处理该请求。这使得及时检测服务器故障成为一项重要任务,它还使系统能够采取纠正行动,将数据/工作移至另一台健康的服务器,阻止环境进一步恶化。
为了解决这个问题,每个服务器会定期向中心监控服务器或系统中的其他服务器发送心跳消息,以显示它仍然存活并正常工作。
心跳是检测分布式系统中故障的一种机制。如果有一个中心服务器,所有服务器会定期向它发送心跳消息。如果没有中心服务器,所有服务器会随机选择一组服务器,并每隔几秒钟向它们发送一条心跳消息。这样,如果一段时间没有收到来自某台服务器的心跳消息,系统就会怀疑该服务器可能已经崩溃。如果在配置的超时期内没有心跳,系统可以得出服务器不再存活的结论,并停止向其发送请求,并开始替换工作。
18、校验和
在一个分布式系统中,在组件之间传输数据时,从节点获取的数据可能会出现损坏的情况。这种损坏可能是由于存储设备、网络、软件等方面的故障导致的。分布式系统如何确保数据完整性,以便客户端接收到错误而不是损坏的数据?
为了解决这个问题,我们可以计算一个校验和并将其与数据一起存储。
为了计算校验和,我们使用了一种加密哈希函数,例如MD5、SHA-1、SHA-256或SHA-512。哈希函数接受输入数据并产生一个固定长度的字符串(包含字母和数字),这个字符串被称为校验和。
当系统存储某些数据时,它计算数据的校验和并将校验和与数据一起存储。当客户端检索数据时,它验证从服务器接收到的数据是否与存储的校验和相匹配。如果不匹配,客户端可以选择从另一个副本中检索该数据。
结论
通过使用上述系统设计概念和模板,最大限度地提高您的系统设计方案。