使用 fpm 打包 ruby(ree)

在没有出现 fpm 之前,打包是件比较麻烦的事,无意发现了 fpm 这个打包神器,后来发现 fpm 的作者 jordansissel 同时也是 logstash 的作者,然后 j 大的 resume 也比较传奇,曾经在 g 家做过 sre,可以膜拜一下。

先来看下如果要人肉的在一台机器上安装 ruby(ree) 是怎么样的一个流程。
首先是安装 rvm,这需要安装各种编译工具:
yum -y install zlib-devel readline-devel libxml2-devel libxslt-devel sqlite sqlite-devel openssl-devel
curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer | bash

登出再登录。接着安装 ree-1.8.7-2012.02,在安装 ree 之前,需要先安装 libyaml:
# rvm pkg install libyaml
# rvm instal ree-1.8.7-2012.02

如果这两个的顺序弄错了,需要安装完 libyaml 之后重新安装 ruby:
# rvm reinstal ree-1.8.7-2012.02

到此结束。最后可以发现,跟上面相关的文件都在 /usr/local/rvm/ 目录下,除此之外需要增加一个 PATH 变量以及 rvm 这个 group。
要使用 fpm,需要通过 gem 安装,这个过程中会自动的解决依赖等问题:
# gem install fpm

安装完之后就可以开始打包了:
# fpm -s dir -t rpm -n rvm -v 1.20.13 –rpm-group rvm  –rpm-user root –before-install preinst  –after-install postinst  -a all -m [email protected] /usr/local/rvm/

当然需要加个 preinst 以及 postinst:

# cat postinst
chown -R root:rvm /usr/local/rvm

# cat preinst
groupadd –system –gid 502 rvm
usermod -aG rvm jaseywang

cat >> /etc/bashrc << EOF

type rvm >/dev/null 2>/dev/null || echo ${PATH} | GREP_OPTIONS="" \grep "/usr/local/rvm/bin" > /dev/null || export PATH="${PATH}:/usr/local/rvm/bin"
EOF

上面的 preinst/postinst 写的比较简略,实际使用的时候可以加些判断之类的,不过效果达到了。

LSI 芯片的监控

主流的 x86 服务器基本都是 LSI 的 RAID 芯片,或者像 DELL/HP 那样做贴牌处理,扒了皮还是 LSI。
要监控 RAID 的状态,方法很多,以市场占有率最大的 DELL 为例,可以使用其提供的 openmanager snmp 来监控 controller 以及磁盘,openmanager 应该只是做了一层封装而已,里面整合了大量的底层管理工具,不过适用性有一定的局限,只能用在 DELL 的机器上。要监控 LSI 的产品,当然是直接调用他们自己提供的工具最为方便。对于 nagios 来说,有一套完整的工具来帮助诊断 。zabbix 的也差不多,基本的东西都一样,都是通过 LSI 提供的 megaraid 来获取信息。安装、基本的使用就不说了,前面的都有纪录。

很早的一片博客提到,如果想让 zabbix 用户执行某些只有 root 才能执行的命令,可以有下面两种方式:
1. 增加 AllowRoot=1
2. visudo:  zabbix  ALL=(ALL)      NOPASSWD:NOPASSWD:ALL
现在看来,只要将方案 2 稍加修改就会变的相对完美了,像下面这样,就可以精确的控制 zabbix 用户的权限问题了:
zabbix  ALL=(ALL) NOPASSWD:/opt/MegaRAID/MegaCli/MegaCli64

根据《MegaRAID SAS Software User Guide》这个文档的说明,PD 一共分为 8 个状态,LD 一共分为 5 个状态,这个可以通过 zabbix 的 mapping 表现出来。虽然官方分了这么多的类别,不过我们真正关心的是,最好 pd 的状态是 Online,LD 的状态是 Optimal,其他的所有状态都是我们不希望看到的。因此可以简单的将其分为 ok 跟 problem 两种状态,因为一旦出现了 problem,工程师肯定会登录到机器上进行进一步的情况确认。

下面我们就以简化的方式来进行磁盘的监控,如果希望添加 mapping 的功能,可以参考这篇博客进行。

