‘壹’ 软件架构中,负载均衡有哪些调度算法
谢邀!
负载均衡调度算法也叫负载均衡方法有很多种,下面以使用比较广的nginx为例说说软件负载均衡的调度算法:
nginx默认的调度算法,按照时间顺序逐一分配后台服务器
在server后加weigth,weight值越高,后台服务器分配概率越大,下图是说ip为102的后台服务分配概率是ip为101后台服务的两倍
按照访问ip的hash分配,增加ip_hash关键字,同一ip访问相同的后台服务
按照访问url的hash分配,增加url_hash关键字,同一url访问相同的后台服务
按照最少连接数方式分配,增加least_conn关键字,哪个后台服务连接数少就分配哪个
按照最短响应时间分配,增加fair关键字,响应时间短的后台服务优先分配
‘贰’ 怎么实现服务器的负载均衡
负载均衡有分硬件负载和软件。
1.
硬件方面,可以用F5做负载,内置几十种算法。
2.
软件方面,可以使用反向代理服务器,例如apache,Nginx等高可用反向代理服务器。
利用DNSPOD智能解析的功能,就可以实现多台机器负载均衡.
首先你用一台高配置的机器来当数据库服务器.然后把网站的前端页面复制成多份,分别放在其他的几台机器上面.再用DNSPOD做智能解析,把域名解析指向多个服务器的IP,DNSPOD默认就有智能分流的作用,也就是说当有一台机器的资源不够用时会自动引导用户访问其他机器上.这是相对来讲比较简单的实现负载均衡的方法.
‘叁’ 平衡二叉树的各种算法实现
多值结点平衡二叉树的结构及算法研究
1引言
传统的AV1.树是一种应用较为广泛的数据结构,适合”几组织在内存中的较小索引.它的
每个结l从上存储有一个关键字、一个平衡因子和两个指针项,山”几它是一棵接近”几理想状态的
平衡二叉树,所以AV1.树具有很高的查询效率.但正如任何事物都具有两而性一样,AV1.树同
样存在比较严重的缺l从,一是存储效率比较低:真正有用的关键字在结l从上所,片的空间比例较
小,而作为辅助信息的平衡因子和指针却,片据较大的空间;二是额外运算量比较大:当有结l从
被插入或删除而导致AV1.树不平衡时,AV1.树就需要进行调整而保持它的平衡性,山”几每个
结l从上只有一个关键字,所以任何一次的数据插入或删除都有可能导致AV1.树的平衡调整,
这种频繁的调整运算将大大降低AV1.树的存取效率.为解决以上问题,结合T3树每个结l从可
以存储多个关键字项的优l侧}l,木文提出了多值结l从平衡二叉树(简称MAV1.树),它的主要特
点在”几每个MAV1.树的结l从都存储有多个关键字项,而其它信息仍与AV1.树一样,即一个平
衡因子和两个指针项.
2 MAV1.树结构描述
MAV1.树仍旧是一种平衡二叉树,它的整体树型结构和算法也是建立在传统的平衡二叉
树基础之上的.MAV1.树的特征在”几它的每个结l从都可以存储多个关键字(较理想的取值大约
在20} 50个之间).用C++语言描述的MAV1.树结l从结构如卜:
struct NodeStruct
int IJ1emsOnNode;
int bf:
struct NodPStruct*lch;ld:
//一结点中项的数目
//平衡因子
//夕.子
struct NodeStruct * rchild:
}lemType }lemsi Max}lem} ;//结点中的项数组
Node T:
在这种结构中.ElemsOnNode反映的是“当前状态卜”该结l从中关键字项的个数.当在此结
点插入一个关键字时.FlemsOnNode值加1.当删除一个关键字时.则FlemsOnNode值减1.每个
结l从上可存储的关键字个数介J几1 } M axElem之间.bf为平衡因r.其作用等同J几AV1.树的平
衡因r. MAV1.树的任一结l从的平衡因r只能取一1 ,0和1.如果一个结l从的平衡因r的绝对
值大”几1.则这棵树就失去了平衡.需要做平衡运算保持平衡.lehild和:child分别为指向左右
J"树根结0的指针.Flems[ i]为结0中第i个关键字项.Flems} MaxFlem”是一个按升序排列的
关键字数组.具体的MAV1.树结l从结构如图1所示.
}lemsOnNode一h‘一* leh;ld一
图1
reh击3
}lemsi 0}一
树结点结构
}lemsi Max}lem}
MAVT
MAV1.树的结构特l从使它比AV1.树具有更高的存储效率.在AV1.树或MAV1.树中.实际
有用的信急只有关键字.1f1! ElemsOnNode ,bf ,lehild和:child都是为了构建树型结构If1J不得不添
加的辅助信急. MAV1.树就是通过减小这些辅助信急的比例来获得较高的存储效率.山MAV1.
树结l从的定义可以看出:FlemsOnNode和bf为int型.各,片4个字节长度.指针型的lchild和
rchild也各,片4个字节长度.在以上四项信急中.AV1.树结l从除了没有ElemsOnNode外.其余和
MAV1.树相同.现假设关键字长度为24字节.M axFl二值定为50.则对AV1.树来说.它的结l从
长度为36字节.其中辅助信h,长度为12字节;If}J MAV1.树的结l从长度是1. 2K字节.其中辅助
信急长度为16字节.山此可以看出.MAV1.树在存储时.结l从中辅助信急长度,片整个结l从长度
的比例是很小的.它对存储空间的利用效率比 AV1.树要高.这一l从对”几主要而向内存应用的
MAV1.树来说是非常重要的.
在实际的应用中.当MAV1.树作为数据库索引结构时.为进一步节约内存空间.结l从中Fl-
emType的结构可根据实际需要作不同的定义.
( 1)当排序关键字较短时.可以直接将数据库中的关键字值拷贝到索引文件中.这样
MAV1.树既有较快的运行速度又不会,片用太大的空间.此时ElemType定义如卜
struct IdxRlemStruct
{
int RecPos://金己录号
KeyType Key://关键字
}R1emType;
( 2}当排序关键字较长时.如果直接将数据库中的关键字值拷贝到索引文件中会,片据较大
的空间.此时可以采用只存储关键字地址的形式.这样不管关键字有多长.映射到MAV1.树后
都只,片据一个指针的固定长度.这种以时间换空间的方法比较适合内存容量有限的情况.此时
ElemType定义如卜
struct Tdxl?lemStruct
int RecPos:
char * Key
R1emType;
//记录号
//关键字指钊
3基于MAUI.树的运算
MAUI.树的基木运算.包括MAUI.树的建立、记录的插入、删除、修改以及查询.这些算法
与基J几AVI.树的算法相似.都建立在一叉查询和平衡算法基础上.
3. 1 MAVI,树的平衡运算
如果在一棵原木是平衡的MAUI.树中插入一个新结l从.造成了不平衡.此时必须调整树的
结构.使之平衡化“21 .MAUI.树的平衡算法与AVI.树的平衡算法是相同的.但山J几MAUI.树的
每个结l从中都存储有多个关键字.所以在关键字个数相同的情况卜. MAUI.树的应用可以大大
减少平衡运算的次数.例如.假设具有n个关键字的待插入序列在插入过程中有5%(根据随
机序列特l从的不同.此数值会有所差异.这里以比较保守的5%为例)的新产生结l从会导致一
叉树出现不平衡.对AVI.树来说.山”几需要为每个关键字分配一个结l从.所以在整个插入过程
中做平衡的次数为n * 5%;对J几MAUI.树.设MAUI.树中M axFl二的值被定义为k(k为大J几1
的正整数少,则平均每k次的数据插入才会有一个新结l从产生,所以在整个插入过程中需做平
衡的次数仅为(nlk) * 5%.即在M axFl二取值为k的情况卜.对”几相同的待插入关键字序列.
在插入过程中MAUI.树用J几平衡运算的开销是AVI.树的1/ k.
3. 2数据查找
在MAUI.树上进行查找.是一个从根结l从开始.沿某一个分支逐层向卜进行比较判等的过
程.假设要在MAUI.树上查找的值为GetKey.查找过程从根结l从开始.如果根指针为NU1.1..则
查找失败;否则把要查找的值GetKey与根结l从关键字数组中的最小项Elems [ 0]进行比较.如
果GetKev小”几当前结i最小关键字.则递归查找左r树;如果GetKey'大”几Elems [ 0].则将
GetKey'与根结0关键字数组中的最大项Fletns} MaxFl二一1]进行比较.如果GetKey'大”几当前
结l从最大关键字.则递归查找右r树;否则.对当前结l从的关键字数组进行查找(山”几是有序序
列.可以采用折半查找以提高效率).如果有与GetKey'相匹配的值.则查找成功.返回成功信
息,7{报告查找到的关键字地址.
3. 3数据插入
数据插入是构建MAV1.树的基础.设要在MAV1.树*T上插入一个新的数据兀素GetKev,
其递归算法描述如卜:
(1)若*T为空树.则申清一新结} ' Elems} MaxElem}.将GetKey'插入到Flems[ 0]的位置.树
的深度增1.
(2)若*T未满.则在*T中找到插入位置后将GetKey'插入.JI在插入后保持结l从中的各
关键项有序递增.若己存在与GetKev相同的项.则不进行插入.
(3)如果*T为满结l从目一GetKey'值介”几Flems[ 0]和Flems} MaxFlem]之间.则在*T中找到
GetKev的插入位置posit ion.山”几*T木身就是满结l从.所以GetKev的插入必然会将原来*T中
的某个数据挤出去JI卜降到r树中.根据插入位置position的不同.分以卜几种情况处理:若*
T中存在与C etl} e`'相同的项.则不进行插入;若插入位置在*T结ii的前半部分(即position <
=MaxFlem/ 2).则将Flems[ 1]到Fletns} position”的数据依次左移一位.再把GetKey插入到Elems
} MaxFlem”中position的位置.Ifn原来*T中最左边项数据将被挤入到*T的左r树中.考察此
数据的特l从.它必然大”几*T左r树中的任一数据项.所以此时不需要作任何的额外运算.直
接将此数据插入到*T左r树根结i从的最右r孙位置处就可以了(见图2中插入,}} 11"后“1,>
的位置变化);若插入位置在*T结ii的后半部分(即position> MaxFlem/ 2).则将Fletns} posi-
tion}到Fletns} MaxFl二一2}的数据依次右移一位.再把GetKev插入到*T结0中position的位
置.与前一种情况类似.结l从中最右边被挤出的项将被插入到*T的右r树根结l从的最左r孙
的位置(见图2中插入“25"后" 30"的位置变化).
插入,"}i”插入”zs0
}o i is i }a
s}土 s
图2
满结点插入数据的过程
(4)若GetKey的值小”几T的最小项值.则将GetKey递归插入到T的左r树中.即在递归调
用时GetKey值不变Ifn T= T->lehild.
(5)若GetKey的值大”几T的最大项值.则将GetKey递归插入到T的右r树中.即在递归调
用时GetKey值不变Ifn T= T->rehild.
4结束语
山J几MAV1.树的结l从中存储有多个关键字值.所以它具有较高的存储效率;对MAV l树进
行查找是_分查找和顺序查找的结合.其查询效率只略低”几AV1.树.血山”几MAV1.树的平衡
运算比AV1.树要少得多.所以MAV1.树有很优秀的综合运算效率.综上所述.在数据量大、内
存容量相对较小、数据增删运算比较频繁的情况卜.用MAV1.树作为常驻内存的索引结构是一
种理想的选择.
‘肆’ 常见的负载均衡技术
四层负责均衡:主要是指通过判断报文的IP地址和端口并通过一定的负载均衡算法来决定转发到哪个指定目标,主要工作在OSI模型的第四层。四层负载均衡对数据包只是起一个数据转发的作用,并不会干预客户端与服务器之间应用层的通信(如:三次握手等)。所以能对数据所进行的操作也就很少,但相对于七层负载均衡来讲效率会高上很多
七层负载均衡:也被称为“内容交换”,指的是负载均衡设备通过报文中的应用层信息(URL、HTTP头部等信息)和负载均衡算法,选择到达目的的内部服务器。七层负载均衡可以“智能化”地筛选报文中 应用层信息,然后根据不同的信息进行特定的负载均衡调度。这种方式提升了应用系统在网络层上的灵活性,另外也在一定程度上提升了后端系统的安全性。因为像网络常见的DoS攻击,这些攻击在七层负载均衡的环境下通常都在负载均衡设备上就截止了,不会影响到后台服务器的正常运行。
前网络中常见的负载均衡主要分为硬件负载均衡和软件负载均衡。硬件负载均衡比较知名的产品有F5 Big-IP、Cirtix Netscaler等等。而软件负载均衡就有着众多的开源项目,常见的有Haproxy、nginx、lvs等。
Haproxy:
lvs:
nginx:
Haproxy可以做代理服务相对于nginx而言有很多相同之处,统一可以基于mode tcp进行四层代理也可以基于mode http进行七层代理,但不同的是其无法使用location和if等进行匹配判断。突出优势在于有会话绑定,web管理界面,状态统计非常详细。官方推荐只启用一个进程,相对于nginx多进程架构工作并不理想,更多的线程可能会受到系统内存的一些限制。
程序环境:
主程序:/usr/sbin/haproxy
主配置文件:/etc/haproxy/haproxy.cfg
Unit file:/usr/lib/systemd/system/haproxy.service
查看配置文件
重要的几个参数,及性能调优,多数无需修改
发现日志发送给本机rsyslog的local2的facility,而本机的rsyslog里并没有定义,需要我们自己去配置
所以vim /etc/rsyslog.conf添加一段将local2的所有信息记录在对应日志文件中
由于HAProxy可以工作在七层模型下,因此,要实现HAProxy的强大功能,一定要使用强大灵活的ACL规则,通过ACL规则可以实现基于HAProxy的智能负载均衡系统。HAProxy通过ACL规则完成两种主要的功能,分别是:
1)通过设置的ACL规则检查客户端请求是否合法。如果符合ACL规则要求,那么将放行;如果不符合规则,则直接中断请求。
2)符合ACL规则要求的请求将被提交到后端的backend服务器集群,进而实现基于ACL规则的负载均衡。HAProxy中的ACL规则经常使用在frontend段中,使用方法如下:
acl 自定义的acl 名称 acl 方法 -i [ 匹配的路径或文件] 其中:
·acl:是一个关键字,表示定义ACL规则的开始。后面需要跟上自定义的ACL名称。
·acl方法:这个字段用来定义实现ACL的方法,HAProxy定义了很多ACL方法,经常使用的方法有hdr_reg(host)、hdr_dom(host)、hdr_beg(host)、url_sub、url_dir、path_beg、path_end等。
·-i:表示不区分大小写,后面需要跟上匹配的路径或文件或正则表达式。与ACL规则一起使用的HAProxy参数还有use_backend,use_backend后面需要跟上一个backend实例名,表示在满足ACL规则后去请求哪个backend实例,与use_backend对应的还有default_backend参数,它表示在没有满足ACL条件的时候默认使用哪个后端
这些例子定义了www_policy、bbs_policy、url_policy三个ACL规则,第一条规则表示如果客户端以 www.z.cn 或 z.cn 开头的域名发送请求时,则此规则返回true,同理第二条规则表示如果客户端通过 bbs.z.cn 域名发送请求时,则此规则返回true,而第三条规则表示如果客户端在请求的URL中包含“buy_sid=”字符串时,则此规则返回true。
第四、第五、第六条规则定义了当www_policy、bbs_policy、url_policy三个ACL规则返回true时要调度到哪个后端backend,例如,当用户的请求满足www_policy规则时,那么HAProxy会将用户的请求直接发往名为server_www的后端backend,其他以此类推。而当用户的请求不满足任何一个ACL规则时,HAProxy就会把请求发往由default_backend选项指定的server_cache这个后端backend。
与上面的例子类似,本例中也定义了url_static、host_www和host_static三个ACL规则,其中,第一条规则通过path_end参数定义了如果客户端在请求的URL中以.gif、.png、.jpg、.css或.js结尾时返回true,第二条规则通过hdr_beg(host)参数定义了如果客户端以www开头的域名发送请求时则返回true,同理,第三条规则也是通过hdr_beg(host)参数定义了如果客户端以img.、video.、download.或ftp.开头的域名发送请求时则返回true。
第四、第五条规则定义了当满足ACL规则后要调度到哪个后端backend,例如,当用户的请求同时满足host_static规则与url_static规则,或同时满足host_www和url_static规则时,那么会将用户请求直接发往名为static的后端backend,如果用户请求满足host_www规则,那么请求将被调度到名为www的后端backend,如果不满足所有规则,那么将用户请求默认调度到名为server_cache的这个后端backend。
log:全局的日志配置,local0是日志设备,info表示日志级别。其中日志级别有err、warning、info、debug4种可选。这个配置表示使用127.0.0.1上的rsyslog服务中的local0日志设备,记录日志等级为info。
maxconn:设定每个HAProxy进程可接受的最大并发连接数,此选项等同于Linux命令行选项“ulimit -n”。
user/group:设置运行HAProxy进程的用户和组,也可使用用户和组的uid和gid值来替代。
daemon:设置HAProxy进程进入后台运行。这是推荐的运行模式。
nbproc:设置HAProxy启动时可创建的进程数,此参数要求将HAProxy运行模式设置为daemon,默认只启动一个进程。该值的设置应该小于服务器的CPU核数。创建多个进程,能够减少每个进程的任务队列,但是过多的进程可能会导致进程崩溃。
pidfile:指定HAProxy进程的pid文件。启动进程的用户必须有访问此文件的权限。
mode:设置HAProxy实例默认的运行模式,有tcp、http、health三个可选值。
retries:设置连接后端服务器的失败重试次数,如果连接失败的次数超过这里设置的值,HAProxy会将对应的后端服务器标记为不可用。此参数也可在后面部分进行设置。
timeout connect:设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,但也可以使用其他的时间单位后缀。
timeout client:设置连接客户端发送数据时最长等待时间,默认单位是毫秒,也可以使用其他的时间单位后缀。
timeout server:设置服务器端回应客户端数据发送的最长等待时间,默认单位是毫秒,也可以使用其他的时间单位后缀。
timeout check:设置对后端服务器的检测超时时间,默认单位是毫秒,也可以使用其他的时间单位后缀。
bind:此选项只能在frontend和listen部分进行定义,用于定义一个或几个监听的套接字。bind的使用格式为: bind [<address>:<port_range>] interface <interface>其可以为主机名或IP地址,如果将其设置为“*”或“0.0.0.0”,将监听当前系统的所有IPv4地址。port_range可以是一个特定的TCP端口,也可是一个端口范围,小于1024的端口需要有特定权限的用户才能使用。interface为可选选项,用来指定网络接口的名称,只能在Linux系统上使用。
option httplog:在默认情况下,HAProxy日志是不记录HTTP请求的,这样很不方便HAProxy问题的排查与监控。通过此选项可以启用日志记录HTTP请求。
option forwardfor:如果后端服务器需要获得客户端的真实IP,就需要配置此参数。由于HAProxy工作于反向代理模式,因此发往后端真实服务器的请求中的客户端IP均为HAProxy主机的IP,而非真正访问客户端的地址,这就导致真实服务器端无法记录客户端真正请求来源的IP,而X-Forwarded-For则可用于解决此问题。通过使用forwardfor选项,HAProxy就可以向每个发往后端真实服务器的请求添加X-Forwarded-For记录,这样后端真实服务器日志可以通过“X-Forwarded-For”信息来记录客户端来源IP。
option httpclose:此选项表示在客户端和服务器端完成一次连接请求后,HAProxy将主动关闭此TCP连接。这是对性能非常有帮助的一个参数。
log global:表示使用全局的日志配置,这里的global表示引用在HAProxy配置文件global部分中定义的log选项配置格式。
default_backend:指定默认的后端服务器池,也就是指定一组后端真实服务器,而这些真实服务器组将在backend段进行定义。这里的htmpool就是一个后端服务器组。
option redispatch:此参数用于cookie保持的环境中。在默认情况下,HAProxy会将其请求的后端服务器的serverID插入cookie中,以保证会话的session持久性。而如果后端的服务器出现故障,客户端的cookie是不会刷新的,这就会出现问题。此时,如果设置此参数,就会将客户的请求强制定向到另外一台健康的后端服务器上,以保证服务正常。
option abortonclose:如果设置了此参数,可以在服务器负载很高的情况下,自动结束当前队列中处理时间比较长的连接。
-balance:此关键字用来定义负载均衡算法。目前HAProxy支持多种负载均衡算法,常用的有如下几种:
cookie:表示允许向cookie插入SERVERID,每台服务器的SERVERID可在下面的server关键字中使用cookie关键字定义。
option httpchk:此选项表示启用HTTP的服务状态检测功能。HAProxy作为一个专业的负载均衡器,它支持对backend部分指定的后端服务节点的健康检查,以保证在后端backend中某个节点不能服务时,把从frotend端进来的客户端请求分配至backend中其他健康节点上,从而保证整体服务的可用性。
option httpchk的用法如下: option httpchk <method> <uri> <version> 其中,各个参数的含义如下:
check:表示启用对此后端服务器执行健康状态检查。
inter:设置健康状态检查的时间间隔,单位为毫秒。
rise:设置从故障状态转换至正常状态需要成功检查的次数,例如,“rise 2”表示2次检查正确就认为此服务器可用。
fall:设置后端服务器从正常状态转换为不可用状态需要检查的次数,例如,“fall 3”表示3次检查失败就认为此服务器不可用。
cookie:为指定的后端服务器设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的后端服务器将在后续的请求中一直被选中,其目的在于实现持久连接的功能。上面的“cookie server1”表示web1的serverid为server1。同理,“cookie server2”表示web2的serverid为server2。
weight:设置后端真实服务器的权重,默认为1,最大值为256。设置为0表示不参与负载均衡。
backup:设置后端真实服务器的备份服务器,仅仅在后端所有真实服务器均不可用的情况下才启用。
用nginx反代后端的两台tomcat主机,做动静分离,如果是jsp结尾的就发往后端,否则就交给nginx处理。
在两台tomcat主机上创建应用
nginx配置
则动静分离就实现了,并且我们还基于uri实现了会话粘性
‘伍’ 直方图均衡化对有些图片不能达到好的效果, 为什么
我来说一下
首先直方图均衡化的公式为sk对nj/n在j由0到k求和,正如楼主你所说,它所起到的作用是把原本分布不均的灰度直方图在整个灰度级别内均匀分布。
呵呵,一定要抓住这一点,即均衡化是由公式实现的,你想一想,对于一幅很暗的图片,既是它的灰度直方图全都集中在低灰度区,即比如灰度值由0-255,灰度值是2,3,5等的低灰度的频数就会很大,即它们的频率好高,因为这幅画很暗。好,现在咱们把这幅画均衡化,看那个公式的定义,根据公式得来的数据,即均衡化后的直方图中,低灰度区,比如5这一灰度级所对应的频数是不是很大,因为现在的是把原图中低灰度区,即正如上面所假设的2,3,5这些频率很大的灰度级相加而得,当然加后所得更大,即在均衡化后,仅5这一点得频数就已经很高,即频数很大,即灰度级很大,可想而知,越往后加,灰度级都很大,对应的,灰度级大了,当然直方图就集中在高灰度区,相应的图像就发白或很亮。特别亮的也是一个道理。
对于这种情况,应该用直方图规定化(匹配)来处理。
对于马赛克,很简单,你想想,先画一个8*8格,拿不同深度的铅笔,比如H,2H,B,2B之类的,你想在只拿一种深度的把四个格都涂满,是不是黑乎乎一片,然后拿两种笔涂,是不是有了区别。你用的铅笔深度种类越多,整个格所构成的图画细节越明显。同理,当你把很暗的图均衡化后,灰度级别都集中在高灰度区,就相当于笔的种类很少来画这幅画,当然也有马赛克。
给你截的图是均衡化后的,你仔细想想.
呵呵