在这部分开始之前我也想聊聊之前我们一直在讲,而且将来还一直会讲下去的一个话题――状态。 之前我们一直在讨论,把用户的状态保存在一个集中的地方,尤其是大规模集群Python部署的情况下。
同样,对于django来说亦是如此,可以说这条金科玉律不只是针对某种针对某个语言,某个框架,它应该是更高层次的一种理念。那么我们可以把状态放到什么地方呢,目前一些流行的选择是DB(内存表,或实体表),memcached,或者cookie。
但这几种选择并不是可以随便互换的,比如业务数据较多的情况下,放在cookie中不是很合适,因为有可能超出cookie大小的限制,那么放在memcached中,很遗憾,memcached(使用slab的情况下)中也有它自己的限制。
如果状态数据大小跨度较大,那么丢数据的情况有可能发生,ahuaxuan很久之前在测试环境下就碰到过这种情况,由于线上memcached开得较大,所以没有出现这种情况,关于这种事件发生得内部原因在ahuaxuan的另外一篇文章中已经有了非常详细的描述。
那么放在DB上呢,显然,DB的压力也是我们需要考虑的问题之一。当然除了这些主流的选择之外,我们其他选择还有很多,比如memcachedb,或者timesten,或者其他等等。但是对于状态这种东西,尤其状态数据比较重要的情况下,我们一定要深入研究并理解状态数据的存储技术,否则可能会遇到我们异想不到的情况。
比如很久之前我想破头也不会想到memcached是LRU是针对某个slab的(而且我还要插一句,LRU的时候其实并不是遍历slab中的chunk链表,而且只遍历最开始的50个数据而已,这样做纯粹是为了速度)。 目前对django来说基本上有两种Python部署策略, 第一种是利用mod_python将django运行在apache进程中,还有一种是webserver+fastcgi,这两种方式各有优缺点。
在mod_python模式中,我们的webserver必须使用apache,apache在webserver这一领域已经独占鳌头很多年了,市场占有率也是远远的超过其他的webserver,不过近几年来,又崛起了几个其他的webserver,其中比较出名的是ligttpd和nginx。
它们都以高性能和低内存消耗对apache发出了挑战,而mod_python是apache的插件,使用这种方式就把我们的webserver限定在apache上了,不过还好apache+mod_python也是非常的稳定的方案了。
第二种就是webserver+fastcgi,这里的webserver就可以随意选择了,大多数的webserver对提供了对fastcgi的支持,比如我们耳熟能详的lighttpd和nginx,而且据称在很多情况下,FastCGI能够提供比mod_python更为优越的安全性和效能。
针对小型站点,相对于Apache来说FastCGI更为轻量级。据称qq的个人空间就是c++加fastcgi实现的,哦,这样做的优势在哪里呢,c++的处理速度将会非常的快,也就是说每个fastcgi处理一个请求将会非常快速。
比如使用python需要50毫秒,c++处理这个请求有可能只需要20毫秒(这个例子未必准确,只是为了说明fastcgi的特性),虽然在开发上c++比较麻烦一点,不过在性能上,c++肯定是no1了,从这个例子上我们可以看到,使用fastcgi速度取决于处理一次请求的速度(废话,哪个不是这样)。
我们来看一下使用fastcgi的一般模式:
1、WEB服务器收到客户端的页面请求
2、WEB服务器将这个页面请求委派给一个FastCGI 外部进程(WEB服务器于FastCGI之间是通过socket来连接通讯的)
3、FastCGI外部进程得到WEB服务器委派过来的页面请求信息后进行处理,并且将处理结果(动态页面内容)返回给WEB服务器
4、Web服务器将FastCGI返回回来的结果再转送给客户端浏览器。
对我们来说第3步是我们最需要关注的,因为第3步的速度严重影响着整个性能。由于fastcgi是基于进程的,所以,我们要根据我们的应用来开启数量合适的fastcgi进程。多开了是对资源的浪费。
少开了就影响性能,这个类似我们在Python部署中开启处理请求的thread一样,只不过tomcat中的request handler thread在配置起来显然更加方便,因为我们只要关注线程池中最大的可以容纳的线程数,最大空闲线程数等就行了。
【编辑推荐】