了解了 LSI 芯片之后,会发现真正需要监控的主要包括 adp、pd、ld 这三个组件的状态:
# MegaCli64 -adpallinfo -aALL
# MegaCli64 -PDList -aALL
# MegaCli64 -ldinfo -Lall -aALL

这个脚本的基础上做了些简单的修改,获取当前磁盘状态的脚本放在了这里

接下来就是定义 UserParameter:
UserParameter=lsi.raid.batterystate,/etc/zabbix/scripts/check_raid.sh batterystate
UserParameter=lsi.raid.isSOHGood,/etc/zabbix/scripts/check_raid.sh isSOHGood
UserParameter=lsi.raid.adapter,/etc/zabbix/scripts/check_raid.sh adapter
UserParameter=lsi.raid.mediaerrors,/etc/zabbix/scripts/check_raid.sh mediaerrors
UserParameter=lsi.raid.otherrrors,/etc/zabbix/scripts/check_raid.sh otherrrors
UserParameter=lsi.raid.raiderrors,/etc/zabbix/scripts/check_raid.sh raiderrors
UserParameter=lsi.raid.alarm,/etc/zabbix/scripts/check_raid.sh alarm

这里还有个简易的 megaraid 的监控程序,对于只有几台机器的公司完全适用。

LSI 芯片状态检测

目前主流的服务器的 HBA 用的基本都是 LSI 的芯片(OEM),要查看判断芯片的状态,使用其提供的 Megacli 这个工具就可以了,默认只提供 rpm 的包,在之前的博客中提到如何在 ubuntu 12.04 上安装 .deb 的包。  ubuntu 10.04 上的安装就相对简单多了,直接转换成 deb 包安装就可以,没有 3.0 kernel 那么多繁杂的转换。

对于 debian 的系统来说,还可以使用第三方的源进行安装。

为了方便,做个 alias:
alias MegaCli64='/opt/MegaRAID/MegaCli/MegaCli64'

下面纪录一些常见的,详细的参数请看最后的链接。

打印出所有 LSI 的信息:
# MegaCli64  -ShowSummary -aALL
# MegaCli64  -AdpAllInfo -aAll -NoLog

下面这个可以看到目前整个磁盘的状况:
# MegaCli64 -CfgDsply -aALL

确认整机的磁盘是否有问题:
# MegaCli64  -AdpAllInfo -aALL -NoLog|egrep '^  (Degraded|Failed)'
Degraded        : 0
Failed Disks    : 1

显示所有的 VD:
# MegaCli64 -LDInfo -Lall -Aall
# MegaCli64 -LDPDInfo -aall

显示所有的 PD:
# MegaCli64  -PDList  -aALL

要显示单个的 hhd 需要指明 Enclosure Device ID 和 Device Id:
# MegaCli64 -pdInfo -PhysDrv [32:5] aALL

上面的 Enclosure Device ID 可以通过下面的方式获取到:
# MegaCli64 -PDlist -a0 | grep "Enclosure Device"

需要注意的是,device id 跟 Slot Number 在大部分情况下是相同的,如果物理位置跟逻辑位置不对应则不同。

过滤一下,一般看到 firmware state 为 failed 就表示有问题了:
# MegaCli64  -PDList -aAll | egrep "Enclosure Device ID:|Slot Number:|Inquiry Data:|Error Count:|state"

Continue reading

RAID 控制卡

目前 raid 控制器基本是 LSI 的天下,分下面的几个方面纪录些基本的方面。

* write policy
write policy 决定 raid 控制器是在数据写入到 cache 后还是在写入到磁盘后发出结束写的请求。

对于 write through 来说,进行一次写操作的时间是写入 cache 加上写入磁盘的时间总和,这在很大程度上会影响磁盘的性能,主存的速度比 cache 慢的多。
而对于 write back 来说则不存在写的延时,数据被直接写入 cache,只有当 cache 满了或者需要时才会写入磁盘。当然二者各有利弊。

这里有个简单的伪代码解释了使用 write back 产生的问题:
IF !(using(UPS)) = TRUE
AND !(using(battery_on_RAID_controller)) = TRUE
AND power_feed_halt = TRUE
THEN file_corruption = TRUE.

