分布式系统设计之常见的负载均衡算法

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 分布式系统设计之常见的负载均衡算法

分布式系统设计之常见的负载均衡算法

0 什么是负载均衡?

负载均衡(Load Balance),其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,从而协同完成工作任务。

负载均衡都分为哪些种类?

  • 软件和硬件负载均衡
  • 软件负载均衡
  • 硬件负载均衡
  • 本地和全局负载均衡
  • 本地负载均衡
  • 全局负载均衡

本篇文章的负载均衡算法是属于软件层面的负载均衡。

1 轮询

顾名思义,将子任务在子节点中一个接一个有序的询问请求。

var list = make([]string, 0)
var servers = make(map[string]string)
func init() {
   servers = map[string]string{
      "stringA": "10.0.0.1",
      "stringB": "10.0.0.2",
      "stringC": "10.0.0.3",
   }
   for s := range servers {
      list = append(list, s)
   }
}
//轮询
var i = 0
func RoundRobin() string {
   if i >= len(list) {
      i = 0
   }
   str := servers[list[i]]
   i += 1
   return str
}
复制代码

2 随机

在子节点中随机的进行请求。

var list = make([]string, 0)
var servers = make(map[string]string)
func init() {
   servers = map[string]string{
      "stringA": "10.0.0.1",
      "stringB": "10.0.0.2",
      "stringC": "10.0.0.3",
   }
   for s := range servers {
      list = append(list, s)
   }
}
//随机
func Random() string {
   i := rand.Intn(len(list))
   return servers[list[i]]
}
复制代码

3 加权轮询

与轮询不同的是,可以增加权重,就是说权重最大的节点会有更多次数(比例)的请求。

var list = make([]string, 0)
var servers = make(map[string]string)
func init() {
   servers = map[string]string{
      "stringA": "10.0.0.1",
      "stringB": "10.0.0.2",
      "stringC": "10.0.0.3",
   }
   for s := range servers {
      list = append(list, s)
   }
   //加权轮询
   var weight_map = map[string]int{
      "stringA": 1,
      "stringB": 2,
      "stringC": 3,
   }
   for s := range weight_map {
      for i := 0; i < weight_map[s]-1; i++ {
         list = append(list, s)
      }
   }
}
//加权轮询
func WeightRoundRobin() string {
   if i >= len(list) {
      i = 0
   }
   str := servers[list[i]]
   i += 1
   return str
}
复制代码

4 加权随机

与随机不同的是,增加某个节点被随机访问的概率。

var list = make([]string, 0)
var servers = make(map[string]string)
func init() {
   servers = map[string]string{
      "stringA": "10.0.0.1",
      "stringB": "10.0.0.2",
      "stringC": "10.0.0.3",
   }
   for s := range servers {
      list = append(list, s)
   }
   //加权轮询
   var weight_map = map[string]int{
      "stringA": 1,
      "stringB": 2,
      "stringC": 3,
   }
   for s := range weight_map {
      for i := 0; i < weight_map[s]-1; i++ {
         list = append(list, s)
      }
   }
}
//加权随机
func WeightRandom() string {
   i := rand.Intn(len(list))
   return servers[list[i]]
}
复制代码

5 源地址哈希

该方法是将请求的源地址进行哈希,并将哈希的结果进行取余,将取余后的结果进行节点的匹配最后进行请求。

//Source Hash
func Hash() string {
   //对客户端(源)地址做哈希 使用md5哈希算法
   has, err := md5.New().Write([]byte("127.0.0.1"))
   if err != nil {
      panic(err)
   }
   i := has % len(list)
   return servers[list[i]]
}
复制代码

6 最小连接数

最小连接数法是根据服务器当前的连接情况进行负载均衡的,当请求到来时,会选取当前连接数最少的一台服务器来处理请求。由此也可以延伸出,根据服务器 CPU 占用最少,根据单位时间内处理请求的效率高低等进行服务器选择。最小连接数法只是动态分配服务器的一种算法,通过各种维度的参数计算,可以找到适合不同场景的更均衡的动态分配服务器的方案。

7 全部代码

package main
import (
   "crypto/md5"
   "math/rand"
   "net/http"
)
var list = make([]string, 0)
var servers = make(map[string]string)
func init() {
   servers = map[string]string{
      "stringA": "10.0.0.1",
      "stringB": "10.0.0.2",
      "stringC": "10.0.0.3",
   }
   for s := range servers {
      list = append(list, s)
   }
   //加权轮询
   var weight_map = map[string]int{
      "stringA": 1,
      "stringB": 2,
      "stringC": 3,
   }
   for s := range weight_map {
      for i := 0; i < weight_map[s]-1; i++ {
         list = append(list, s)
      }
   }
}
//轮询
var i = 0
func RoundRobin() string {
   if i >= len(list) {
      i = 0
   }
   str := servers[list[i]]
   i += 1
   return str
}
//随机
func Random() string {
   i := rand.Intn(len(list))
   return servers[list[i]]
}
//Source Hash
func Hash() string {
   //对客户端(源)地址做哈希 使用md5哈希算法
   has, err := md5.New().Write([]byte("127.0.0.1"))
   if err != nil {
      panic(err)
   }
   i := has % len(list)
   return servers[list[i]]
}
//加权轮询
func WeightRoundRobin() string {
   if i >= len(list) {
      i = 0
   }
   str := servers[list[i]]
   i += 1
   return str
}
//加权随机
func WeightRandom() string {
   i := rand.Intn(len(list))
   return servers[list[i]]
}
//----------Web测试---------------//
func main() {
   //httpServer(WeightRandom)
}
func httpServer(fun func() string) {
   http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
      w.Write([]byte("Request Node is " + fun()))
   })
   http.ListenAndServe(":8888", nil)
}
复制代码

