RH 6.2 关闭 gro

先了解几个术语。
tso(tcp segmentation offload)
利用网卡分割大数据包,减小 CPU 负荷的一种技术。这个需要硬件的支持。
gso(generic segmentation offload)
将 tso 的技术一般化,通过 gso 的技术实现。比 tso 更通用,不需要硬件的分片就可以实现。

lro(large receive offload)
它通过将多个 TCP 数据聚合在一个 skb 结构,在稍后的某个时刻作为一个大数据包交付给上层的网络协议栈,以减少上层协议栈处理 skb 的开销,提高系统接收 TCP 数据包的能力。
gro(generic receive offload)
lro 有不少问题,后续的驱动,都应该使用 GRO 的接口,而不是 LRO。

详细的解释可以看看这个文档,从 TSO 到 GSO,从 LRO 到 GRO。

6.2 的机器如果部署有 LVS,需要关闭 gro,否则其性能会异常的低:
# ethtool  -k em1
Offload parameters for em1:
rx-checksumming: off
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off

# ethtool -K eth0 gro off

6.2 版本之前由于有 bug,无法在 ETHTOOL_OPTS 里面加上多个参数。包括 6.2 在内的以后的版本可以直接在 /etc/sysconfig/network-scripts/ifcfg-em1 里面指定:
ETHTOOL_OPTS="-K ${DEVICE} tso on; -G ${DEVICE} rx 256 tx 128"

而对于 6.2 之前的,方法有二:
1. 将 ethtool 放到 rc.local 里面,但此时如果使用 service network restar 就无法生效了
2. 建立  /sbin/ifup-local 文件,将需要操作的脚本写到这个里面,并将其可执行

从 ubuntu 到 redhat

这里说的是我们的生产系统(server),而非个人的笔记本(desktop)。做这个决定由来已久。之前写过一篇博客,总结了自使用了 [email protected] 机器上出现的诸多问题,再加上 ubuntu 没有专业的支持(发布的时候发现目前 ubuntu 已经有专业的技术团队支持了, ubuntu advantage),有问题只能去 launchpad 上提 issue,能不能解决还是另外一回事,如果遇到一些 kernel panic,比如之前我们线上机器遇到的 208 天宕机这类及其严重的事故,这对一个线上的系统来说绝对是一个非常大的打击。之后,我们着手调研了两大商业系统,redhat 以及 suse,由于之前没有正式的使用过,再加上我司一贯的作风,人少(我一个全职带人)事多(负责从上架到下架的所有过程包括周边的 IDC 等),因此我们更多的是通过同行之间的交流获取到的一些信息。另外,好歹当年我也是满分通过的 RHCE,对 redhat 还是有一些感情的。所以,最终我们决定使用 redhat,我们挑选了某个业务的一小部分集群做线上的测试,使用了大半年的时间,除了遇到过几次 panic,其他的都比较稳定,再加上 redhat 售后技术支持的给力工作,尤其是海外的团队专业专注,几个 panic 都得到了比较好的解决;一些日常的小问题提交到其 portal 上也能得到很快的回复解决。总体说来,这是一次比较成功的转变。
当然,我们绝对不是说 ubuntu 不好,只能说是适用场景不同。对于一个刚孵化的公司,使用 ubuntu server 绝对是一个很好的选择,就像我们初期那样,0 成本(费用,这个对刚开始创业的公司是一个非常重要的因素),社区丰富,上手快,仅这几点就有足够的吸引力了。然而,当一公司进入了快速成长的阶段,发展到了一定的规模,需要的是更加的稳定的对外服务、出现问题的及时解决以及一对一的更加有效的服务,这时候选择 redhat/suse 就是一个比较好的方式,因为通过花费一定的费用,可以得到令人满意的服务,这个服务最终的是体现在出现问题后的及时有效的解决以及各种软件包的推送更新(主要是安全方面)。
再扯一句,说到系统的定制,我认为,除非你的机器数量超过 5 位数,做系统的定制甚至是内核的定制,对于业务的提升有帮助,哪怕只有 1% 的提升,从单台机器的角度看没什么大不了,但是放大到一万台,十万台,效果显而易见,最终解决的就是成本,说白了就是白花花的银子。但是如果规模只有数百台或者只有数十台,那就完全没有必要了,有这个空去做那百分之几的提升,不如花更多的时间放在核心业务的稳定高效上。

