technology

2.6.29 – 2.6.39 之间的 kernel 不要在 LVS Director 的网卡开启 GRO

我之前开发了一个传图系统,直接使用了 @agentzh 的 lua_resty_upload (其实这里不应该用 nginx_lua 做的),但发现其在 LVS 下,POST 请求总是 socket timeout ,而直接 POST 到 real server 没有问题。无奈我当时只好用 DNS 轮训的方式,终于在最近找到原因了。

Linux 在 2.6.29 的时候,引入了一个 GRO (Generic receive offload) 。

MTU 一般都是 1500 字节,如果一个包超过了 MTU ,就会被分片。1500 这个数字,估计是基于当时的网络环境制定的,而现在,10Gbps 的网卡都普遍使用了,可能就不太适用了。如果 10Gbps 的网卡满载地来跑,一个完整的数据包会被分片 800w 片。我们可以通过调整 client 和 server 端的 MTU 令到分片尽可能减少,提高吞吐量。但是,如果 client 端(例如用户)不受我们控制呢,那我们就无法提高性能了。于是有人想到通过网卡的行为来间接实现相当于提高 MTU 的作用,这就是 GRO [1] 。

GRO 就是在网卡中将满足一定的条件(比较严格)的包,将分片的包组装合并了,才一次性交给上面的协议栈。现在的网卡一般都支持了,除了网卡支持,还要驱动也支持才可以。如果网卡和驱动都支持,那么在 2.6.29 以后的 kernel ,都会默认开启。

ethtool -k eth0 ,来查看是否有 generic-receive-offload: on ,如果是 off ,也不一定是不支持,可以通过 ethtool -K eth0 gro on 来尝试开启。

但是 GRO 和 LVS 协作得并不好,具体表现就是,POST 数据到 LVS 很慢。

抓包看我的 POST 请求,握手阶段用了较长时间,出现了数次 incorrect 后才真正开始传输。POST 小于 MTU 的数据,并不会触发这个问题,而 POST 大于 MTU 的数据,就会。证明了这里肯定是 GRO 惹的祸。

没有 google 到最根本的原因,但也有一些说法 [2] ,就是 GRO 和 LVS 之间的兼容没有做好,知道 2.6.39 已经修复了这个问题。

经验主义一点,就是 LVS 的 director 一律关闭网卡的 GRO 。

ethtool -K eth0 gro off

这个情况我遇到的,一般发生在内网 POST 的时候,而用户 POST 给我的情况太慢的不太多,也有可能是他们网络根本就慢,手机的网络环境变数太多,而我暂时也没有办法把他们过滤出来一一查看。我猜想,是因为内网的网络环境正好符合了 GRO 的 merge 的条件,GRO 起作用了,所以我的 POST 很慢。而用户的请求不符合条件,所以还是比较正常的。

 

 

Reference:

[1] http://lwn.net/Articles/358910/

[2] http://archive.linuxvirtualserver.org/html/lvs-users/2011-05/msg00004.html

几个关于 python package (objc , PIL )的 bug

最近在处理一个图片需求的时候,竟然遇到数个几年了都没人修正的 bug。。。这个过程值得记录一下。。。

原始需求是这样的:

首先,是用一个 ImageAlpha 的 app ,这个 app 其实做得不错的,但是因为基于 GUI ,如果我要处理 1000 张图片,那会累死人的

但是。。。这个 app 竟然还不能直接使用,需要安装 pyobjc ,至少在我的 MacOSX 上需要安装。

1)第一个 bug ,pip 安装 pyobjc

pip install pyobjc

报错:

 
Downloading/unpacking PyObjC
 
Running setup.py egg_info for package PyObjC
 
Downloading/unpacking pyobjc-core==2.3 (from PyObjC)
 
Running setup.py egg_info for package pyobjc-core
 
/usr/local/Cellar/python/2.7.2/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'use_2to3'
 
warnings.warn(msg)
 
Traceback (most recent call last):
 
File "", line 14, in
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/site-packages/trashcli/build/pyobjc-core/setup.py", line 452, in
 
**extra_args
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/distutils/core.py", line 152, in setup
 
dist.run_commands()
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/distutils/dist.py", line 953, in run_commands
 
self.run_command(cmd)
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/distutils/dist.py", line 972, in run_command
 