参考文章:

blog.csdn.net/claram/arti…


相关实践学习
小试牛刀,一键部署电商商城
SAE 仅需一键,极速部署一个微服务电商商城,体验 Serverless 带给您的全托管体验,一起来部署吧!
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
8月前
|
存储 负载均衡 算法
负载均衡算法
负载均衡算法
102 1
|
2月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
2月前
|
NoSQL 算法 安全
分布式锁—1.原理算法和使用建议
本文主要探讨了Redis分布式锁的八大问题,包括非原子操作、忘记释放锁、释放其他线程的锁、加锁失败处理、锁重入问题、锁竞争问题、锁超时失效及主从复制问题,并提供了相应的优化措施。接着分析了Redis的RedLock算法,讨论其优缺点以及分布式专家Martin对其的质疑。此外,文章对比了基于Redis和Zookeeper(zk)的分布式锁实现原理,包括获取与释放锁的具体流程。最后总结了两种分布式锁的适用场景及使用建议,指出Redis分布式锁虽有性能优势但模型不够健壮,而zk分布式锁更稳定但部署成本较高。实际应用中需根据业务需求权衡选择。
|
8月前
|
缓存 负载均衡 算法
slb支持多种负载均衡算法
slb支持多种负载均衡算法
243 6
|
5月前
|
运维 NoSQL 算法
【📕分布式锁通关指南 04】redis分布式锁的细节问题以及RedLock算法原理
本文深入探讨了基于Redis实现分布式锁时遇到的细节问题及解决方案。首先,针对锁续期问题,提出了通过独立服务、获取锁进程自己续期和异步线程三种方式,并详细介绍了如何利用Lua脚本和守护线程实现自动续期。接着,解决了锁阻塞问题,引入了带超时时间的`tryLock`机制,确保在高并发场景下不会无限等待锁。最后,作为知识扩展,讲解了RedLock算法原理及其在实际业务中的局限性。文章强调,在并发量不高的场景中手写分布式锁可行,但推荐使用更成熟的Redisson框架来实现分布式锁,以保证系统的稳定性和可靠性。
214 0
【📕分布式锁通关指南 04】redis分布式锁的细节问题以及RedLock算法原理
|
6月前
|
负载均衡 算法
架构学习:7种负载均衡算法策略
四层负载均衡包括数据链路层、网络层和应用层负载均衡。数据链路层通过修改MAC地址转发帧;网络层通过改变IP地址实现数据包转发;应用层有多种策略,如轮循、权重轮循、随机、权重随机、一致性哈希、响应速度和最少连接数均衡,确保请求合理分配到服务器,提升性能与稳定性。
1152 11
架构学习:7种负载均衡算法策略
|
6月前
|
存储 人工智能 算法
解锁分布式文件分享的 Java 一致性哈希算法密码
在数字化时代,文件分享成为信息传播与协同办公的关键环节。本文深入探讨基于Java的一致性哈希算法,该算法通过引入虚拟节点和环形哈希空间,解决了传统哈希算法在分布式存储中的“哈希雪崩”问题,确保文件分配稳定高效。文章还展示了Java实现代码,并展望了其在未来文件分享技术中的应用前景,如结合AI优化节点布局和区块链增强数据安全。
|
8月前
|
算法 关系型数据库 MySQL
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
在分布式系统中,确保每个节点生成的 ID 唯一且高效至关重要。Snowflake 算法由 Twitter 开发,通过 64 位 long 型数字生成全局唯一 ID,包括 1 位标识位、41 位时间戳、10 位机器 ID 和 12 位序列号。该算法具备全局唯一性、递增性、高可用性和高性能,适用于高并发场景,如电商促销时的大量订单生成。本文介绍了使用 Go 语言的 `bwmarrin/snowflake` 和 `sony/sonyflake` 库实现 Snowflake 算法的方法。
346 1
分布式唯一ID生成:深入理解Snowflake算法在Go中的实现
|
7月前
|
存储 算法 安全
分布式系统架构1:共识算法Paxos
本文介绍了分布式系统中实现数据一致性的重要算法——Paxos及其改进版Multi Paxos。Paxos算法由Leslie Lamport提出,旨在解决分布式环境下的共识问题,通过提案节点、决策节点和记录节点的协作,确保数据在多台机器间的一致性和可用性。Multi Paxos通过引入主节点选举机制,优化了基本Paxos的效率,减少了网络通信次数,提高了系统的性能和可靠性。文中还简要讨论了数据复制的安全性和一致性保障措施。
435 1
|
8月前
|
负载均衡 算法
SLB-Backend的负载均衡算法
【10月更文挑战第19天】
120 5

热门文章

最新文章