负载均衡器类型
一般来说,负载均衡器分为三类:
- DNS 轮询(很少使用):客户端获得一个随机顺序的 IP 地址列表。
- 优点:易于实现且免费
- 缺点:难以控制且响应不佳,因为 DNS 缓存需要时间过期
- 网络(L3/L4)负载均衡器:流量通过 IP 地址和端口进行路由。L3 是网络层(IP)。L4 是会话层(TCP)。
- 优点:更好的粒度,简单,响应迅速
- 应用(L7)负载均衡器:流量根据 HTTP 协议中的内容进行路由。L7 是应用层(HTTP)。
一般来说,负载均衡器分为三类:
B 树的优点
B+ 树的优点
经验中等或更少,或在之前的职位中没有担任领导或设计职位(无论是正式还是非正式)的人
描述您之前的一个项目,这个项目对您来说特别有趣或令人难忘。后续问题:
是什么让这个项目有趣? 项目中最具挑战性的部分是什么,您是如何应对这些挑战的? 您从项目中学到了什么,您希望在开始之前知道什么? 您考虑过其他设计/实施方法吗?您为什么选择了您所选择的那个?如果您要重新做同样的项目,您会有什么不同的做法?
由于这里的目标是评估一个可能从未担任过可以进行速成课程角色的人的技术沟通能力和兴趣水平,您应该准备好不断向他们提问(无论是为了获取更多细节,还是关于项目的其他方面)。如果他们是最近毕业的学生并做了论文,通常这是一个很好的谈论选择。虽然这个问题在许多方面与电话筛选中的简历问题相似,但这个问题的预期长度大约是四倍,并且应该更详细地探讨他们所做的事情。因此,评分标准相似,但应以更高的期望和更多的数据进行评估。
优秀候选人将会
能够在整个时间内谈论项目,面试官的互动将是对话而非指引
对整个项目有深入了解,而不仅仅是他们关注的领域,并能够清晰表达项目的意图和设计
对项目充满热情,能够清楚描述激发这种热情的项目元素
能够清晰解释考虑过的替代方案,以及为什么选择了他们所采用的实施策略
对自己的经历进行了反思并从中学习
良好候选人将会
可能在全程谈话中遇到一些困难,但在面试官的帮助和提问下能够进行交流
可能对项目的整体范围缺乏一些了解,但仍对他们的特定领域和直接与他们互动的部分有较强的知识
可能表现出热情,但无法清楚解释是什么激发了这种热情
可能能够讨论他们所做的替代方案,但没有深入考虑
对自己的经历进行了反思并从中学习
差劲候选人将会
在全程谈话中遇到困难。面试官 可能会感到他们是在审问而不是与候选人交谈
可能对项目缺乏详细了解,即使在他们工作的领域内。他们可能不理解他们的部分是如何设计的,或者可能不理解它如何与其他系统互动
对项目似乎不太感兴趣——请记住,您是在询问他们做过的最有趣的项目,他们应该对无论是什么项目都非常感兴趣
可能对他们的实施方法的潜在替代方案不熟悉
似乎没有从项目的经历中学习或反思。一个关键的迹象是对“你学到了什么”和“你会有什么不同的做法”的回答很简短和/或几乎相同。
大数据集 ⟶ 扩展 ⟶ 数据分片 / 分区 ⟶ 1) 数据访问的路由 2) 可用性的副本
路由抽象模型本质上只有两张地图:1) 键-分区图 2) 分区-机器图
哈希和取模
虚拟桶:键--(哈希)-->虚拟桶,虚拟桶--(表查找)-->服务器
一致性哈希和 DHT
按主键排序,按主键范围分片
范围-服务器查找表(例如 HBase .META. 表)+ 本地基于树的索引(例如 LSM,B+)
(+) 搜索范围 (-) log(n)
使用案例:Yahoo PNUTS,Azure,Bigtable
系统设计面试是为了让人们找到能够独立设计和实施互联网服务的团队成员。面试是展示你“工程能力”的绝佳机会——你必须将你的知识与决策能力结合起来,为正确的场景设计合适的系统。
关于系统设计面试,你需要知道的第一件事是,你必须在整个面试过程中保持健谈。当然,你必须咨询面试官,以确定你是否在正确的轨道上,能够满足他们的需求;然而,你仍然需要证明你可以独立完成工作。因此,理想情况下,在面试过程中,你应该不断谈论面试官所期望的内容,甚至在他们提出问题之前。
其次,不要仅限于一种解决方案。面对同样的问题,可能有很多种解决方法,成为工程师并不需要许可证。你所做的所有选择都有利弊。与面试官讨论权衡,并选择最适合你假设和约束条件的解决方案。这就像在现实世界中,人们不会在沟渠上建造金门大桥,也不会在旧金山湾上建造临时桥。
最后,要在面试中表现出色,你最好带来一些新东西。“优秀的工程师编写脚本;伟大的工程师创新”。如果你不能教会人们一些新东西,你只是优秀,而不是伟大。优质答案 = 新颖性 x 共鸣。
如果你不确定如何在面试中保持健谈,这里有一个简单的 4 步模板,你可以以分而治之的方式遵循:
本书中的所有设计都将遵循这些步骤。
特别是对于这个“设计 Pinterest”,我将尽可能详细地解释一切,因为这是整本书的第一个案例。然而,为了简单起见,我不会在本书的其他设计中涵盖许多元素。
所有系统存在都是有目的的,软件系统也是如此。同时,软件工程师不是艺术家——我们构建东西是为了满足客户的需求。因此,我们应该始终从客户出发。同时,为了将设计适应 45 分钟的会议,我们必须通过做出假设来设定约束和范围。
Pinterest 是一个高度可扩展的照片分享服务,拥有数亿月活跃用户。以下是需求:
在勾勒出大局之前,不要深入细节。 否则,走错方向会浪费时间,并阻止你完成任务。
这是高层架构,其中箭头表示依赖关系。(有时,人们会使用箭头来描述数据流的方向。)
一旦架构确定,我们可以与面试官确认他们是否希望与你一起深入探讨每个组件。有时,面试官可能希望聚焦于一个意想不到的领域问题,比如设计照片存储(这就是我总是说没有一种适合所有的系统设计解决方案的原因。继续学习...)。然而,在这里,我们仍然假设我们正在构建核心抽象:上传照片,然后发布给关注者。
再次强调,我将尽可能多地以自上而下的顺序进行解释,因为这是我们的第一个设计示例。在现实世界中,你不必逐个组件地详细讨论;相反,你应该首先关注核心抽象。
移动和浏览器客户端通过边缘服务器连接到 Pinterest 数据中心。边缘服务器是提供网络入口的边缘设备。在图中,我们看到两种类型的边缘服务器——负载均衡器和反向代理。
负载均衡器将传入的网络流量分配给一组后端服务器。它们分为三类:
负载均衡器可以存在于许多其他地方,只要有平衡流量的需求。
与位于客户端前面的“正向”代理不同,反向代理是一种位于服务器前面的代理,因此称为“反向”。根据这个定义,负载均衡器也是一种反向代理。
反向代理根据使用方式带来了许多好处,以下是一些典型的好处:
Nginx、Varnish、HAProxy 和 AWS 弹性负载均衡是市场上流行的产品。我发现编写一个轻量级反向代理在 Golang 中既方便又强大。在 Kubernetes 的上下文中,这基本上就是 Ingress 和 Ingress 控制器所做的。
这是我们提供网页的地方。在早期,网络服务通常将后端与页面渲染结合在一起,如 Django 和 Ruby on Rails 框架所做的。后来,随着项目规模的增长,它们通常被解耦为专用的前端和后端项目。前端专注于应用渲染,而后端为前端提供 API 供其使用。