cmd_obj.run()
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/site-packages/trashcli/build/pyobjc-core/setup.py", line 110, in run
 
orig_egg_info.egg_info.run(self)
 
File "", line 7, in replacement_run
 
AttributeError: class egg_info has no attribute 'iter_entry_points'
 
Complete output from command python setup.py egg_info:
 
/usr/local/Cellar/python/2.7.2/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'use_2to3'
 
warnings.warn(msg)
 
running egg_info
 
Traceback (most recent call last):
 
File "", line 14, in
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/site-packages/trashcli/build/pyobjc-core/setup.py", line 452, in
 
**extra_args
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/distutils/core.py", line 152, in setup
 
dist.run_commands()
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/distutils/dist.py", line 953, in run_commands
 
self.run_command(cmd)
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/distutils/dist.py", line 972, in run_command
 
cmd_obj.run()
 
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/site-packages/trashcli/build/pyobjc-core/setup.py", line 110, in run
 
orig_egg_info.egg_info.run(self)
 
File "", line 7, in replacement_run
 
AttributeError: class egg_info has no attribute 'iter_entry_points'

参考 [1] , [2] 才能完整解决

1、pip 安装失败后,会在当前目录有 build 目录,修改 setup.py 文件,build/pyobjc-core/setup.py

use_2to3 = True   =>    use_2to3 = False

2、chmod 执行权限

chmod a+x build/pyobjc-core/libxml2-src/configure
chmod a+x build/pyobjc-core/libxml2-src/install-sh

3、export MACOSX_DEPLOYMENT_TARGET=10.5 (我也不知道为什么要声明这个系统变量)

4、python build/pyobjc-core/setup.py install ,就可以把 pyobjc-core 安装上了,然后再 pip install pyobjc ,会安装其它的一些包

 

但我不喜欢用 GUI ,我相信用几行 python 就能解决,于是我用 PIL ,并参考 [3] ,但文章中的函数并不能正常运行,原文如下:

from PIL import Image
 
im = Image.open('mouse.png')
# Get the alpha band
alpha = im.split()[3]
# Convert the image into P mode but only use 255 colors in the palette out of 256
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
# Set all pixel values below 128 to 255,
# and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
# Paste the color of index 255 and use alpha as a mask
im.paste(255, mask)
# The transparency index is 255
im.save('mouse.gif', transparency=255)

会报错:

python pil ‘NoneType’ object has no attribute ‘bands’

2)以上就是第二个 bug … 两个解决方法

1、参考 [4] ,在调用 im.split() 前,先 im.getdata() 一下,如下

from PIL import Image
 
im = Image.open('mouse.png')
# Get the alpha band
 
im.getdata()
 
alpha = im.split()[3]
# Convert the image into P mode but only use 255 colors in the palette out of 256
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
# Set all pixel values below 128 to 255,
# and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
# Paste the color of index 255 and use alpha as a mask
im.paste(255, mask)
# The transparency index is 255
im.save('mouse.gif', transparency=255)

2、fix 了这个 bug 的 patch ,在这里 [5] http://hg.effbot.org/pil-2009-raclette/changeset/fb7ce579f5f9

 

为了处理 1k 张图片。。。真折腾。。。还以为我需要把 ImageAlpha 的函数抽出来了,它是用 python 调用 objective-c 的接口来做的。

 

Reference:

[1] https://github.com/pypa/pip/issues/11#issuecomment-6485553

[2] http://www.slevenbits.com/2012/05/installing-pyobjc-in-virtualenv-on-mac-os-x-10-7

[3] http://nadiana.com/pil-tips-converting-png-gif

[4] http://bugs.python.org/issue9383

[5] http://hg.effbot.org/pil-2009-raclette/changeset/fb7ce579f5f9

 

 

 

如何在 MacOSX 下使用virt-manager 呢

直接使用呢,是不可能的了,但可以接近使用。

找一台 Linux 作为跳板机吧,一般来说呢,我都会选择办公室网关。。。如果没有,可以 vbox 虚拟一个,vbox 里的 Linux 可以不装 X 。

我的跳板机是办公室网关 ,一台 Gentoo 。

1)安装 virt-manager :

emerge virt-manager

需要安装几十个包吧,包括耗时最长的 X11 系列。

2)开启 X11 forward :

# vim /etc/ssh/sshd_config

X11Forwarding yes

