主要参考:
轮询调度算法(Round-Robin Scheduling)
轮询算法 这是一个印度人写的,学习下。 来自 codeproject
但是随着各站点访问量和信息交流量的迅猛增长,如何使用最小的资源成本,提高网络的效率,最优化用户体验,已经成为网络管理人员不得不面对的挑战。
从技术上讲,就是ICP行业面临的网络资源有效利用问题,也就是如何进行对网络的访问分流,以便能够快速响应用户反应,即:负载均衡。
从这篇文章起,我们将讲述在负载均衡技术实现中的核心技术:负载均衡算法(算法)的原理及其实现,使大家对负载均衡底层技术有一个深刻的了解。这些算法是负载均衡设备中的核心实现基础。
本篇文章先讲述轮询调度算法 (Round-Robin)及其在此基础上改进型的权重轮询算法 (Weighted Round-Robin)。
负载均衡的基本算法,主要有以下几种(参考F5产品):
- 随机:负载均衡方法随机的把负载分配到各个可用的服务器上,通过随机数生成算法选取一个服务器,然后把连接发送给它。虽然许多均衡产品都支持该算法,但是它的有效性一直受到质疑,除非把服务器的可运行时间看的很重。
- 轮询:轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器。轮询算法在大多数情况下都工作的不错,但是如果负载均衡的设备在处理速度、连接速度和内存等方面不是完全均等,那么效果会更好。
- 加权轮询:该算法中,每个机器接受的连接数量是按权重比例分配的。这是对普通轮询算法的改进,比如你可以设定:第三台机器的处理能力是第一台机器的两倍,那么负载均衡器会把两倍的连接数量分配给第3台机器。
- 动态轮询:类似于加权轮询,但是,权重值基于对各个服务器的持续监控,并且不断更新。这是一个动态负载均衡算法,基于服务器的实时性能分析分配连接,比如每个节点的当前连接数或者节点的最快响应时间等。
- 最快算法:最快算法基于所有服务器中的最快响应时间分配连接。该算法在服务器跨不同网络的环境中特别有用。
- 最少连接:系统把新连接分配给当前连接数目最少的服务器。该算法在各个服务器运算能力基本相似的环境中非常有效。
- 观察算法:该算法同时利用最小连接算法和最快算法来实施负载均衡。服务器根据当前的连接数和响应时间得到一个分数,分数较高代表性能较好,会得到更多的连接。
- 预判算法:该算法使用观察算法来计算分数,但是预判算法会分析分数的变化趋势来判断某台服务器的性能正在改善还是降低。具有改善趋势的服务器会得到更多的连接。该算法适用于大多数环境。
性能调优社区dynatrace在其博客中分享了客户案例,电商网站在假日客流峰值期间数次崩溃,经过SQL优化和调整负载均衡算法解决了相关问题.首先要分析执行最慢的数据库语句,并做性能优化,比如增加索引等。同时也优化了连接池大小来满足高峰时刻的需求。然后,企业把负载均衡器的算法从Round-Robin改为了Least-Busy。
#pragma once
#include
using namespace std;
class roundrobin//class representing round robin scheduling
{
int *rq;//request times
int n;//number of processes
int q;//time quantum
int *w;//wait times
int *t;//turn-around times
int *a;//arrival times
list order;
public:
roundrobin(void);
~roundrobin(void);
int read();//read input from the user
void calc();//to calculate turn-around and wait times of all processes and the ordering
void display();
};
#include "roundrobin.h"
#include
#include
using namespace std;
roundrobin::roundrobin(void)
{
rq=w=t=NULL;
}
roundrobin::~roundrobin(void)
{
if(rq!=NULL)
{
delete[] rq;
delete[] w;
delete[] t;
delete[] a;
}
}
int roundrobin::read()//read input from the user
{
int i;
cout<<"Enter number of processes:";
cin>>n;
if(rq!=NULL)
{
delete[] rq;
delete[] w;
delete[] t;
}
try
{
rq=new int[n];
w=new int[n];
t=new int[n];
a=new int[n];
}
catch(bad_alloc &ba)
{
cerr< exit(1);
}
cout<<"Enter arrival times:\n";
for(i=0;i {
cin>>a[i];
}
cout<<"Enter request times:\n";
for(i=0;i {
cin>>rq[i];
w[i]=t[i]=0;
}
cout<<"Enter time quantum:";
cin>>q;
return 1;
}
void roundrobin::calc()//to calculate turn-around and wait times of all processes and the ordering
{
int j=0;
int time;
int k;
int i;
int *r;//remaining times
try
{
r=new int[n];
}
catch(bad_alloc &ba)
{
cerr< exit(1);
}
for(i=0;i bool f=false;//flag to indicate whether any process was scheduled as i changed from 0 to n-1 in the next for loop
int sp=0;//time spent
for(i=0;j {
if(r[i]>0&&sp>=a[i])//find the next uncompleted process which has already or just arrived
{
f=true;
if(r[i]<=q)//if the process requests for time less than the quantum
time=r[i];//time to be alloted in this turn is the complete requested time
else time=q;//else, it is the quantum time
//schedule the process
t[i]+=time,r[i]-=time,order.push_back(i+1);
if(r[i]==0) j++;//if the process has got completed, increment j
for(k=0;k if(r[k]!=0&&k!=i&&a[k] if(!(a[k]<=sp))//if they arrived while scheduling this process
w[k]+=sp+time-a[k],t[i]+=sp+time-a[k];//account for the time they spent waiting while the process was being scheduled
else
w[k]+=time,t[k]+=time;//add time to their wait times and turn-around times
sp+=time;
continue;
}
if(i==n-1)
{
if(!f)
//now there are no more arrived processes to be scheduled
//so change sp to the arrival time of next arriving process
{
int it;
int diff=0;//diff between present time spent and arrivaltime of next arriving process
for(it=0;it if(sp {
if(diff==0) diff=a[it]-sp;
else if(diff>a[it]-sp) diff=a[it]-sp;
}
sp+=diff;
}
f=false;
}
}
delete[] r;
}
void roundrobin::display()
{
int i;
float tav=0;//average turn-around time
float wav=0;//average wait time
for(i=0;i tav+=t[i],wav+=w[i];
tav/=n,wav/=n;
cout<<"Scheduling order:\n";
list::iterator oi;
for(oi=order.begin();oi!=order.end();oi++)
cout<<*oi<<"\t";
cout<<"\nAverage turn-around time = "<#include
using namespace std;
#include
int main()
{
roundrobin r;
r.read();
r.calc();
r.display();
cout<<"Press any key to exit...";
_getch();
}