因此,如果系统不能容忍数据的丢失,使用 write throuth,但这会造成 I/O 的下降,如果要使用 write back,尽量配备 UPS 或者给 RAID 加电池。


* read policy:
raid 配置上的 read policy 决定 raid 卡控制器是否会顺序的读取磁盘的 sector。
read ahead 策略表示当获取数据时,raid 控制器会顺序的读取逻辑磁盘上的 sector。如果数据本身就是顺序写的话,read ahead 可以提高系统的性能。 no read ahead 表示不会使用 read ahead 的策略。
adaptive read ahead 也就是会自适应的 read ahead,其条件是,最近的两次读是顺序读,否则则变成 no read ahead。


* cache policy
cache policy 决定所有的读是否先 buffer 到 cache 中。
cache I/O 表示所有的读先 buffer 到 cache 内存中。
direct I/O 表示读操作不 buffer 到 cache 中。
这里有个测评,主流的配置,direct 完胜 cache。

对于 write policy 来说,是 back 还是 through 要看具体的业务; read policy 选择 adaptive read ahead 无争议;cache 对于所有的 RAID 来说,选择 direct I/O。


* strip size VS stripe size
strip size 是可以配置的,而 stripe 则表示同类的 strips,这个由 strip 以及 RAID level、磁盘的数量决定,这个文档给出的例子是 strip 是 256KiB,stripe 则是 256×3=768KiB。
再比如这个文档中提到的, 4+1 块磁盘做 RAID5,4 块 spindles,1 块做  parity bits。因此 stripe width 就是 4,架设 stripe segment size(strip size) 为128KB,那么 stripe size 则是 4×128=512KB。
LSI 默认是 64KiB 大小的 strip size。看过不少测评,一般比较通用的是将 strip size 设置为 256 或者 512。不过这个对于性能的提升并不是十分的明显。

NTP 的 ACL 控制

跟 ntp 权限访问相关的都在 restrict 这个声明里面。

默认情况下,如果 ntp.conf 里面没有任何的 restrict 字段,表示默认全部放行。比如下面这个配置:
# cat /etc/ntp.conf
server x.x.x.x prefer
server y.y.y.y
server z.z.z.z

这意味着什么了?如果服务器开了公网 IP,没有防火墙的,再加上 ntp 无法监听指定的端口,这会导致互联网上任何一台主机都能够操作这台 ntp,比如:
ntpq> peers
     remote           refid      st t when poll reach   delay   offset  jitter
     ==============================================================================
     *192.168.40.92     202.112.31.197   3 u 1010 1024  377    0.202    0.000 0.398
     +192.168.50.44      202.112.31.197   3 u  364 1024  377    0.314    1.415 0.875
     +192.168.30.8      202.112.31.197   3 u  424 1024  377    0.280    1.759 0.952
     +dns2.synet.edu. 137.189.4.10     2 u  395 1024  377   11.255    0.830 0.647
      LOCAL(0)        .LOCL.          10 l  24d   64    0    0.000    0.000 0.000

还能看到 NTP, OS 的相关信息:
ntpq> rl
associd=0 status=0615 leap_none, sync_ntp, 1 event, clock_sync,
version="ntpd [email protected] Tue Jun  5 20:12:08 UTC 2012 (1)",
processor="x86_64", system="Linux/3.2.0-40-generic", leap=00, stratum=4,
precision=-23, rootdelay=12.562, rootdisp=73.370, refid=192.168.40.92,
reftime=d59b67c9.85575f94  Thu, Jul 15 2013 17:00:57.520,
clock=d59b700e.367fac37  Thu, Jul 15 2013 17:36:14.212, peer=59253,
tc=10, mintc=3, offset=0.000, frequency=5.968, sys_jitter=0.398,
clk_jitter=0.242, clk_wander=0.036

下面参照官方文档学习下 ntp 在 acl 方面做的一些工作。
默认先阻挡掉一切的连接:
restrict default ignore

下面的语句实现跟上面类似的效果:
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery

