摘要:

网上发现一篇关于修改基于Linux内核修改路由内核参数,改善负载均衡效果的文章,改作者主要用的是openwrt,执行命令:

echo -1 > /proc/sys/net/ipv4/rt_cache_rebuild_count

原文介绍如下

建立多个PPPOE链路后,进行负载均衡与带宽合并的方法一般是利用内核中提供的equal cost multipath功能,添加一条特殊的默认路由表项。此表项带有多个下一跳(nexthop)目标,并带有各自的权重。在匹配到这一表项后,内核根据权重随机挑选一条nexthop目标,将数据包路由出去。
这个看上去很完美的方案在实际使用中常常会遇到这样的问题:在访问同一目标地址时负载均衡效果不明显。

网上发现一篇关于修改基于Linux内核路由的内核参数,改善负载均衡效果的文章,作者主要用的应该是openwrt,执行命令:

echo -1 > /proc/sys/net/ipv4/rt_cache_rebuild_count

原文介绍如下

建立多个PPPOE链路后,进行负载均衡与带宽合并的方法一般是利用内核中提供的equal cost multipath功能,添加一条特殊的默认路由表项。此表项带有多个下一跳(nexthop)目标,并带有各自的权重。在匹配到这一表项后,内核根据权重随机挑选一条nexthop目标,将数据包路由出去。

这个看上去很完美的方案在实际使用中常常会遇到这样的问题:在访问同一目标地址时负载均衡效果不明显。比如用多线程从单一地址下载一个文件,会发现传输速率大致只相当于一条线路的带宽。
其原因在于路由缓存(routing cache)。使用 ip route show cache命令能查看系统中的路由缓存,看上去像是大量这样的表项:
local 192.168.1.2 from 198.173.**.** dev lo  src 192.168.1.2
    cache   iif eth0
在对数据包进行路由判定(routing decision)时,为了效率,内核会先查看路由缓存,然后才是真正的路由表。这也是我们在修改路由表项后一般会运行一下ip route flush cache的原因。也正是因为这个原因,在向同一目标地址发起多个连接时,只会用到一条线路,就是routing cache中的那条线路。

解决这一问题的方法是显然的:禁用掉路由缓存。但你会惊奇地发现,内核中居没有一个直接的选项作为路由缓存的开关。在google了N次之后,我终于发现这一个神一般的内核参数:

/proc/sys/net/ipv4/rt_cache_rebuild_count

内核官方文档像这样解释这一参数:
The per net-namespace route cache emergency rebuild threshold.
Any net-namespace having its route cache rebuilt due to
a hash bucket chain being too long more than this many times
will have its route caching disabled
大致意思是说,routing cache是以带bucket的散列表的形式来存放的。当bucket大长,散列冲突太多,超过这一限定值时,为了效率就进行一次rebuild。当这种情况发生许多次时,内核会认为routing cache没有起到应有的作用,于是禁用掉routing cache。禁用掉routing cache!看到没,这不正是我们想要的吗?
解决方法是简单地将这一参数设置成-1,这样任何长度的bucket都会触发rebuild,进而禁用掉routing cache:
echo -1 > /proc/sys/net/ipv4/rt_cache_rebuild_count
之后再从同一源地址多线程下载文件,便能看到质的变化:
  
大家会问,禁用掉routing cache会不会影响路由的转发性能呢?
事实上是这样,由于一般家用路由的路由表项极少,禁用掉routing cache对性能的影响非常小。在我个人的实际使用过程中完全感觉不到。反倒是多线程下载的速度明显提升了。

但据部分使用的朋友反映,如果路由的CPU负载太高,或者根本不够用,禁用掉缓存会影响性能,所以如果路由本身已经开了太多进程或应用的,看下平均负载再决定是否禁用,

原文链接: http://www.morfast.net/blog/linux/load-balance/