下面谈正题,在我们正式投入使用之前,有差不多一个月的测试时间,从机器的下单,到远程卡配置 RAID 建立 BIOS 升级、系统安装服务部署监控系统等,在此期间还是遇到了一些问题。这篇博客主要涉及的是 redhat 系统本身的一些问题。相对底层的会在系统部署的这一阶段通过 cobbler 的 snippet 解决,而比较上层的则通过 puppet, saltstack 解决。

Continue reading

安装 rhel 过程中遇到的 “an unhandled exception”

使用图形界面人肉测试安装台 rhel,在执行到安装 grub 的步骤中,出现了如下图所示的 "An unhandled exception has occured"

使用 scp "Save" 了 log 之后,点击 "Exit" 就转到了下面这个图片

$ cat abrt.log
executable:     /mnt/runtime/usr/bin/python
hashmarkername: anaconda
kernel:         2.6.32-220.el6.x86_64
product:        Red Hat Enterprise Linux
reason:         YumBaseError: Error: rpmdb open failed
time:           Fri 01 Feb 2013 06:19:12 PM CST
version:        6.2

anaconda-tb-Zz_jzR: Text file, 503386 bytes

description:
:The following was filed automatically by anaconda:
:anaconda 13.21.149 exception report
:Traceback (most recent call first):
:  File "/usr/lib/python2.6/site-packages/yum/config.py", line 1022, in _getsysver
:    raise Errors.YumBaseError("Error: " + str(e))
:  File "/usr/lib/python2.6/site-packages/yum/config.py", line 877, in readStartupConfig
:    startupconf.releasever = _getsysver(startupconf.installroot, startupconf.distroverpkg)
:  File "/usr/lib/python2.6/site-packages/yum/__init__.py", line 295, in _getConfig
:    startupconf = config.readStartupConfig(fn, root)
:  File "/usr/lib/anaconda/yuminstall.py", line 808, in doConfigSetup
:    YumSorter._getConfig(self)
:  File "/usr/lib/anaconda/yuminstall.py", line 362, in setup
:    self.doConfigSetup(root=self.anaconda.rootPath)
:  File "/usr/lib/anaconda/yuminstall.py", line 1284, in doBackendSetup
:    self.ayum.setup()
:  File "/usr/lib/anaconda/backend.py", line 225, in doBackendSetup
:    if anaconda.backend.doBackendSetup(anaconda) == DISPATCH_BACK:
:  File "/usr/lib/anaconda/dispatch.py", line 208, in moveStep
:    rc = stepFunc(self.anaconda)
:  File "/usr/lib/anaconda/dispatch.py", line 126, in gotoNext
:    self.moveStep()
:  File "/usr/lib/anaconda/gui.py", line 1390, in nextClicked
:    self.anaconda.dispatch.gotoNext()
:YumBaseError: Error: rpmdb open failed

END:

