`
andrew913
  • 浏览: 187425 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

大家来谈谈关于负载均衡的设计

阅读更多
最近要搞一个负载均衡,看了下ipvs ( lvs ) 的介绍:但是非常遗憾,ipvs只是做了IP层的负载均衡,无法做到基于URL的负载。

我找了,网上都推荐ipvs+nginx来完成基于url的负载均衡。

自己总结了一下:大概是一下的模式:

    一台做做 IPVS的机器(或者加一台备份机器)=====》多台装有nginx的机器(做反向代理)==》N台web服务器

听网上说:IPVS只做ip层的解析,效率应该不成问题。而对于nginx,需要做应用层协议的解析(找到相应的URL,hostname等),效率要低些,听说一般的机器能承受2-3W个链接。下面是就web服务器,这里暂时不讨论。

我没看过nginx的源码,但是大概了解了下,估计就是一种数据转发,这种基于应用层的数据转发,效率都会有问题,应为一个有内容的链接都要经过两次的内核空间与用户空间的切换。这样一来效率就有所下降了。

我在想,能不能把nginx的这层的数据转发也做到内核空间里面去。
例如:当一台机器接受到从IPVS 转发过来的包的时候,通过SKB直接读取到应用层的数据,在根据这些内容做相应的转发,这在netfilter里面应该可以实现吧?

对于上面的内容我想做一些效率的优化:

1.只对某种端口的链接进行处理(例如HTTP等),这样可以大大减少过滤的包。

2.做一个hash表,记录连接的5元组等信息,这条连接在hash 表里面保存一段的时间。例如一个链接来了,马上对这个链接进行hash查找,如果在hash表里面,直接转发到相应的机器,以免过多的过滤而影响效率。
对于这一条,一般的http请求在三次握手后的两个包就会包含url等信息(除了https).所以我们需要过滤的包并不是很多。


这样一样来,就可以不用nginx 了,我感觉这样的效率应该要高于实现与用户空间的nginx.

大家来看看我这样设计有没有价值,我没搞过(只做过ipvs),只是随便想想的。希望大家来一起讨论下这个实现的一些问题。或者说市面上有没有相关的开源产品。

各路神仙都过来讨论讨论啊。
分享到:
评论
26 楼 store88 2009-09-15  
浙江电信用的一般是F5的,呵呵
25 楼 wangcgen 2009-09-10  
我们项目中也有类似的情况,希望看到好的回复
24 楼 silasoni 2009-09-09  
mark
只有观看的份了
读nginx代码又看不懂
23 楼 neptune 2009-08-31  
lvs一定要两台,两台要做HA.
22 楼 argan 2009-08-26  
linux888 写道
高版本的F5支持脚本编程,你想怎么负载都行,为什么不用呢,价格不一定就比自己去研发折腾来得贵.


这个要看情况了,有时候如果你的公司发展太快了,厂商的东西跟不上的,自己做的东西虽然不够健全,但是肯定能解决自己的问题,买东西就是选择太少,很有可能我花了100w,买来的东西是很好,而且值这个100w,但是我只会用到值10w的东西,感觉很亏,我自己花个5,6w,折腾一下,解决掉自己的问题,也不错的,如果说以后,以后么,就重复这个过程

当然,这是一个权衡的过程,如果花的钱不是太多,又能解决问题,还是花钱来的好,谁愿意去折腾啊
21 楼 linux888 2009-08-26  
高版本的F5支持脚本编程,你想怎么负载都行,为什么不用呢,价格不一定就比自己去研发折腾来得贵.
20 楼 argan 2009-08-23  
andrew913 写道
搞lvs,如果出问题了,责任在于他们,如果用F5,出错了,可以推给XXX.

另外就和现在很多中国企业就是不缺钱(上市圈的)。



这个还是看人的,特别是管技术的人,有钱也不是用来乱花的,能省的地方还是要扣的
19 楼 whaosoft 2009-08-15  
负载均衡 没搞过
18 楼 andrew913 2009-08-13  
搞lvs,如果出问题了,责任在于他们,如果用F5,出错了,可以推给XXX.

另外就和现在很多中国企业就是不缺钱(上市圈的)。

17 楼 ubotutwin 2009-08-13  
<div class="quote_title">andrew913 写道</div>
<div class="quote_div">
<div class="quote_title">ubotutwin 写道</div>
<div class="quote_div">
<p>    首先支持楼主感想敢干的精神!!</p>
<p>    然后,你的思路说简单些,就是把nginx的lb直接做到kernel里,和lvs配合起来工作,可nginx除了lb还有个cache功能了,要都搞进来难度大大地,不搞的话7层lb的性能不佳,而你把他直接搞到主均衡器里面了,也就没法再搞多个nginx连在一个均衡器后面的架构了,这样系统日后的可扩展性会有点问题,因为作为老大的主均衡器如果调好些的话能力是超强的,远超拆包到7层的小弟们的承受能力,这个还要多考虑些吧。</p>
<p>    最后,lb最好还是做在4层,底下的realserv搞成对称的,不然就用soa,7层lb确实对资源消耗很多。举个例子,我用过一个red5的bigip 6400本来是做在4层,后来因为厂商的技术水平比较低也比较保守就改在7层了,结果效果有很大下降。要知道red5可是用硬逻辑实现的全部lb功能,都会造成性能的下降,用软件实现就更要命了</p>
</div>
<p>七层解析效率是要远远小于四层解析的,这是很显然的,因为到了传输层需要做那么多处理,还要读取应用层的数据,最要命的是还要把数据读到用户空间来处理。</p>
<p> </p>
<p>在这里稍稍介绍一下Linux 内核处理数据包的过程吧:一个包从网卡驱动读进来的时候,被ip_recv()函数接受后,然后就会根据具体的IP查找路由表,如果到本地的,则转给传输层进行处理,如果不是本地的,直接转发就foward。因此我们的路由器,基本是不用处理传输层以上的数据处理的,一个高端路由器是可以处理那么多链接,这个数据绝对是海量的。因为他只需要处理IP层及以下的业务逻辑。而现在大部分路由器是可以根据port,IP,MAC等信息进行过滤的,由于这些数据都是应用层以下的数据,而且在数据包中位置基本上是固定的。所以处理起来非常方便,基本上不怎么影响效率的。</p>
<p> </p>
<p>但是先也开始出现基于内容的过滤的防火墙产品(如GFW),这就需要去读取应用层的数据,而且应用层数据变化万千,业务逻辑非常复杂,严重影响效率。咱们天朝的GFW就是这种东西,所以我认为GFW绝对拖慢了整个中国的网络速度,就算他的算法再高明。我以前在一家信息安全公司做过一段时间,他们防火墙产品就可以控制所有市面上流行的网络协议。例如你用QQ,MSN等传文件,都是可以被过滤关键字的。但是这种功能是严重影响速度的。</p>
<p> </p>
<p>对于应用层协议的封堵,我们当时的设计方案是:在ip_recv()完成以后,挂一个钩子函数,碰到SYN包的时候,马上选择过滤握手成功后的两个包,一般的应用层协议特征都会在这两个包里面体现(ssl)除外。例如我们要封堵QQ,并且我们发现这个包的特征是QQ包的特征,马上DROP,并且记录5元组,在某一段时间内,这样的5元组包都将会被DROP掉。这种封堵最耗时间的是匹配包的应用层规则的过程。而在匹配到以后,通过5元组过滤,效率是非常高的。由于很多包过滤都是做在硬件里面的,所以总体效率还是非常高的。</p>
<p> </p>
<p>基于上面的描述,我们可以断定LVS与nginx的效率绝对不是一个数量级的。而我提出的想法基本上和应用层协议封堵差不多,来一个SYN包,并且是属于某个端口的包(例如80端口),马上对他链接建立后两个包进行过滤(ssl除外),找出他的URL等信息(读取skb可以获取应用层数据,skb是底层网络中最重要的一个结构),HTTP基本算是标准的协议,过滤起来还是比较简单的。选择负载均衡的点以后,然后转发,并记录5元组,其实和LVS差不多的,只是LVS没去过滤应用层协议数据而已。</p>
<p> </p>
<p>对于LVS与nginx,在负载均衡上不是竞争的关系,如果你的集群不需要做七层解析,肯定要选择lvs的,如此的成熟优秀的作品,干嘛不选择。至于那些F5硬件,我想原理都是一样的,只是一些包过滤在硬件里面做了。我仍然相信LVS是很多人最好的选择(百万连接应该没问题)</p>
<p> </p>
<p>我这边是要做类似于Google App Engine的东西,是必须要七层过滤的,不过我们项目基本上不会采用我的想法的,还要搞内核开发,成本太高。没必要,而且还不知道稳定与否(我只是实习生,打酱油的)。</p>
<p> </p>
<p>我始终觉的这不仅仅是体力活,里面还是有很多算法可以搞的。</p>
<p>最近太忙,PHP源码很烦,宏定义太多了,都没时间看l7sw,haproxy,nginx源码,悲哀。。。。。。10月份要开始找工作了,要复习基础知识。。。。太悲哀了。</p>
<p> </p>
<p>写的罗嗦了点,也算是我真实的想法,希望大家拍砖头。</p>
<p> </p>
</div>
<p>          lz说的不错,lvs确实是好东西,可是碍于国内sa们低劣的技术水平和浮躁轻狂的心态,这么好的东西却一直被冷落着~~~。曾有一白痴+白菜级别的sa和我说,“虽说我没用过,但lvs这些不收费的东西,性能和灵活性绝对比不了我们用的f5!”。我就问他,你一个bigIp要多少银两?用这些银子都他妈的能买个小型机了!花了一样多的钱,再比性能吧!还有灵活性,你硬均衡都是商业不开源的,lvs连代码都给你了,哪个灵活?关键问题还是在于会不会用吧~~,尤其是要上性能就得搞出超小型的os,f5以前用的openBSD听说搞成了15兆,而f5新出的用linux的据说竟然搞出了个不到10兆的!</p>
16 楼 seen 2009-08-13  
内核的l4/l7分析和拆包封包我都做过
user space的也都做过
从效率上来说user space的确要低很多 这不废话嘛

但内核做有很多实际的问题是逃不掉的
内存管理 spin-lock kernel-thread tcp-state管理 spl 测试
尤其是测试 几十种协议要分析调试 很多协议都是在win上跑的client 必须连接到internet 服务器也就得暴露在internet上 协议调试也得live的 你以为remote gdb那么好玩吗
有些变态的协议 逼你要pull-up 1000多byte的数据 写出来的代码没法不丑陋
还有 碰到panic 服务器又不是摆在你桌上的PC 按一下reset就能重起
一个core就tm几十几百兆
这些最终都转化为重体力活 没什么技术含量

相反 如果是user space的应用 可以搭一个单机的测试环境 测试数据可以用tcpdump抓的包 跑死了也很容易分析core live-gdb-session也很轻松
这样可以大大减少研发的压力

目前既然有haproxy能跑出这么高的效率 完全可以借鉴它的方案 没必要再跑回kernel里了

另外 linux的netfilter的效率是个已知的问题 虽然写个mod加个hook很容易 但是整套体系的效率是较低的 不如2.4时代的stack

我知道写点儿kernel的代码看起来很刁 但是做多了也就是个体力活 为什么呢 因为你我的水平是没法搞创新的 无非是别人修好了高速公路你来开车

内核里面适合做的应用也有 譬如简单的l4拆封 或者pktgen那种猛喷垃圾数据的

话说回来 lz作为学生 玩玩这些东西还是可以的 毕竟拿出去也是找工作的本钱 对自己也的确有提高
15 楼 andrew913 2009-08-12  
<div class="quote_title">ubotutwin 写道</div>
<div class="quote_div">
<p>    首先支持楼主感想敢干的精神!!</p>
<p>    然后,你的思路说简单些,就是把nginx的lb直接做到kernel里,和lvs配合起来工作,可nginx除了lb还有个cache功能了,要都搞进来难度大大地,不搞的话7层lb的性能不佳,而你把他直接搞到主均衡器里面了,也就没法再搞多个nginx连在一个均衡器后面的架构了,这样系统日后的可扩展性会有点问题,因为作为老大的主均衡器如果调好些的话能力是超强的,远超拆包到7层的小弟们的承受能力,这个还要多考虑些吧。</p>
<p>    最后,lb最好还是做在4层,底下的realserv搞成对称的,不然就用soa,7层lb确实对资源消耗很多。举个例子,我用过一个red5的bigip 6400本来是做在4层,后来因为厂商的技术水平比较低也比较保守就改在7层了,结果效果有很大下降。要知道red5可是用硬逻辑实现的全部lb功能,都会造成性能的下降,用软件实现就更要命了</p>
</div>
<p>七层解析效率是要远远小于四层解析的,这是很显然的,因为到了传输层需要做那么多处理,还要读取应用层的数据,最要命的是还要把数据读到用户空间来处理。</p>
<p> </p>
<p>在这里稍稍介绍一下Linux 内核处理数据包的过程吧:一个包从网卡驱动读进来的时候,被ip_recv()函数接受后,然后就会根据具体的IP查找路由表,如果到本地的,则转给传输层进行处理,如果不是本地的,直接转发就foward。因此我们的路由器,基本是不用处理传输层以上的数据处理的,一个高端路由器是可以处理那么多链接,这个数据绝对是海量的。因为他只需要处理IP层及以下的业务逻辑。而现在大部分路由器是可以根据port,IP,MAC等信息进行过滤的,由于这些数据都是应用层以下的数据,而且在数据包中位置基本上是固定的。所以处理起来非常方便,基本上不怎么影响效率的。</p>
<p> </p>
<p>但是先也开始出现基于内容的过滤的防火墙产品(如GFW),这就需要去读取应用层的数据,而且应用层数据变化万千,业务逻辑非常复杂,严重影响效率。咱们天朝的GFW就是这种东西,所以我认为GFW绝对拖慢了整个中国的网络速度,就算他的算法再高明。我以前在一家信息安全公司做过一段时间,他们防火墙产品就可以控制所有市面上流行的网络协议。例如你用QQ,MSN等传文件,都是可以被过滤关键字的。但是这种功能是严重影响速度的。</p>
<p> </p>
<p>对于应用层协议的封堵,我们当时的设计方案是:在ip_recv()完成以后,挂一个钩子函数,碰到SYN包的时候,马上选择过滤握手成功后的两个包,一般的应用层协议特征都会在这两个包里面体现(ssl)除外。例如我们要封堵QQ,并且我们发现这个包的特征是QQ包的特征,马上DROP,并且记录5元组,在某一段时间内,这样的5元组包都将会被DROP掉。这种封堵最耗时间的是匹配包的应用层规则的过程。而在匹配到以后,通过5元组过滤,效率是非常高的。由于很多包过滤都是做在硬件里面的,所以总体效率还是非常高的。</p>
<p> </p>
<p>基于上面的描述,我们可以断定LVS与nginx的效率绝对不是一个数量级的。而我提出的想法基本上和应用层协议封堵差不多,来一个SYN包,并且是属于某个端口的包(例如80端口),马上对他链接建立后两个包进行过滤(ssl除外),找出他的URL等信息(读取skb可以获取应用层数据,skb是底层网络中最重要的一个结构),HTTP基本算是标准的协议,过滤起来还是比较简单的。选择负载均衡的点以后,然后转发,并记录5元组,其实和LVS差不多的,只是LVS没去过滤应用层协议数据而已。</p>
<p> </p>
<p>对于LVS与nginx,在负载均衡上不是竞争的关系,如果你的集群不需要做七层解析,肯定要选择lvs的,如此的成熟优秀的作品,干嘛不选择。至于那些F5硬件,我想原理都是一样的,只是一些包过滤在硬件里面做了。我仍然相信LVS是很多人最好的选择(百万连接应该没问题)</p>
<p> </p>
<p>我这边是要做类似于Google App Engine的东西,是必须要七层过滤的,不过我们项目基本上不会采用我的想法的,还要搞内核开发,成本太高。没必要,而且还不知道稳定与否(我只是实习生,打酱油的)。</p>
<p> </p>
<p>我始终觉的这不仅仅是体力活,里面还是有很多算法可以搞的。</p>
<p>最近太忙,PHP源码很烦,宏定义太多了,都没时间看l7sw,haproxy,nginx源码,悲哀。。。。。。10月份要开始找工作了,要复习基础知识。。。。太悲哀了。</p>
<p> </p>
<p>写的罗嗦了点,也算是我真实的想法,希望大家拍砖头。</p>
<p> </p>
14 楼 chenlb 2009-08-12  
HAProxy 应该不错吧,它 ip 层,和 http 层,有健康检测
13 楼 cx6445 2009-08-12  
一般应用能不用7层lb就不用,大型网站也90%以上的应用都跑4层不跑7层。
12 楼 ubotutwin 2009-08-11  
<p>    首先支持楼主感想敢干的精神!!</p>
<p>    然后,你的思路说简单些,就是把nginx的lb直接做到kernel里,和lvs配合起来工作,可nginx除了lb还有个cache功能了,要都搞进来难度大大地,不搞的话7层lb的性能不佳,而你把他直接搞到主均衡器里面了,也就没法再搞多个nginx连在一个均衡器后面的架构了,这样系统日后的可扩展性会有点问题,因为作为老大的主均衡器如果调好些的话能力是超强的,远超拆包到7层的小弟们的承受能力,这个还要多考虑些吧。</p>
<p>    最后,lb最好还是做在4层,底下的realserv搞成对称的,不然就用soa,7层lb确实对资源消耗很多。举个例子,我用过一个red5的bigip 6400本来是做在4层,后来因为厂商的技术水平比较低也比较保守就改在7层了,结果效果有很大下降。要知道red5可是用硬逻辑实现的全部lb功能,都会造成性能的下降,用软件实现就更要命了</p>
11 楼 andrew913 2009-08-10  
刚才去看了下haproxy,貌似很牛啊,以下摘自 http://cn.haproxy.org/

内核tcp splicing : 避免了内核到用户然后用户到内核端的数据拷贝, 提高了吞吐量同时又降低了CPU使用率. Haproxy 1.3支持Linux L7SW 以满足在商用硬件上数Gbps的吞吐的需求。
==============

不错,刚快去看看。
10 楼 andrew913 2009-08-10  
非常感谢,我去看看,我现在 在看l7sw ,思路上看起来还不错。 
9 楼 CharlesCui 2009-08-10  
基于URL有好多实现,比如Haproxy就可以,我搞了个基于Http Method的负载均衡配置,你看看是不是你要的:

http://charlescui.iteye.com/admin/blogs/442550
8 楼 andrew913 2009-08-10  
我想效率的突破点是:在用户空间做转发的话,你任意一个请求来了,都需要把这些内容从内核搬出来,然后处理完了以后再搬到内核空间,再发出去。但是如果在内核做转发的话,根本不需要,其实过滤的包也不是很多,只需要过滤下三次握手后面的两个包就可以了(读下url就行了),感觉和LVS有点类似。

如果我的公司现在要用负载均衡,我直接选一种成熟的技术就OK了,没必要折腾那么都哦,搞内核代码是要掉头发的,时刻都要看到panic信息。

不过我是准备搞点毕业设计的材料(有个比赛需要负载均衡的东西,新一点东西总能引起注意),所以就想了下一些可能可行的想法。

内核搞过一段时间,基本都是netfilter的东西吧,还做过一个和网卡驱动相关的程序。
7 楼 Magicloud 2009-08-10  
andrew913 写道
另一方面一定要考虑,如果这个模块死了,怎么办?按你的思路,负载均衡只有这一台机器,死了服务就挂了……

=========
做 ipvs 这里是要有一台做备份的。
而后面做七层解析解析的机器,挂了是没事的,做ip转发的机器是有监控功能。

如果内核代码健壮的话,挂的几率应该是小于用户空间的daemon进程的。

ps: 不能因为怕 kernel panic而否决内核实现的。

也就是你需要两层机器来做,一个ip转发,一个应用转发……如此的话,我相信把应用转发做到内核不会有很高提升。

不要“应该”,理论上足够健壮的代码无论在哪都无所谓。不会因为运行在用户空间就更容易挂。
内核模块挂了可能要重启系统,而用户daemon挂了,重启daemon远远快得多。
而整个应用转发功能放到内核,你能保证每一行代码都没错么?
另外必然是要做并发的,内核模块并发代价远大于用户层并发。

不是因为怕崩溃而否定内核实现,但你要明白现在很多内核应用都被移出到用户空间,(甚至可以说是一个趋势,无论Linux、Windows),是有原因的。

这个问题,其实技术实现是次要的,均衡全局得失才是项目的重点。而均衡得失需要有全面的事实支持。因此问一句,你有内核开发经验么?

对你的需求,我认为用一个模块直接把网卡接收数据传递到用户空间,在用户空间做分析处理,已经是项目最好的实现了。

相关推荐

Global site tag (gtag.js) - Google Analytics