3)ssh 上去跳板机开启 virt-manager 吧

ssh -X hello@nudar “virt-manager”

 

update 2012-08-25 :

跳板机记得先 ssh 一下宿主机,因为要记一下指纹。。。否则会报错 could not open display localhost 10:0 之类的无相关报错。。。

当 QQ 的离线图片遇上正向代理的 Squid

blog 荒废了好久。。。都长草了。自从去了陌陌以后,就没有写过一篇 blog 了,但期间其实做了不少东西的,可惜不是那么容易拿出来分享。

对很多东西有了很多新的认识,例如不再那么厌恶 CentOS 。终于尝试了一回 nginx_lua ,还用它写了一个传图系统,代替那个恶心的 NFS 。全面开始自动化管理,真的不需要经常 ssh 上去的。为大家带来更多我认为高效的工具。

好了,回到题目,说说情况吧。首先,办公室是一定需要翻墙的,只需要放一个兼容 PC 作为办公室的网关,就解决了,同时,还搭建一个 squid ,主要为了缓存一些 itunes 更新吧,哗哗的!!次要,可以缓存一些陌陌的图片啦(大家都有习惯刷一些周围的mm的图片),缓存一下微博的图片啊(如果大家关注的人都一样的话)

把内网往 80 的访问都重定向到 squid (在 192.168.18.1 的 3128 ):

iptables -t nat -A PREROUTING -s 192.168.18.0/24 -i eth0 -p tcp -m tcp –dport 80 -j DNAT –to-destination 192.168.18.1:3128
iptables -t nat -A POSTROUTING -j MASQUERADE

一切运行正常的,但同事总是说 QQ 发图片收不到什么的,一直没在意,今天实在想修一下了!!

由于我以前一直不用 Q ,还真不知道还真的会出现这种事情。。。

如果是发送 QQ 离线图片的话,会把图片分块上传到几台服务器(124.89.102.x , 124.115.10.x ),由于我把所有对外的 80 的包都导向到 squid 了,发送离线图片的时候,在squid 的日志中看到,不断地 POST 到那个 ip,抓包看到一堆的 “tcp segment of a reassembled PDU” ,感觉是经过 SQUID 以后,分段的 POST 无法在 QQ 那边合并起来了。

其实呢。。。说了这么多,其实我是还没找到真正的方法去解决的。。。但我又没空搭理这个小问题,还有很多线上的业务要忙呢,只好绕过了。

iptables -t nat -A PREROUTING -d 124.89.102.0/24 -i eth0 -p tcp -m tcp –dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -d 124.115.10.0/24 -i eth0 -p tcp -m tcp –dport 80 -j ACCEPT

mark 一下,当QQ离线图片遇上正向代理的 Squid,暂时我也没办法。

 

申请一个 bing translator api 玩玩

想补充下我的 DrawSthHelper 的翻译功能,google translate 的 api 收费了,于是转而投奔 bing translate ,然后发现,真 TMD 麻烦。很少用 MS 的 online 服务,好像是 bing app ID 的模式 deprecated 了,以后要用 Azure Marketplace 的了。然后就有了下面这个麻烦至极的过程。。。

api doc 在这里:http://msdn.microsoft.com/en-us/library/ff512421.aspx

其中,因为 bing app id 已经不再维护了(但还是可用的),还要注册一个 Azure Marketplace ,还要获取一个 access token 。

获取 access token 在这里:http://msdn.microsoft.com/en-us/library/hh454950.aspx

我简单罗列一下步骤,也就是翻译一下啦 @@

1,来这里免费注册个账号 https://datamarket.azure.com/developer/applications/

2,然后通过这个链接:http://go.microsoft.com/?linkid=9782667 ,来订阅(subscribe)Microsoft Translate API 的数据,每个月可以免费翻译 200w 个字符,我相信。。。一般人都够用了。

3,然后注册一个自己的应用,以下需要填的信息:

客户端ID(client_id,等会需要用),名称(随意),客户端机密(这翻译烂的。。。client secret ,等会也需要用),重定向 URL (其实是随意的,就是如果你的应用对外使用了,会显示你的名称,而你的名称的链接就是填的这个)

4,然后,POST 数据去获取 access token

POST 的参数如下:

client_id , 就是刚才那个客户端ID

