PHP5.3.3集成了FPM,使用FASTCGI更加方便。
今天晚上研究了一下,不能免俗,顺便把本博客的服务器切换成了“甚为流行”的nginx+fastcgi.php。
fpm的具体介绍可以参见这里:http://php-fpm.org/
PHP5.3.3集成了FPM,使用FASTCGI更加方便。
今天晚上研究了一下,不能免俗,顺便把本博客的服务器切换成了“甚为流行”的nginx+fastcgi.php。
fpm的具体介绍可以参见这里:http://php-fpm.org/
好久不看书了,空闲的时间大都用来看电影了,最近的某一天终于被一个烂片打击到了。那天很凉快,于是搬出放书的箱子,找找看有啥有兴趣的书。居然翻到一本几年前买的《操作系统设计与实现》,这本书是几个minix3系统的主要作者编写的,主要就是以minix3为实例来讲解操作系统各个部分的原理和实现,比如进程管理,内存管理,IO系统等。我快速的翻了翻,居然对这本书一点印象都没有,翻完之后感觉很有意思,于是跑到minix3的网站去看了一番,收获颇丰。
虽然作者一直声明minix3只是一个教学用的系统,不要对其有太高期望,但我研究了几天后,还是感觉很惊讶,这确实是一个能用而且还挺好用的操作系统,我列举的几点证据:
1,安装文件很小,下载最新版的iso只有大概13M。
2,下载后的iso居然还是一个livecd,也就是说,放到光驱里面就能启动,不需要进行安装就能玩。
3,安装方法异常的简单直接,启动后执行setup命令,然后只要你能看懂简单的英文,就可以毫不费力的安装完毕。
4,非常好的支持vmware等虚拟机解决方案,我在vmware player里面安装,没有遇到任何问题。整个安装过程小于10分钟。
5,启动迅速,从按下驱动按钮到出现login的提示符,绝对在5秒钟以内。
6,posix兼容系统,有过linux等系统经验的人,一点都不会感觉陌生。
7,居然还有一堆编译好的软件包可供选择。
8,居然还有一套二进制包安装管理系统:packman,我感觉比FreeBSD的package系统还方便和直接。
9,完整的开发环境:不仅可以方便的安装gcc等必备工具,还自带整套系统的源代码。
10,微内核系统,很奇妙,网卡驱动程序居然是一个单独的进程,内存管理也是一个单独的进程,内核代码只有4000行!
我研究了几天后,感觉minix3绝对不是一个玩具,而是一个真正的操作系统,有很多值得研究的地方。
1,使用apc_fetch获取数据,每次大约3微秒。
2,使用Memcache::get通过localhost获取本服务器的数据,每次大概38微秒。
3,使用Memcache::get通过本机IP地址获取本服务器的数据,每次大概36微秒。
4,使用Memcache::get通过IP地址获取同网段(千兆以太网)其他机器的数据,每次大概110微秒。
5,使用PDO::query通过IP地址获取同网段(千兆以太网)其他机器的数据,每次大概110微秒。
现在的嵌入式设备,性能真是越来越好了,我家里的那个ADSL无线路由器,里面的CPU的主频竟然高达260Mhz,内存也有32M,还带USB口,可以连接移动硬盘、摄像头、打印机等。比我05年从公司拍卖得到的那台IBM PC机差不了多少,这个PC机的CPU是赛扬433,内存64M。配置这么高的嵌入式设备,软件也不能落后,那天有空telnet进去看了看,运行的是linux系统,内核版本还是2.6.x的,顿时觉得这个路由器是个宝贝,我可以在上面做些有意思的事情。
研究了一会,发现这个路由器没有关于硬件的文档,也没有找到可以刷新系统的方法,所以就打消了自己另装一套linux的想法,转念又想,装系统也太没技术含量了,哪里有时间折腾,还是在上面写点程序比较有实际意义。
这个系统裁剪的还不算太厉害,有uClibc库,有pthread库,貌似支持epoll,网络支持那肯定不用说了,本身就是路由器,还有iptables可以用,所以还算够用。CPU是ARM10的,这也算是RISC的CPU了吧,哈哈,我终于也在非X86机器上写过程序了。
于是想弄一个能运行在这个路由器上的BT下载程序,路由器连接上USB存储设备,嗯,省电!估计总功耗不过10W吧,我一直用来BT的那台IBM PC机,我估计功耗至少得50W。
于是找来BitTorrent的协议文档,研究了一下,发现协议还算简单,又翻看了很多BT客户端的实现代码,发现都写得很复杂,最讨厌看这么复杂的代码了,还是自己写吧,就当练练手了。
具体的程序实现还在规划中,预计今年能够完成吧,哈哈,这种路由器是中国网通和电信定制的产品,用户安装ADSL的时候就赠送这个,所以据传闻这个路由器的用户量至少有1000万,恩,等我把这个程序完成了,卖给他们每人一份,每份就算10块钱吧,不算太黑吧……
想起来我还有一个嵌入式设备,是一个卫星电视接收设备:DM500,里面的CPU是PowerPC的,主频大概也是250Mhz,内存32M,这个设备比较开放,已经有很多网友在上面开发各种各样的好玩的程序,只可惜这个DM500没有USB接口可以连接存储设备,所以很多想法就被限制了。
今天在我的一台桌面电脑上测试了一下跑在U盘上的数据库的性能,机器配置大概是:
CPU:超低电压版U2500,2X1.2Ghz,2M二级缓存。
内存:1G DDR2 单通道。
存储:
1,日立500G SATA硬盘。
2,金士顿2G U盘。
软件环境:
Windows XP SP3,xampplite 1.7.0 MySQL 5.1.30
测试程序:
delimiter ;;
create procedure ikv(c int unsigned)
begin
while (c > 0) do
insert into kv(v) values (floor(rand()*1000000000000));
set c=c-1;
end while;
end;;
delimiter ;
drop procedure if exists skv;
delimiter ;;
create procedure skv(c int unsigned)
begin
declare vv bigint unsigned;
declare kk int unsigned;
while (c > 0) do
set kk=floor(rand()*6000000);
select v into vv from kv where k=kk;
set c=c-1;
end while;
end;;
delimiter ;
测试结果:
《测试结果截图丢失,印象中,U盘的表现胜过普通磁盘10倍以上》
测试结论:
U盘的数据库读取的性能表现是硬盘的4倍。
U盘或者类似的存储结构,具有十分优秀的随机访问时间,对于单笔小数据量的随机读取,十分适合。
很有发展前景。
本文通过整理系统开发部一次内部交流的资料,总结了一下SPACE产品开发初期形成的一些MemcacheDB的衍生应用。业务需求是千变万化的,我们需要灵活的运用这些基础设施,简单高效的达到我们的目标。
《原有PPT截图丢失》
以下是针对 MemcacheDB-Queue的技术实现的一些文字简介:
memcachedb-queue 设计与实现
0,基于memcachedb的代码,memcachedb为单进程单线程程序,所以全局变量不须任何锁操作。
1,增加两个全局变量:head和tail,类型为unsigned long。
用于表示头节点和尾节点所对应的key值。
2,精简memcache协议,只支持add和get两个命令,add表示入队列,get表示出队列。
此时add和get的key参数和expire参数已经无实际意义,用途仅为协议兼容。
3,增加一个init_queue函数,用于初始化head和tail的值,默认从db中取得,如果没有,则都为0。
4,增加一个save_queue函数,并通过atexit注册,在程序退出时负责将head和tail的值保存到db中。
5,add的实现伪代码:
key=tail;
save_to_db(key,value);
tail++;
6,get的实现伪代码:
key=head;
get_from_db(key,&value);
del_db(key);
head++;
具体实现参见 memcachedb-queue.c
目前经过几天的测试,基本实现目标。
计划用于纸条箱的发纸条队列,还有其他的一些模型类似“生产者/消费者”的程序。
本次交流已经年代久远,其中很多观点和技术以现在的眼光来看,已经显得有些落伍,我目前正在筹划新的一版队列系统的设计与实现,队列是很有用的基础组件之一,值得深入的研究。完成之后,会在博客上与大家分享,敬请期待!
记得我在几年前看到过一个面试的题目,如何不引入额外的变量,实现两个数交换的函数,当时觉得不可思议,按照传统的做法:
swap的代码应该是:
void swap1(int *a,int *b)
{
int c;
c=*a;
*a=*b;
*b=c;
}
怎么不使用c这个变量来实现swap呢?现在看来好像是一个脑筋急转弯的问题,类似怎么只挪动一根火柴让等式成立之类的游戏。
看下面这个swap函数:
void swap2(int *a,int *b)恩,应该是没有引入外部变量。
{
*a=*a-*b;
*b=*a+*b; // a-b+b=a
*a=*b-*a; // a-(a-b)=a-a+b=b
}
更深入一步,我们来看看这两个函数编译成汇编语言的的结果(gcc -O2 -S):
swap1:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %ecx
pushl %ebx
movl (%edx), %ebx
movl (%ecx), %eax
movl %eax, (%edx)
movl %ebx, (%ecx)
popl %ebx
popl %ebp
ret
swap2:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
movl 12(%ebp), %edx
movl (%ecx), %eax
subl (%edx), %eax
movl %eax, (%ecx)
addl (%edx), %eax
movl %eax, (%edx)
subl (%ecx), %eax
movl %eax, (%ecx)
popl %ebp
ret
对比一下,swap2在汇编语言里面确实节省了一个寄存器ebx的使用。
然后看看怎么动态加载shared object(就是俗称的 嗖文件):
#include
#include
#include
#include
int main()
{
char *so="./swap.so";
void *hdl=dlopen(so,RTLD_LAZY);
if(!hdl) exit(1);
void (*f)(int *,int *);
f=dlsym(hdl,"swap");
if(!f) exit(2);
int a=2,b=3;
printf("a=%d,b=%d\n",a,b);
(*f)(&a,&b);
printf("a=%d,b=%d\n",a,b);
}
这样做的一个主要用途就是方便对程序进行扩展,比如MySQL的udf扩展,比如PHP的扩展,比如csf的扩展等等。
以上几个小技巧都是我感觉比较有意思的,也是曾经让我很迷惑的,再次分享给大家,有错误的地方,还请大家指正。
我也用上这么阳春白雪的东西了,哈哈。
Amazon做的确实不错,使用很方便,价格制定的也很灵活,按时间和流量计费,我试验了一下,还是很精确的。
《《本来有图,但是原来的博客图片丢失了,是一个AWS的WEB界面截图》》
不过有一个小问题让我听迷惑的,每个实例是不是只能运行一次?如果shutdown或者选择终止这个实例,是不是就不能再启动了?反正我是没找到启动的按钮。《现在知道了,只能一次性运行,要想保留,得花钱买持久化的,呵呵,现在看来,所谓云计算,就是卖虚拟机的?》
早就想研究一下这个新潮的东西了,无奈Lua的资料实在是很少,目前Lua最新版是5.1,Lua网站上那本书是第一版,主要是针对5.0的,好多API和5.1都不一样,我还是老老实实买了一本纸版的第二版,研究了一下,弄出来第一个比较有意义的Lua应用:
cat sum.lua
function sum(a,b)
return a-b
end
cat main.c
#include
#include
#include
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
int main(int argc,char **argv)
{
int a=100,b=200,c=0;
void *s;
lua_State *L=luaL_newstate();
luaL_openlibs(L);
luaL_loadfile(L,”sum.lua”);
lua_pcall(L,0,0,0);
lua_getglobal(L,”sum”);
lua_pushnumber(L,a);
lua_pushnumber(L,b);
if(lua_pcall(L,2,1,0) != 0) {
printf(“%s\n”,lua_tostring(L,-1));
exit(2);
}
if(!lua_isnumber(L,-1)) exit(3);
c=lua_tonumber(L,-1);
lua_pop(L,1);
printf(“a+b=%d\n”,c);
}
以上就是用C语言程序来调用Lua脚本实现的函数的做法,编译方法:
gcc -o main main.c /path/to/liblua.a -I /path/to/lua/include/ -lm -ldl
最后的-lm 和 -ldl不能少。
好书还是要买的,一本书才几十块钱,但好书让你学到知识和技能,这些知识和技能所能够创造的价值,可不是几十块钱这个数量级的。
提要
一年之计在于春。
本文对我最近两年所参与设计的系统进行概述,总结期间的经验,希望有助于日后的工作,也期望对本文的读者有所帮助。
轰轰烈烈的纸条箱
2007年的春天,我参与设计开发纸条箱系统,产品定位是新浪站内的便捷通讯系统。当时产品设计对系统容量有很大的期望,技术设计人员也对系统有很高的要求,要求能够做到分布式异地部署,导致初期花费大量时间对系统底层进行设计。期间,在负载均衡方面,通过改装LIGHTTPD,设计出七层交换系统,并冠名以F7来抗衡当时著名的并且获得过新浪年度创新奖的F6系统(现在已经出现最新一代的F8系统);在存储方面,总结以前邮箱的经验,借鉴了TINYMIC的重要思想,设计出单纯使用文件系统进行消息存储和索引的存储策略;在系统间通信方面,计划对DNS系统进行改装,来作为存储和前端的通信系统;对设备的要求也从初期的预计八台演变到最终上线时的二十五台。上线期间紧张而又兴奋,但通过不断的观察系统负载情况,渐渐的很失望,服务器利用率很低。此时产品人员热情依旧高涨,当时有想法要做移动版的纸条箱,捆绑嵌入到手机等移动终端设备,誓言要超过中国移动短信的发送数量。随着日子一天天过去,大家对纸条箱的热情逐渐降温,纸条箱的访问量也随之下降,反倒是当初纸条箱的一个附加产品:黑白名单系统日渐活跃,后逐渐演变为目前的好友系统。
SPACE上线初期,对纸条箱系统进行了改造,存储方式由纯粹的文件系统转向数据库方式,对数据进行了迁移,最终两台数据库即承担了整个纸条箱业务的服务。
总结:
产品设计人员对产品的容量有不切实际的夸大,技术设计人员对高新技术有与生俱来的喜好,二者相辅相成,使得产品开发阶段过分看重技术实现,忽视业务逻辑,最终产品上线后,因为不能达到预期目标而造成资源的浪费。
顽强生存的好友系统
好友系统的前身只是纸条箱系统的一个附加功能:让用户可以设置黑白名单,来控制垃圾纸条的接收,随着互动社区的发展,好友系统的轮廓日渐清晰,重要性也与日俱增,曾经出去对效率与负载的考虑,试图增加Cache机制,但后来发现,即使不用任何外部的Cache机制,好友系统依然效率很好,如果增加Cache机制,反倒经常因为缓存不同步造成用户投诉甚至故障。后经过总结,主要是由于好友系统由简单的数据库存储,简单的数据结构、简单的应用逻辑构成,使得系统即使承担每秒钟3000次以上的查询,依然能够保持快速的响应。
总结:
无心插柳柳成荫。
不要重新发明轮子。
未见天日的Twitter
纸条箱后期、SPACE前期我参与设计新浪Twitter系统,当初产品设计人员对系统容量没有明确的目标,反倒是技术人员有更多的想法,认为这个系统的访问量会非常高(当时用“恐怖”来形容),消息发送量可能会超过UC的IM系统,所以技术人员站在了很高的高度,投入很多的时间和精力设计了“下一代分布式统一存储系统”,设计目标要不仅能够分布式部署,还能够灵活选用多种存储介质,性能当然也不能落后,要能够很好的解决互联网应用对于分布式存储的需求。当时这个系统还有一个辅助的高性能的队列系统,已经动工并有阶段性成果,但由于整体系统设计及其复杂,以当时的人力物力,尚不能实现。后来产品方逐渐热情不再,导致这个系统都像泡沫一样在大家心中破灭。
总结:对技术的狂热,蒙蔽了我们的眼睛,使我们看不清真正的敌人。
年度大戏
SPACE这场年度大戏终于上演了,我作为系统开发人员,对系统做了部分设设计,存储部分计划采用MYSQL多主库分布式部署方案,这样的方案,技术比较成熟,开发成本很低,实施难度并不是很大,系统运维部同事也大力配合,分别在北京、广州、天津三地机房部署了大量机器,多主库部署的结构也基本搭建完成。当时为了应对想像中SPACE巨大的用户量和数据量,不惜成本采购了大量的磁盘阵列系统,并部署到各个机房,由于部署盘阵的经验不足,当时费了很大周折。之后SPACE第一版的程序陆续开发完成,但在第一次系统测试的过程中,北京到天津机房之间的专线网络出现了严重的故障,导致测试很难进行,北京到广州的网络也有很大的延迟,公司网络访问广州机房很慢,使测试人员以及领导对系统的印象很不好。后来经过深刻反思,决定弃繁从简,放弃异地分布部署,全部收缩到北京进行部署(这一决定值得SPACE至今仍然只部署在北京一地)。此后一直到系统上线,基本顺利。上线后,系统负载基本平稳。预料中可能出现问题的地方是SPACE的核心部分:FEED系统。FEED部分由于数据量巨大,一个月内积累的数据达到数亿条,频繁出现数据读取延迟的现象。为此系统运维同事作出很大的努力,当时硬件资源比较匮乏,找一台大内存的机器都很困难,如果当初有两台16G内存的机器,FEED系统读取数据延迟的现象会大为缓解。后也曾设计很多解决FEED数据量的技术方案,但大多由于实施复杂、或者运维人员见解不一直而未能施行。
总结:
Make It Simple。
复杂的问题总是有简单的解决方案,《UNIX编程艺术》这部著作中写道:
优化一个系统的最好的方式就是什么都不做——等待着新一代更快的机器出现。
有时候我们辛苦几个月实施一套复杂的优化方案,效果反而不如增加几条内存明显。
平淡的留言
接下来设计开发了平台留言系统,此时我对那些先进的系统架构没有了太多兴趣,当时领导对平台留言系统的期望亦不是很高,加之开发时间紧迫,所以平台留言系统平移了SPACE留言系统的存储方式、存储操作程序接口,只是简单的包装了一层应用逻辑。现在看来,留言系统在在系统架构上是大有文章可做的,平台留言采取页面读取数据接口的方式,很适合对数据接口进行异地分布式部署。我错过了一个千载难逢的实践分布式部署的机会。目前数据库多主库异地部署,在SINA貌似还没有先例,这应该是一个比较有意义的实践。
总结:
技术人员需要激情。
又一个订阅系统
最近的正在做邮箱信息订阅系统,因为产品人员不能拿出一个有说服力的系统容量数据而搁置。我觉得产品人员拿不出这个数据是很正常的,如果我们来做产品设计,也不一定能够拿出有理有据的数据,在很大程度上会是“拍脑门”定出来的。我认为应该以系统开发人员的经验来评估这个容量数据,迅速开发简单的系统,上线后在针对运行情况做进一步评估,来决定系统容量是否需要扩充。很有可能这个系统表现平淡,在运行一段时间后,就没有人关注了,然后黯然下线。所以我们没有必要在这个容量因素上纠缠太久,实践是检验真理的唯一标准。
总结:
产品人员畏缩了,技术人员保守了,就算是理性么?
没有结尾
系统设计还在一个接一个的进行中,其中的纠结怎能用一篇短文道出!
Powered by WordPress