我目前使用 DNS 轮询进行负载平衡,效果很好。记录如下所示(我的 TTL 为 120 秒)
;; ANSWER SECTION:
orion.2x.to. 116 IN A 80.237.201.41
orion.2x.to. 116 IN A 87.230.54.12
orion.2x.to. 116 IN A 87.230.100.10
orion.2x.to. 116 IN A 87.230.51.65
我了解到,并非所有 ISP/设备都以相同的方式处理此类响应。例如,一些 DNS 服务器会随机轮换地址或始终循环使用。有些服务器只是传播第一个条目,而另一些服务器则尝试通过查看 IP 地址来确定哪个条目最好(区域接近)。
但是,如果用户群足够大(分布在多个 ISP 等),平衡性会相当好。负载最高的服务器与负载最低的服务器之间的差异几乎不会超过 15%。
然而现在我遇到的问题是,我正在向系统中引入更多的服务器,但并非所有服务器都具有相同的容量。
我目前只有 1 Gbps 的服务器,但我也想使用 100 Mbps 和 10 Gbps 的服务器。
所以我想要引入一个权重为 100 的 10 Gbps 服务器,一个权重为 10 的 1 Gbps 服务器和一个权重为 1 的 100 Mbps 服务器。
我之前曾两次添加服务器以增加流量(效果不错——带宽几乎翻倍)。但向 DNS 添加 10 Gbps 服务器 100 次有点荒谬。
所以我考虑使用TTL。
如果我给服务器 A 240 秒 TTL,而给服务器 B 仅 120 秒(这大约是循环使用的最小值,因为如果指定了较低的 TTL,许多 DNS 服务器会将其设置为 120(我听说是这样))。我认为在理想情况下应该会发生类似这样的事情:
First 120 seconds
50% of requests get server A -> keep it for 240 seconds.
50% of requests get server B -> keep it for 120 seconds
Second 120 seconds
50% of requests still have server A cached -> keep it for another 120 seconds.
25% of requests get server A -> keep it for 240 seconds
25% of requests get server B -> keep it for 120 seconds
Third 120 seconds
25% will get server A (from the 50% of Server A that now expired) -> cache 240 sec
25% will get server B (from the 50% of Server A that now expired) -> cache 120 sec
25% will have server A cached for another 120 seconds
12.5% will get server B (from the 25% of server B that now expired) -> cache 120sec
12.5% will get server A (from the 25% of server B that now expired) -> cache 240 sec
Fourth 120 seconds
25% will have server A cached -> cache for another 120 secs
12.5% will get server A (from the 25% of b that now expired) -> cache 240 secs
12.5% will get server B (from the 25% of b that now expired) -> cache 120 secs
12.5% will get server A (from the 25% of a that now expired) -> cache 240 secs
12.5% will get server B (from the 25% of a that now expired) -> cache 120 secs
6.25% will get server A (from the 12.5% of b that now expired) -> cache 240 secs
6.25% will get server B (from the 12.5% of b that now expired) -> cache 120 secs
12.5% will have server A cached -> cache another 120 secs
... I think I lost something at this point, but I think you get the idea...
正如您所见,预测起来相当复杂,而且在实践中肯定不会这样。但它肯定会对分布产生影响!
我知道加权循环机制是存在的,并且仅由根服务器控制。它只是在响应时循环 DNS 记录,并返回具有与权重相对应的设定概率的 DNS 记录。我的 DNS 服务器不支持此功能,而且我的要求也不是那么精确。如果它的权重不完美,那也没关系,但它应该朝着正确的方向发展。
我认为使用 TTL 字段可能是一种更优雅、更简单的解决方案 - 并且它不需要动态控制它的 DNS 服务器,从而节省资源 - 在我看来,这是 DNS 负载平衡与硬件负载平衡器的全部意义所在。
我现在的问题是:是否有任何最佳实践/方法/经验规则来使用 DNS 记录的 TTL 属性来加权循环分配?
编辑:
该系统是一个正向代理服务器系统。带宽量(不是请求量)超过了一台以太网服务器可以处理的量。所以我需要一个平衡解决方案,将带宽分配给多台服务器。除了使用 DNS 之外还有其他方法吗?当然,我可以使用带有光纤通道等的负载平衡器,但成本太高,而且它只会增加瓶颈的宽度,而不会消除瓶颈。我能想到的唯一东西是任播(是任播还是多播?)IP 地址,但我没有办法建立这样的系统。
答案1
首先,我完全同意@Alnitak 的观点,DNS 不是为这种事情设计的,最佳做法是不要将 DNS 滥用为穷人的负载均衡器。
我现在的问题是......是否有任何最佳实践/方法/经验规则来使用 DNS 记录的 TTL 属性来加权循环分布?
根据问题的前提来回答,使用 DNS 执行 basix 加权循环的方法是:
- 调整相对发生率权威 DNS 响应中的记录。例如,如果
Server A
要拥有 1/3 的流量,而Server B
要拥有 2/3,那么对 DNS 代理的权威 DNS 响应的 1/3 将包含仅有的A
的 IP,而 2/3 的响应仅B
是 的 IP。(如果 2 个或更多服务器共享相同的“权重”,则它们可以捆绑成一个响应。) - 保持较低的 DNS TTL,以便相对快速地平衡不平衡的负载。由于下游 DNS 代理后面的客户端数量非常不均匀,因此您需要频繁地重新调整记录。
亚马逊的Route 53 DNS 服务使用此方法。
带宽(不是请求)量超出了一台以太网服务器的处理能力。因此我需要一个平衡解决方案,将带宽分配给多台服务器。
是的。据我了解,您拥有某种“廉价”下载/视频分发/大文件下载服务,总服务比特率超过 1 GBit。
如果不知道你的服务和服务器布局的具体细节,就很难准确判断。但是A这种情况下常见的解决办法是:
- DNS 循环到两个或多个 TCP/IP 或 HTTP 级别负载均衡器实例。
- 每个负载均衡器实例都具有高度可用性(2 个相同的负载均衡器协作以始终保持一个 IP 地址处于开启状态)。
- 每个负载均衡器实例使用加权循环或加权随机连接处理到后端服务器。
这种设置可以用开源软件来构建,也可以用许多供应商提供的专用设备来构建。负载平衡标签这是一个很好的起点,或者您可以聘请以前做过此事的系统管理员为您提供咨询......
答案2
我现在的问题是......是否有任何最佳实践/方法/经验规则来使用 DNS 记录的 TTL 属性来加权循环分布?
是的,最佳做法是不要这样做!!
请跟我重复
- DNS 不用于负载平衡
- DNS 不提供弹性
- DNS 不提供故障转移功能
DNS 用于映射姓名到一个或多个 IP 地址. 任何后续的平衡都是靠运气,而不是设计。
答案3
看一眼强力DNS。它允许您创建自定义管道后端。我修改了一个用 perl 编写的示例负载均衡器 DNS 后端以使用算法:一致性哈希::Ketama 模块。这样我就可以像这样设置任意权重:
my $ketamahe = Algorithm::ConsistentHash::Ketama->new();
# Configure servers and weights
$ketamahe->add_bucket("192.168.1.2", 50);
$ketamahe->add_bucket("192.168.1.25", 50);
还有一个:
# multi-colo hash
my $ketamamc = Algorithm::ConsistentHash::Ketama->new();
# Configure servers and weights
$ketamamc->add_bucket("192.168.1.2", 33);
$ketamamc->add_bucket("192.168.1.25", 33);
$ketamamc->add_bucket("192.168.2.2", 17);
$ketamamc->add_bucket("192.168.2.2", 17);
我已经将所需顶级域名的 cname 添加到我称为 gslb(即全局服务器负载平衡)的子域名。从那里,我调用此自定义 DNS 服务器并根据所需权重发送 A 记录。
效果极佳。ketama hash 具有良好的特性,即在添加服务器或调整权重时对现有配置的干扰最小。
我建议阅读 Jan-Piet Mens 的《Alternative DNS Servers》。他在书中提出了许多好的想法,并提供了示例代码。
我还建议放弃 TTL 调制。您已经走得太远了,再添加一个临时解决方案将使故障排除和文档记录变得极其困难。
答案4
要处理此类设置,您需要研究真正的负载平衡解决方案。阅读Linux 虚拟服务器和HAProxy。如果服务器发生故障,它们会自动从池中移除,这会带来额外的好处,而且其影响也更容易理解。权重只是一个需要调整的设置。