client_secret ,URL encode 一下,例如,”=” 是 %3D

scope,定值,http://api.microsofttranslator.com/

grant_type,也是定值,client_credentials

然后就 POST 吧

curl -d ‘grant_type=client_credentials&client_id={your client id}&client_secret={your client secret after url encode}&scope=http://api.microsofttranslator.com’ https://datamarket.accesscontrol.windows.net/v2/OAuth2-13 | python -m json.tool

返回的是一个 json ,我用 python 去解析了一下,我们只需要其中的 access token 。

5,翻译一个词看看,这回是 GET ,GET 的参数如下:

text , 需要翻译的文本啊,字符串啊

to ,这个不用解释了吧。。。

from ,这个也不用

不过,需要注意的一点。。。就是要加一个 Authorization 的header ,值是 bearer + ” ” + 刚才的 access token

翻译开始:

curl -H “Authorization: bearer {刚才那一大串access token}”  “http://api.microsofttranslator.com/V2/Http.svc/Translate?text=hello&from=en&to=zh-CH”

bing 返回:

<string xmlns=”http://schemas.microsoft.com/2003/10/Serialization/”>你好</string>

(这个时代还用 XML 。。。)

 

附 language codes :http://msdn.microsoft.com/en-us/library/hh456380.aspx

npm 安装hashlib 失败

呃。。。这篇东西趟在我的草稿箱一段时间了。。。

当时在摆弄 hubot 。我本机 MacOSX 要装几个 lib

==================

有个script 需要hashlib 的,但我发现npm 安装不上hashlib ,报错

