Alipay, Hangzhou

Archive for the ‘My Work’ Category

服务器批量部署Tips

Friday, December 16th, 2011

无可否认,如果手头只有各位数的服务器,无论怎么弄人力都不成问题。
然而当规模上升到一定层次的时候,这种重复性的问题就让人变得很烦躁。

三年多前,我在淘宝的工作就是负责安装调试MySQL。一开始业务量很小,我很开心地在每台服务器上运行configure&&make&&make install。看着编译输出跑满整个屏幕,很有一种matrix的感觉。手工编辑my.cnf,手工启动MySQL。一切都那么美好。

半年过去了,随着业务量的增长,我发现曾经最享受的简单劳动变成了压榨剩余时间的怪兽。在多方咨询之后,我做了一个简单的安装脚本,只要在目标主机上运行它,不需要任何干涉就能跑完。所以我的工作变成了打开很多个窗口,并行执行这个脚本。事情又变得美好起来了。
(more…)

服务器余量统计系统设计以及实现

Wednesday, October 19th, 2011

作为一个运维工程师,不管是DBA还是SA,都希望能够对系统的余量有个大概的了解,这样就能在前台应用有重大波动前提早进行扩容,决胜千里之外。然而不同的服务器上面跑了不同的程序,导致我们不能简单通过MySQL的能力模型或者MongoDB的能力模型去估算当前服务器的余量。随着部署程序的种类(主要是数据库种类)的逐步增多,一个通用的服务器余量统计方案变得越来越有必要。

服务器有哪些指标涉及到余量?我们能想到的只有CPU、内存、网卡出入带宽、磁盘这几个大项,而磁盘这一个大项里面还有容量、IOPS、文件系统INode等小项。对于Linux上的CPU来说,被系统和用户使用掉的时间片占总时间片的比例即是CPU的使用率(有些程序对于多核的使用率比较差,虽然程序很忙,但是服务器却仍有大量CPU富余,这种情况需要再加特定的余量指标来标示程序的繁忙程度);内存可能是最为简单的,只要看看不可抢占的内存占总内存的百分比即可;对于网卡出入带宽而言,一定要关注多网卡的绑定方式和单网卡的吞吐量,如果是单工网卡的话出入流量还得相加才能进行运算;磁盘稍微有些麻烦,虽然容量、文件系统INode都很容易抓到,但是IOPS在不同访问模式下有数量级的差异。 (more…)

MongoDB性能测试——写入篇

Tuesday, March 8th, 2011

在MongoDB 1.6.4的使用过程中,我们发现当文件系统cache用尽的时候MongoDB的写入性能会有非常大的波动。更为致命的是,偶尔还会发生持续20-30秒的写入阻塞。虽然MongoDB的设计非常先进,但是稳定性一直是我们头痛的一个问题。带着疑问我们参加了Mongo北京开发者聚会,会上10gen的工程师Alvin Richards建议测试一下MongoDB 1.8,据说在写锁上有所改进。
回到杭州后,我们在Redhat 6.0上重做了MongoDB 1.6.4和1.8.0-rc0的对比测试。测试的结果如下图所示:


这两张图的横坐标是时间轴(每个点代表10秒钟),纵坐标是插入速度(代表10秒内的平均速度)。
测试逻辑如下:
1、在zyy库下建立一个名为test的collection
2、在test的k字段上建立索引
3、开启测试程序并打点。该测试程序将开启10个线程对test进行并发写入。k由uuid调用生成,长度为37字节;v长度为1k。

从测试结果上看,MongoDB 1.8.0相对于1.6.4在写入性能上有所改进。首先,1.6.4除了预分配文件造成性能下降外,写入性能偶尔还会长时间降到0。而1.8.0基本没有出现写入性能降到0的情况,性能的最低点在于预分配文件。其次,从性能的稳定性上看,1.8.0的波动显然没有1.6.4那么夸张。在InnoDB上做的测试也会出现类似波动,但是性能最低点不会降到MongoDB那么低。

总体而言,MongoDB 1.8.0-rc从功能和性能上都有所改进。期待release版本和新的存储引擎中。

具体测试代码见此:

http://pastie.org/1645946

pop set的小函数一个

Tuesday, January 18th, 2011

用过MySQL set类型的同学们可能记得FIND_IN_SET这个函数,它的作用是查找element在set内的位置。然而在MySQL的函数列表里面却找不到通过位置查找element的函数。这对我们使用set造成了比较大的麻烦。
下面是一个非常简单的函数,可以实现该功能:

CREATE FUNCTION `pop_from_set`(set_string varchar(1024), dlm varchar(16), idx int) RETURNS varchar(128)
READS SQL DATA
DETERMINISTIC
BEGIN
DECLARE s_left VARCHAR(1024);
DECLARE s_sub VARCHAR(128);
DECLARE s_len INT;
IF idx=1 THEN
RETURN SUBSTRING_INDEX(set_string, dlm, 1);
END IF;
SET s_sub = SUBSTRING_INDEX(set_string, dlm, idx-1);
SET s_len = CHAR_LENGTH(s_sub);
SET s_left = SUBSTRING(set_string, s_len+2);

RETURN SUBSTRING_INDEX(s_left, dlm, 1);
END

MySQL的Routine非常难调试,就这小小一段代码花了我一个小时。
希望能有同学能用到,呵呵。