《深入浅出分布式技术原理》 学习笔记 day4

129 阅读5分钟

大家好,我是砸锅。一个摸鱼八年的后端开发。熟悉 Go、Lua。今天和大家一起学习分布式技术😊

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 16 天,点击查看活动详情

负载均衡

每一个被调用的服务都会有多个实例,那么服务的调用方应该将请求发向被调用服务的哪一个服务实例呢?这就是负载均衡的应用场景

负载均衡就是一个调度器,将发送给被调用服务的每一个请求,都按照一定策略分配给后端实例组中的其中一个实例,确保能高效、正确的提供服务

负载均衡的关键点

  1. 公平性。负载均衡需要关注被调用服务实例组之间的公平性,不能出现负载差异很大造成资源浪费的情况
  2. 正确性。负载均衡需要确保外部对后端服务的请求,一定能被路由到可以提供正确服务的实例上,不能出现不能处理和错误处理的情况

对于负载均衡策略的设计,影响最大的因素是后端实例是否存在状态,如果后端实例存在状态,负载均衡就需要关心请求的状态。依据负载均衡是否关心请求的状态,可以将负载均衡策略分为无状态的负载均衡、半状态的负载均衡和全状态的负载均衡

无状态的负载均衡

最常见的负载均衡模型就是无状态,所有的后端实例都是对等的,请求发向哪一个都可以得到正确且相同的处理结果,不需要关心请求的状态

轮询

轮询的负载均衡策略非常简单,只需要将请求按照顺序分配给多个后端实例就可以了,不需要做其他的处理。轮询在路由时,不利用请求的状态信息,属于无状态的负载均衡策略

权重轮询

权重轮询的负载均衡策略是将每一个后端实例分配一个权重,分配请求的数量和实例的权重成正比轮询,权重轮询在路由时,不利用请求的状态信息,属于无状态的负载均衡策略。在公平性方面,因为权重策略会按实例的权重比例来分配请求数,所以,我们可以利用它解决实例的处理能力差异的问题,认为它的公平性比轮询策略要好

无状态的负载均衡策略除了上面的两种外,还有 FAIR 、随机、权重随机和最少链接数等策略

半状态的负载均衡

半状态的负载均衡将请求按照一定的策略进行路由,后端实例可以利用路由规则来进行优化。例如使用 Hash 运算加求模来路由请求

Hash

Hash 负载均衡策略是指将请求的状态信息按照一定的 Hash 算法固定分配到一个实例里,例如根据请求来源 IP 地址或者用户的 ID,将同一个来源 IP 或者用户 ID 的请求固定在一个实例。例如公式:

i = MD5(ID)%2 // 2 是实例的数量

公平性方面,在不考虑 Hash 算法均匀性的情况下,Hash 策略会按 Hash 值按模等分,它和轮询策略类似,不能解决请求的工作负载和实例的处理能力差异的问题

一致性 Hash

Hash 的负载均衡策略中,最大的一个问题是基于机器数量求模,如果机器数量发生变化,请求和实例的分配关系机会将全部变化,这会影响它的正确性,而一致性 Hash 就可以用来解决这个问题:

image.png

假设 Hash 环的空间大小是 2^32,一致性 Hash 就只对固定值 2^32 求模,不会随着机器数量变化而变化。如果机器数量发生变化,例如 Node A 下线了,那么“键 5 ”将被路由到 Node B ,如果在“键 5 ”和 Node B 之间新增了一个节点,那么“键 5 ”将路由到新增的节点

不过假如后端实例数很少,例如只有两个,公平性就会出现问题,很容易造成负载不平衡。这时候可以通过增加虚拟节点的方法来解决,每个实例都生成多个虚拟实例,使分配更加均衡。对于实例之间性能差异的问题,一致性 Hash 策略通过让实例生成虚拟实例的数量,与该实例的权重成正比的策略来解决

全状态的负载均衡

全状态的负载均衡是指,负载均衡策略不仅利用请求的状态信息进行路由,并且在后端实例有状态的情况下,依然会保证路由的正确性

全状态的负载均衡一般以路由服务的形式存在,在路由服务里面,都会存储后端实例 ID 和状态信息的索引,在进行请求路由的时候,路由服务从请求的状态信息中获得索引的标识,通过查询索引获得后端实例的 ID,然后再进行路由

此文章为2月Day11学习笔记,内容来源于极客时间《深入浅出分布式技术原理》