基于百分比的路由算法
Percentage based routing algorithm
浏览基于百分比的路由,偶然发现this thread。
根据下面提出的算法:
对于给定的模型如下:
public class Host {
private String name;
private int percentageLoad;
private int percentageAccum;
}
percentageAccum 的初始值为 percentageLoad 的值。
收到请求时:
- 选择累积百分比最大的主机
- 从所选主机的 percentageAccum 中减去 100
- 将所有主机的 percentageLoad 添加到 percentageAccum,包括所选主机
下面是我的实现
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class HostWeightage{
private String hostId;
private int weightage;
private int accumulatedWeightageSoFar;
}
样本Java执行者
public String getRoutedHost(List<HostWeightage> hostWeightageList) {
// assume 0th index as default
HostWeightage hostWithMaxAccWeight = hostWeightageList.get(0);
// choose the host with the largest percentageAccum
for (int i = 1; i < hostWeightageList.size(); i++) {
if (hostWeightageList.get(i).getAccumulatedWeightageSoFar() >= hostWithMaxAccWeight.getAccumulatedWeightageSoFar()){
hostWithMaxAccWeight = hostWeightageList.get(i);
}
}
// subtract 100 from the percentageAccum for the chosen host
int inverseAccWeight = hostWithMaxAccWeight.getAccumulatedWeightageSoFar() - 100;
hostWithMaxAccWeight.setAccumulatedWeightageSoFar(inverseAccWeight);
// add percentageLoad to percentageAccum for all hosts, including the chosen host
int weight = hostWithMaxAccWeight.getWeightage();
for (HostWeightage wightedHost : hostWeightageList) {
int accWeight = wightedHost.getAccumulatedWeightageSoFar();
wightedHost.setAccumulatedWeightageSoFar(weight + accWeight);
}
return hostWithMaxAccWeight.getHostId();
}
这是我的示例运行,每个调用 10 次
INFO: initial config
HostWeightage(hostId=redirect_host_1, weightage=10, accumulatedWeightageSoFar=10),
HostWeightage(hostId=redirect_host_2, weightage=40, accumulatedWeightageSoFar=40),
HostWeightage(hostId=redirect_host_3, weightage=50, accumulatedWeightageSoFar=50)
final distribution of 10 calls:
INFO: host1 3 ( should have been 1)
INFO: host2 3 ( should have been 4)
INFO: host3 4 ( should have been 5)
-------------------------
INFO: initial config
HostWeightage(hostId=redirect_host_1, weightage=30, accumulatedWeightageSoFar=30),
HostWeightage(hostId=redirect_host_2, weightage=30, accumulatedWeightageSoFar=30),
HostWeightage(hostId=redirect_host_3, weightage=40, accumulatedWeightageSoFar=40)
final distribution of 10 calls:
INFO: host1 3 ( correct output )
INFO: host2 3 ( correct output )
INFO: host3 4 ( correct output )
-------------------------
INFO: initial config
HostWeightage(hostId=redirect_host_1, weightage=10, accumulatedWeightageSoFar=10),
HostWeightage(hostId=redirect_host_2, weightage=20, accumulatedWeightageSoFar=20),
HostWeightage(hostId=redirect_host_3, weightage=70, accumulatedWeightageSoFar=70)
final distribution of 10 calls:
INFO: host1 3 ( should have been 1 )
INFO: host2 3 ( should have been 2 )
INFO: host3 4 ( should have been 7 )
任何指向算法实现错误的指针都将受到赞赏!!
问题出在代码末尾的循环中。由于行:
,它对所有主机使用相同的权重
int weight = hostWithMaxAccWeight.getWeightage();
添加到每个主机累加器的权重需要是该主机的权重,而不是所选主机的权重。所以循环应该是:
for (HostWeightage weightedHost : hostWeightageList) {
int weight = weightedHost.getWeightage();
int accWeight = weightedHost.getAccumulatedWeightageSoFar();
weightedHost.setAccumulatedWeightageSoFar(weight + accWeight);
}
使用权重 A:10 B:80 C:10
的算法示例 运行 如下所示:
accumulators
A B C
10 80 10 choose B
20 60 20 choose B
30 40 30 choose B
40 20 40 choose A
-50 100 50 choose B
-40 80 60 choose B
-30 60 70 choose C
-20 140 -20 choose B
-10 120 -10 choose B
0 100 0 choose B
10 80 10 back to start
浏览基于百分比的路由,偶然发现this thread。
根据下面提出的算法:
对于给定的模型如下:
public class Host {
private String name;
private int percentageLoad;
private int percentageAccum;
}
percentageAccum 的初始值为 percentageLoad 的值。
收到请求时:
- 选择累积百分比最大的主机
- 从所选主机的 percentageAccum 中减去 100
- 将所有主机的 percentageLoad 添加到 percentageAccum,包括所选主机
下面是我的实现
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class HostWeightage{
private String hostId;
private int weightage;
private int accumulatedWeightageSoFar;
}
样本Java执行者
public String getRoutedHost(List<HostWeightage> hostWeightageList) {
// assume 0th index as default
HostWeightage hostWithMaxAccWeight = hostWeightageList.get(0);
// choose the host with the largest percentageAccum
for (int i = 1; i < hostWeightageList.size(); i++) {
if (hostWeightageList.get(i).getAccumulatedWeightageSoFar() >= hostWithMaxAccWeight.getAccumulatedWeightageSoFar()){
hostWithMaxAccWeight = hostWeightageList.get(i);
}
}
// subtract 100 from the percentageAccum for the chosen host
int inverseAccWeight = hostWithMaxAccWeight.getAccumulatedWeightageSoFar() - 100;
hostWithMaxAccWeight.setAccumulatedWeightageSoFar(inverseAccWeight);
// add percentageLoad to percentageAccum for all hosts, including the chosen host
int weight = hostWithMaxAccWeight.getWeightage();
for (HostWeightage wightedHost : hostWeightageList) {
int accWeight = wightedHost.getAccumulatedWeightageSoFar();
wightedHost.setAccumulatedWeightageSoFar(weight + accWeight);
}
return hostWithMaxAccWeight.getHostId();
}
这是我的示例运行,每个调用 10 次
INFO: initial config
HostWeightage(hostId=redirect_host_1, weightage=10, accumulatedWeightageSoFar=10),
HostWeightage(hostId=redirect_host_2, weightage=40, accumulatedWeightageSoFar=40),
HostWeightage(hostId=redirect_host_3, weightage=50, accumulatedWeightageSoFar=50)
final distribution of 10 calls:
INFO: host1 3 ( should have been 1)
INFO: host2 3 ( should have been 4)
INFO: host3 4 ( should have been 5)
-------------------------
INFO: initial config
HostWeightage(hostId=redirect_host_1, weightage=30, accumulatedWeightageSoFar=30),
HostWeightage(hostId=redirect_host_2, weightage=30, accumulatedWeightageSoFar=30),
HostWeightage(hostId=redirect_host_3, weightage=40, accumulatedWeightageSoFar=40)
final distribution of 10 calls:
INFO: host1 3 ( correct output )
INFO: host2 3 ( correct output )
INFO: host3 4 ( correct output )
-------------------------
INFO: initial config
HostWeightage(hostId=redirect_host_1, weightage=10, accumulatedWeightageSoFar=10),
HostWeightage(hostId=redirect_host_2, weightage=20, accumulatedWeightageSoFar=20),
HostWeightage(hostId=redirect_host_3, weightage=70, accumulatedWeightageSoFar=70)
final distribution of 10 calls:
INFO: host1 3 ( should have been 1 )
INFO: host2 3 ( should have been 2 )
INFO: host3 4 ( should have been 7 )
任何指向算法实现错误的指针都将受到赞赏!!
问题出在代码末尾的循环中。由于行:
,它对所有主机使用相同的权重int weight = hostWithMaxAccWeight.getWeightage();
添加到每个主机累加器的权重需要是该主机的权重,而不是所选主机的权重。所以循环应该是:
for (HostWeightage weightedHost : hostWeightageList) {
int weight = weightedHost.getWeightage();
int accWeight = weightedHost.getAccumulatedWeightageSoFar();
weightedHost.setAccumulatedWeightageSoFar(weight + accWeight);
}
使用权重 A:10 B:80 C:10
的算法示例 运行 如下所示:
accumulators
A B C
10 80 10 choose B
20 60 20 choose B
30 40 30 choose B
40 20 40 choose A
-50 100 50 choose B
-40 80 60 choose B
-30 60 70 choose C
-20 140 -20 choose B
-10 120 -10 choose B
0 100 0 choose B
10 80 10 back to start