代码 Golang 随机公平库 satmihir/fair

2024-11-19 03:28:37 +0800 CST views 1095

Golang 随机公平库 satmihir/fair

FAIR 是一个 Go 库,旨在确保资源受限环境中的公平性。它帮助在资源短缺的情况下将有限的资源(如数据库/Blob 存储吞吐量、作业执行资源等)均匀分配给多个客户端,防止因客户端行为引起的过度分配和资源饥饿问题。

简介

FAIR 的核心算法基于随机公平的 BLUE[1] 算法,该算法通常用于网络拥塞控制,经过了一些修改。FAIR 的理念是在真正资源短缺时才进行限制,而不是像令牌桶或漏桶等方法一样,即使资源可用也可能拒绝请求。FAIR 采用了多级 Bloom Filter[2] 风格的数据结构,使所需的内存保持恒定,不会随客户端数量增加而扩展。在正确配置下,FAIR 可以扩展到大量客户端,具有较低的误报概率,并且得益于哈希轮换机制,误报持续时间接近于零。

主要特性

  • 框架和协议无关,易于集成到任何 HTTP/GRPC 服务中。
  • 自动调优,开箱即用,配置最少,但也可以进行全面调优。
  • 可扩展到大量客户端,内存需求恒定。
  • 简单的资源和错误跟踪模型,适用于多种类型的资源限制场景。

评估

在一个评估例子中,20 个客户端竞争一个以 20/s 的速率再生的资源。20 个客户端中有 18 个表现良好,它们每秒请求一次资源,剩下的两个客户端则每 100 毫秒请求一次。在不受限制的情况下,不公平的客户端抢占了大量资源,而常规工作负载处于饥饿状态,资源获取速率远低于 1/s。使用 FAIR 限制后,常规工作负载几乎不受影响,不公平的工作负载则受到限制,且长时间内也能获得公平份额。

安装

使用 go get 安装 FAIR 库:

go get github.com/satmihir/fair

在 Go 代码中导入:

import "github.com/satmihir/fair"

使用方法

默认配置

使用默认配置(通常效果良好):

trkB := tracker.NewFairnessTrackerBuilder()
trk, err := trkB.BuildWithDefaultConfig()
defer trk.Close()

自定义配置

通过 setter 修改配置:

trkB := tracker.NewFairnessTrackerBuilder()
// 设置底层哈希每分钟轮换一次,避免误报
trkB.SetRotationFrequency(1 * time.Minute)

trk, err := trkB.Build()
defer trk.Close()

注册请求

对于每个传入请求,使用流标识符(例如客户端 ID)来判断是否需要限制:

ctx := context.Background()
id := []byte("client_id")

resp, _ := trk.RegisterRequest(ctx, id)
if resp.ShouldThrottle {
    throttleRequest()
}

报告失败

当资源不足时,报告失败以触发限制:

ctx := context.Background()
id := []byte("client_id")

trk.ReportOutcome(ctx, id, request.OutcomeFailure)

报告成功

成功获取资源时,报告成功:

ctx := context.Background()
id := []byte("client_id")

trk.ReportOutcome(ctx, id, request.OutcomeSuccess)

调优

使用 GenerateTunedStructureConfig 调优跟踪器配置:

conf := config.GenerateTunedStructureConfig(1000, 1000, 25)
trkB := tracker.NewFairnessTrackerBuilder()

trk, err := trkB.BuildWithConfig(conf)
defer trk.Close()

参考链接

复制全文 生成海报 编程 资源管理 算法 软件开发 Golang

推荐文章

mysql 计算附近的人
2024-11-18 13:51:11 +0800 CST
Vue3中如何实现响应式数据?
2024-11-18 10:15:48 +0800 CST
PHP 微信红包算法
2024-11-17 22:45:34 +0800 CST
为什么大厂也无法避免写出Bug?
2024-11-19 10:03:23 +0800 CST
一个简单的html卡片元素代码
2024-11-18 18:14:27 +0800 CST
jQuery `$.extend()` 用法总结
2024-11-19 02:12:45 +0800 CST
js迭代器
2024-11-19 07:49:47 +0800 CST
Linux 常用进程命令介绍
2024-11-19 05:06:44 +0800 CST
Nginx 跨域处理配置
2024-11-18 16:51:51 +0800 CST
Golang 中应该知道的 defer 知识
2024-11-18 13:18:56 +0800 CST
Golang在整洁架构中优雅使用事务
2024-11-18 19:26:04 +0800 CST
PHP 如何输出带微秒的时间
2024-11-18 01:58:41 +0800 CST
MySQL设置和开启慢查询
2024-11-19 03:09:43 +0800 CST
css模拟了MacBook的外观
2024-11-18 14:07:40 +0800 CST
在 Rust 中使用 OpenCV 进行绘图
2024-11-19 06:58:07 +0800 CST
Redis函数在PHP中的使用方法
2024-11-19 04:42:21 +0800 CST
PHP 允许跨域的终极解决办法
2024-11-19 08:12:52 +0800 CST
Go 语言实现 API 限流的最佳实践
2024-11-19 01:51:21 +0800 CST
程序员茄子在线接单