如果仅仅有上面这条,这意味着会 block 所有的主机,包括本机。这个明显不是我们想要的,可以开放指定的机器,包括 localhost。下面这个仅仅对 192.168.40.0 以及 localhost 开放查询权限:
restrict -4 default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict 192.168.40.0 mask 255.255.255.0

注意: restrict 需要使用 IP 而非域名的形式。

从上面可以看到,ntp 配置的不好会对系统的安全造成非常严重的隐患。另外,老生常谈的事,绝对不要在线上环境执行不熟悉的命令,修改不熟悉的配置,很多工程师都是修改完了重启发现没问题就仍在那儿不管了,以为自己做的很好,其实留下了很严重的安全隐患。

CloudFlare 新一代 G4 服务器

业务的快速增长推动技术的发展,转眼 CloudFlare 已经推出自己的 G4  服务器了。
我之前写过一篇《服务器定制》的博客,主要说的是 backblaze 这家做存储的公司为了满足业务的需要定制的 Storage Pod 3.0 的服务器;CloudFlare 跟他们比起来,虽然价格上没有明显的优势,但是从各个部件的选料上,可以明显的看出花了不少的功夫,做了大量的调研测试。
之前的 G3 是如下的配置:
* HP,2U
* 2xE5645
* 最多 25 块 Intel SSD
* 48G ram
* 6x1Gbps 的网卡,2 块主板,4 块 PCI
* 单电,白金

针对 G3 的不足,设计出了 G4。

1. 首先是存储方面的改进。
CloudFlare 在服务器上大量的使用 SSD,主要原因无外乎下面几个:
* 寿命长可预测健康状况
* 能耗低,跟原来相比,每个机柜可以多放一台服务器
* 速度快
在存储方面,跟 G3 最大的不同就是完全移除了 RAID 卡,这样提高了 50% 的性能。目前 G4 会根据业务需求,配备 6-24 块不等的 Intel 520 SSD 240GB。除了硬件方面的改进之外,他们也做了不少软件优化方面的工作,包括 FS。稳定性倒不是特别的高,数据没了直接去原站取就好了。
在内存方面,由原先的 48G 增加到了 128G,这样差不多能有 100G 的 in-memory 文件缓存,5x 大小的提升。

2. CPU
G3 的时候对 CPU 的需求还不是那么的旺盛,不过遇到 Layer 4 DDoS,CPU 中断就会造成瓶颈了,再加上越来越多的 CPU bound 的任务,需要对 CPU 也进行一定的测试。在测试中 CloudFlare 发现增加时钟频率并没有大的改善,不过增加 core 倒是有不错的提升,最终选择的是 2xXeon 2630L,功耗低,该型号在整个 E5 系列也是比较低档的。

3. 网络方面的工作
这个是重点了。G3 是 1G的网络,最大 6x 1G;G4 一跃为 10G 网络。为此 CloudFlare 也评估了不少厂商的 PCIe 卡,最终用的 Solarflare 的,16mpps 的性能,一般的 10G 网卡也就 9mpps 左右,并且他们的 network butter 相比一般的 512KB 也大得多,达到了 16MB。 同时,为了使用了 OpenOnload kernel bypasswd 技术,避免了产生 CPU 中断,他们跟厂商合作重写了网卡驱动,使用 FiberStore 的 SFP+ 连接到交换机。

4. 其他独特的设计

依然使用白金单电,但是设计的网络能够在发生电源问题时能够自动的切换流量。
服务器并非从 DELL 或者 HP 这样的 OEM 直接采购,而是直接从 Quanta 这家 ODM
下单,他们曾经为 Google、Facebook 设计过服务器。

总的拉说,跟 G3 比,价格有小幅度的下降,但是 CPU 性能有小幅度的提升,更快的存储,3x的内存,3x的网络容量,并且减少了 20% 的能耗。

RackSpace 目前也是自己设计服务器,不过初衷跟 CloudFlare 不大一样,跟多了是为了降低成本,他们在 Facebook 公布的 OCP 基础上进行设计,ODM 除了 Quanta 之外,还有家同样来自 TW 的公司 Wiwynn,有兴趣的可以看看这篇报道