看上面的的 log 没看出什么端倪。后来在 RH Support 的提醒下才发现,由于这台机器之前是装过系统的,也就是说是有分区在磁盘上的,在使用自定义分区之后,需要勾选 "Format as",不然会像我一样悲剧 :-(

如果机器之前没有磁盘分区,就不会存在这个问题。这个问题估计也只有人肉的时候会发现,批量话的话,肯定会先执行

rh6.2 kernel panic 级别的 bug

线上已经稳定运行了半年多,一共遇到了两次不同的 kernel panic。以下的使用的是 6.2 的标准内核 2.6.32-220.el6.x86_64。

1. Kernel panic on divide-by-zero in get_dirty_limits
这个现象是在执行 reboot 之后,出现 panic,导致机器无法启动
这个在 vm.dirty_ratio 以及 vm_dirty_bytes 同时被置为 0 时,会出现 overflow,这个 private bug 目前还没 patch 出来(rhel 6.5 会修复这个 bug),比较好的方式是将 vm.dirty_ratio = 1。

2. kernel panic at nf_nat_setup_info
如果机器上部署了 SNAT 的话,就会中标。这个只能升级 kernel 到 2.6.32-220.30.1.el6 或者更高。在升级的过程中还遇到了一个小插曲。
由于完全进不了系统,只能通过 rescue mode 进行升级。进入之后:
# uname -a
Linux localhost.localdomain 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux

将需要更新的 kernel* 上传到该机器上:
# ll kernel-*
-rw-r–r– 1 root root 26408880 Feb 25 11:15 kernel-2.6.32-279.el6.x86_64.rpm
-rw-r–r– 1 root root  7990420 Jun 15  2012 kernel-devel-2.6.32-279.el6.x86_64.rpm
-rw-r–r– 1 root root  9099056 Feb 25 11:09 kernel-firmware-2.6.32-279.el6.noarch.rpm
-rw-r–r– 1 root root  1988972 Feb 25 11:09 kernel-headers-2.6.32-279.el6.x86_64.rpm

安装:
# rpm -ivh *rpm
会出现如下的 error:
kernel-firmware-2.6.32-220.el6.x86_64 conflicts with file from package kernel-firmware-2.6.32-279.el6.x86_64

只有先覆盖原来的 firmware,再安装剩余的三个:
# rpm -Uvh kernel-firmware-2.6.32-279.el6.noarch.rpm
# rpm -ivh kernel-2.6.32-279.el6.x86_64.rpm kernel-devel-2.6.32-279.el6.x86_64.rpm kernel-headers.2.6.32-279.el6.x86_64.rpm

完成,检查确认:
# cat /etc/grub.conf
# rpm -qa | grep kernel

关于第二个 bug 还要再说几句,本来这个 bug 也不是个多大的事,SNAT 挂了顶多是内网的机器无法访问外网,悲剧的是,为了省事我们的 web server 跟 SNAT 部署在同一台机器上,更悲剧的是,当时紧急上线,web server 连个 failover 都没有,最后的结果就是我们的这台前端机器两天挂了六次,损失了 [email protected]#$%^%。
总之教训就是,1)不要图省事。2)可以做 failover 的必须做。现在侥幸的迟早会出事。
单台硬件是不稳定的,单台软件也是不稳定的,但是两台同时宕的几率应该是小之又小了,除非发生了网络故障。

除了上面两个,还有个 2.6.32 都会发生的 208.5 day 的 bug,之前线上的 ubuntu 也遇到了这类悲剧,10.04 的可以升级到 2.6.32-38;rh 6.x 的可以升级到 kernel-2.6.32-279.el6

最后,我们的一个跑在 rh6.2 的 hadoop 集群曾经遇到过 sys time、load 高出正常水平的问题,究其原因,6.2 默认开启了 THP,关闭即可。

bonding

Ubuntu
安装 ifenslave,用来将 slave 接口 attach/detach 到 bonding 设备:
$ sudo apt-get install ifenslave

$ cat /etc/modprobe.d/bond.conf
alias bond0 bonding
options bonding mode=1 miimon=100

$ cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto eth1
iface eth1 inet manual

auto bond0
iface bond0 inet static
 address 192.168.10.53
 netmask 255.255.255.0
 gateway 192.168.10.254
 bond-slaves eth0 eth1

$ sudo /etc/init.d/networking restart
Continue reading

升级 ext3 至 ext4

CentOS 5.6(2.6.18 内核) 默认是 ext3 的文件系统,与之相比,ext4(最早出现在 2.6.19) 有很多的优点: 增大了单个分区以及单个文件的最大值,现在一个分区最大可支持 1EB(1EB=1024PB=1024^2TB) 的容量,单个文件达 16TB;有很好的兼容性,ext3 和 ext2 可以挂载为 ext4,也就是说 ext4 向下兼容 ext3/2;同时使用校验和来提供文件的可靠性,当然性能也有很大的提升。DW 上有篇很好的简述 ext4 的文章。
Continue reading