[1/6] cc: libhash/md4c.c -> build/Release/libhash/md4c_1.o
[2/6] cc: libhash/md5c.c -> build/Release/libhash/md5c_1.o
[3/6] cc: libhash/sha0c.c -> build/Release/libhash/sha0c_1.o
[4/6] cxx: hashlib.cc -> build/Release/hashlib_2.o
../hashlib.cc:14:16: error: ev.h: No such file or directory
../hashlib.cc:15:17: error: eio.h: No such file or directory
../hashlib.cc:311: error: ‘eio_req’ was not declared in this scope
../hashlib.cc:311: error: ‘req’ was not declared in this scope
../hashlib.cc:312: error: expected ‘,’ or ‘;’ before ‘{’ token
Waf: Leaving directory `/usr/local/lib/node_modules/npm/node_modules/hashlib/build’
Build failed:  -> task failed (err #1):
{task: cxx hashlib.cc -> hashlib_2.o}

解决办法也简单,根据 https://github.com/brainfucker/hashlib/issues/25

npm install https://github.com/ovaillancourt/hashlib/tarball/compat_fix_node_0_6_X 即可

DrawSth

这几天都在玩这个 app,苦于词汇量真的太少。。。真的看出来对方画的是什么,也不懂拼。

随便写了个小程序,原理很简单,将所有的字母全排列一次,然后 spell check 。全排列原来已经有 lib 实现了,spell check 也有 pyenchant ,真是没有技术含量啊。。。

日后考虑加入 Google Translate ,不知道会不会因为太频繁访问被 Google ban 掉。

https://github.com/hellosa/draw-something-helper

当然,一般不用这东西,要不就破坏了游戏性了。

—————

update 2012-03-20:

今天想加入 google translate 的功能。。。发现貌似收费了。。。

zhihubot 搭建

zhihubot 是一个基于GitHub 开源的Hubot [1],长期寄居于Campfire 某个room 的机器人。那说回来,Hubot 又是啥呢?Hubot 是GitHub 内部的机器人,它能做很多事情,例如自动化部署,时不时贴一下有趣的图片,为他们播放音乐,翻译,你能想到的,都可以,只需要在Campfire 里的一个有Hubot 的chat room 里,和Hubot 说一句话就可以了,剩下就交给Hubot 吧。原生支持shell 和campfire ,当然,还有更多的接口,如IRC, gtalk。它之前的内部版本是用什么写的就不知道了,现在开源的版本是用node.js 的CoffeeScript 写的,想到自己的Hubot 需要什么功能,自行动手写吧。

还是说如何搭建吧。Hubot 有两个项目:主项目 https://github.com/github/hubot 和收集回来的脚本 https://github.com/github/hubot-scripts,下载源码包吧,以后它更新了你又跟进不了,git clone 一个readonly 的吧,差不多效果。所以,fork 吧,以后说不定要加入自己的很多scripts呢。fork 出来以后,在自己本地clone 一份吧,然后就可以开始了。

我一般在自己的Mac 下用shell 测试,在线上的Linux 连接Campfire 。因为包管理工具不同而略有不同而已。

Mac 下,我用的是homebrew

brew install node.js ,安装node.js

curl http://npmjs.org/install.sh | sh ,安装npm — node package manager

进入hubot 目录,npm install ,然后所有的依赖都帮你安装完成了

进行测试前,要export 一个系统变量,export PATH=”node_modules/.bin:$PATH”

./bin/hubot ,测试,尽情玩吧

Hubot>       ,见到这个命令行提示符,我最初是完成不知道如何操作的。。。万事开头难啊,哈哈

输入 hubot pug me 测试下

Linux 下,这次我用的是Debian

# apt-get install build-essential libssl-dev git-core redis-server libexpat1-dev ,安装相关的包

debian 既然还没有node.js 。。。自己下源码装吧

# wget http://nodejs.org/dist/v0.6.9/node-v0.6.9.tar.gz
# tar xf node-v0.6.9.tar.gz -C /usr/local/src && cd /usr/local/src/node-v0.6.9
# ./configure && make && make install
安装完node.js 后,安装 CoffeeScript ,npm install -g coffee-script

同样,现在也可以用shell 测试了。

现在来尝试一下连接Campfire 。首先去新建一个账号给hubot 使用。然后去邀请hubot 加入campfire 。

在hubot 目录下新建一个文件run ,内容为:

=========================================

#!/bin/bash

##

## Wrapper for Hubot startup

##

HUBOT=”/path/to/your/hubot/”

NAME=”zhihubot”

ADAPTER=”campfire”

HUBOT_CAMPFIRE_TOKEN=”your bot’s api”

HUBOT_CAMPFIRE_ACCOUNT=”subdomain”

HUBOT_CAMPFIRE_ROOMS=”room number 1, room number 2″

OPTS=”–name ${NAME} –adapter ${ADAPTER}”

export HUBOT_CAMPFIRE_TOKEN

export HUBOT_CAMPFIRE_ACCOUNT

export HUBOT_CAMPFIRE_ROOMS
until ${HUBOT} ${OPTS}; do

echo “Hubot crashed with exit code $?. Restarting.” >&2

sleep 5

done

================================================

NAME ,hubot 的名字,每次发命令基本都要带上,robot.hear 的不用

HUBOT_CAMPFIRE_TOKEN ,你申请那个hubot 用的账号的api token,在账号的info 里有

HUBOT_CAMPFIRE_ACCOUNT ,这里的account 有点误导,其实是$subdomain.campfirenow.com 的subdomain ,而不是hubot 的账号

HUBOT_CAMPFIRE_ROOMS ,聊天室的id ,用逗号分隔

填上以上,再赋个权,chmod +x run ,在screen or tmux 下,./run 即可。

OK. Let’s rock !

如果成功了,hubot 会作为你刚才为它申请那个账号的身份,进入聊天室,你会见到它在线的

在聊天室中输入 zhihubot pug me (格式一般为$hubotname $command ,可以 zhihubot help 查看帮助)看看效果??(爱死那狗狗了!)

hubot-scripts 里还有很多有趣的scripts ,可以自行玩玩,但由于写的人很多,很不完善,未必每个scripts 都能顺利跑起来噢

由于其默认读取的是两个目录:hubot/scripts & hubot/src/scripts ,后者是built-in 脚本,那么我就把自己觉得好玩的或者自己写的脚本放hubot/scripts 里。

========================================

Campfire 本身是可以免费的,但免费版实在太弱了,只能同时容纳4 个人聊天,想让你的Hubot 活起来,果断购买吧!!一个月10+ 刀的消费对于一个公司甚至个人来说都不算什么,何况它能极大提高团队的活力、幸福感、积极性、xxxx

Hubot ,很明显来自于GitHub 的Hub ,加上robot 的bot,而zhihubot ,很明显又是利用了hubot 的hu ,直接将zhihu 串上去,很是山寨。所以呢,zhihubot 是有它自己的名字的,它叫Marvin ,它长这个样子的

Reference:

[1] http://hubot.github.com/

HAproxy 代理redis

转眼2012 的1 月要过去了。。。还是不要空着一个月吧,随便写点什么记录一下。

1 月实践了一下haproxy  作为redis 的代理,统一了所有的redis 入口,对于应用来说,其实最好还是有一个全局的队列,这个中间层完全接管了mysql 和nosql 的写入读取。大工程啊,这里还是说一下简单的。

直接上配置吧:

global
log 127.0.0.1  local3 notice
ulimit-n 40960
maxconn 10240
user haproxy
group haproxy
nbproc  4
daemon
quiet
defaults
log     global
mode    http
option tcplog
balance roundrobin
stats uri /redis-proxy
stats auth hello:123
contimeout 5000
clitimeout 30000
srvtimeout 30000
listen monitor
mode http
bind 0.0.0.0:2000
listen redis
bind 0.0.0.0:6379
mode   tcp
option tcpka
server redis1 192.168.100.1:6379 check inter 5000 fall 3
server redis2 192.168.100.2:6379 check inter 5000 fall 3 backup

我这里两个redis ,一个是active 状态对外服务,另一个是热备。

用redis-benchmark 来随便打了一下压力,和redis-cli 直连性能上差不多。

timeout 一定要配置,之前就是忘了配置,其中一个down 了以后很久都不切。

velocity 2011

总的来说,有点失望,含金量不高。

老外的好几个都是在卖广告。。。门票的大头就是他们吧。。。还有一些是说自己的产品如何好如何好,连技术原理都不说,就说你使用了我们的产品呢,能怎么样怎么样的。

简单理一下我的一些笔记吧。略去广告。

======================

第一天,含金量最高,而且都在下午。

Steve Souders 的《高性能移动互联网》。这个Steve 大有来历,简单用熟悉一点的东西去介绍,就是 Yslow 和 Firebug 的开创者。可惜。。。我迟到了。。。前面那部分没听到。后面大概就是说一些与移动互联网相关的参数,Yahoo! 的14 条铁律在移动互联网已经不再完全适用,更多的是依靠app 自身,例如cache 。

章文嵩的《低功耗服务器定制与绿色计算》。上一年SACC 上分享淘宝CDN 的时候就已经提及的话题,今年就展开来说一下。大概就是,在最外层的squid cache 层,cpu 完全不是瓶颈,磁盘IO 和网络IO 才是,在这些地方用低功耗服务器可以节省很大一笔钱呢。然后我惊奇地发现,他们在定制低功耗服务器中测试过的三款CPU ,其中两个intel E5620 和 Atom D525 都是我们正在用或者将会试用的cpu。到现在,他们已经优化到cpu 快成为瓶颈了,真可怕。除了低功耗服务器,淘宝CDN 他就简单带过了,无非就是上一年的内容。混合使用各类不同的磁盘再次提到,无非就是SAS , SATA , SSD 三种不同成本的硬盘用来存放大中小文件,及冷热数据。然后我发现。。。他每次的ppt 介绍的都是这些内容啊。。。是不是每次分享都是一两年前的东西。。。现在内部用的已经是很成熟的一套了??

Percona 的季海东(http://www.haidongji.com/ )的《Innodb/Xtradb 性能优化与诊断》。他喜欢配合着DEMO 来说ppt ,这个其实很好。。。但是当时间不足的时候。。。他连Xtradb 都完全没有提及就已经没有时间了。其中演示了一些MySQL 的操作,技巧等。。。重点的调优说得不多,尤其是,innodb 的最重要参数 buffer_pool_size ,竟然武断地说,一般设置为物理内存的80% 。。。没有考虑到NUMA 架构的机器??

米聊陈臻的《开源工具选型》。这个分享其实不错。米聊同样是一年左右的创业时间,但他们在开源软件的经验上,对比我们还是多了不少。由于他们也是创业公司,注重点还是在产品上面,所以一般都是用开源软件。他们的原则:用大公司正在用的工具,用大公司不用但自己能在代码层级搞掂的工具。他们对于一些软件的选型,其实也没有太多的道理,例如java 容器的选型,resin 和tomcat ,没什么原因,因为初始的那一批人就是用resin 的,而且也没什么毛病,就一直选用resin 了。

奇异李刚的《NoSQL 选型与实践》。也蛮不错的,虽然Sean 一直不推荐去听这个分享@@ 奇异用mongodb 相对于redis 多一点,他们甚至用mongodb 来存放图片。。。这个我实在不能理解。。。不过既然他们用了,而且用得挺欢,那也就参考一下吧。或者是有点数量级了吧,他们对细节的优化很到位,没办法,mongodb 对内存是很贪婪的,他们不优化不行。他们在使用中发现了一些bug ,还主动hack 了。

淘宝的tengine 。其实这个也是不错的。包括两部分,第一部分是朱照远说说淘宝正在如何使用nginx 和tengine 的一些特性吧。第二部分是chaoslawful 的分享,其实就是这个ppt :https://docs.google.com/present/view?id=dddqrph4_23gmctkmcg&pli=1 。tengine 的很多特性还是挺不错的,但是不知道为啥。。。就是不想用。。。唉。。。难道是洁癖作怪??我之前一直徘徊于nginx module 和 nginx_lua 之间挣扎,听完chaoslawful 的分享,不矛盾了,luajit 完胜啊!

第二天,早上第一场据说已经很少人去听了。。。我前一天晚上工作到3 点多,也没能起来。。。也就算了。。。迟到吧

整个早上。。。也是要工作的。。。结果错过了几个分享,只听到半个分享,就是 来自OmniTI 的 Theo Schlossnagle 的运维生涯。分享了一些有趣的故事吧,由于我进场的时候已经说到一半了,就不用同声传译了,直接英语听力吧,所以一些地方可能没有catch 到他的本意。facebook 的infrastructure team 与业务没有关系,专门从事架构类的一些工作,而且还是允许错误发生的,不过不能在同一个错误上犯错两次而已。也说到了所谓的 DevOps ,不过我认为,如果不懂开发的运维,就会沦为操作者,使用着一些别人开发好的工具,严格依照着操作文档去操作而已,在腾讯,叫做一线运维,地位是比较低下的。所以一个合格的运维必须一定懂编程。

百度的《大规模集群控制系统与自动运维》。意义不大,其实就是自己开发的一套运维系统嘛。与sohu 的sagent 差不多,各自都根据自己的业务自己完全开发了一套。其实原理就那些,实现细节虽然可能会麻烦,但也就那些,重点还是有没有人力去做这回事。在我当前无法做到的情况下,我只能用用开源的puppet 了。所以这个分享我听了一半就去听 Yahoo! 的《大型网站性能监控、测量和故障排除》

Yahoo! 的是一个可爱的mm 分享的,主要介绍了yslow 这个command line tool . http://developer.yahoo.com/yslow/commandline/ ,貌似是最近才开源的。反正就是根据Yahoo! 的14 条铁律写出来的一个命令行工具,还可以生成漂亮的web 报表之类的。和 http://www.showslow.com/ 配合就能很好的分析网站的瓶颈了。虽然这个工具对web1.0 网站似乎用途会大一点,但如果能加入 cookie 的话,那也可以适用我们的网站了。据说是支持的。。。空了试用下。

去哪儿分享的《机票实时搜索引擎的优化》。这个是完全偏题的分享!!。。。但内容还ok 。。。根本没有实时搜索引擎相关的什么优化。。。只是说了去哪儿在前端和后端的优化。他们的前端开始的时候使用了 trimpath 这个框架,后来实在有性能问题了,就自己写了一套,我的前端很烂,就不说了。后端的优化说了几个实例。有一个trick , 就是xml 的解析,如果只是需要一个xml 的某些标签的content ,可以不用xml 解析器去把整个xml 解析出来,而是直接用正则把需要的字段抽出来即可,效率相差数量级啊!!还有一个就是memcache 的使用经验,我也曾经犯过这个错,就是分配给memcache 的内存,并不是都可以用于存储的,例如100k data block 会分配一定数目的桶,200k 300k 亦然,当大量小object 占满了100k 的桶子时,memcache 就会根据算法置换一些旧object 出去,也就会出现,分配的512M 内存都没有用完,但就经常miss cache 的情况了。他们说了一点:优化重视细节,但切忌过早过度优化,一开始设计很大,但其实最先出现问题的往往没有考虑过的地方。我也曾经一度陷入这个怪圈,但其实真的没有必要一开始考虑得太多,有时候船到桥头自然直。我现在多数关注的是瓶颈的方面了。