2009/03/26

Web项目开发与架构杂谈 (二)

数据库

    选择一个优秀的数据库对应用来说至关重要,简单的可以分为两类:收费和免费,当然免费也可以说不是绝对的。比较著名的数据库有:Oracle、DB2、SQL Server、MySQL、PostgreSQL等,还有很多优秀的数据库就不一一列举了。前面三个相对来说都比较庞大,不管是体系还是本身功能,购买相关许可都需要不菲的价格。由于自己比较贫困 :-)一直没有机会尝试,也就不提相关内容了。这里重点介绍下MySQL。对大部分应用来说可以认为MySQL是个免费的产品,不会为此付出相关费用。安装MySQL非常简单,支持大部分平台,推荐使用对应的平台的安装包进行安装当然也可以从源码安装,只要有个标准的C/C++编译器即可。MySQL非常小巧快速,很适合做互联网应用的后端数据库。兼容SQL标准,对于大部分用SQL能解决的应用绝对是利器。在5.0以后版本中也相继添加了其他商业数据库流行的功能:视图、存储过程和触发器等,不过这些相对来说还不如商业的成熟与稳定,喜欢尝鲜的朋友可以试试,当然这些新功能也不会太搓的拉。MySQL现在应用比较广泛的版本大致有两个:4.1和5.0。不需要太多功能的话使用4.1就足够了。另外在以后版本和Max版中MySQL也提供了一些更强劲的功能,比如:Cluster(有翻译叫簇)、表分区、其他数据库存储引擎等等。在实际应用中的的数据库划分以及业务上的切割这里就不多说,本文最后会有简单描述。开源数据库中还有个PostgreSQL也很不错,出自大名鼎鼎的伯克利大学的产品。在许可范围上更加广泛,可以应用于商业、教育等等方面。在8.x版本之前在速度和安全性上不是很理想,不过之后版本更改了许多。几乎支持大部分商业数据库的功能,有些地方还更为先进。听Yahoo中国的agentzh说过好像在内部部署的就是PostgreSQL集群哦。不过在国内Web开发公司好像应用这个的并不多,可能大部分都用来研究了把。

    最后还是推荐一把MySQL,可以应付大部分互联网的应用。当然如果对安全性以及功能性需求很强的推荐购买Oracle等商业数据库。

开发工具

    本来并不想把开发工具列入本文的讨论范围,所谓各有喜好。不过一个好的开发工具确实可以收到事半功倍的效果,加快开发速度以及简化相应的调试。这里推荐下Eclipse。相信大部分写Java的人都知道它的大名,在过去的几年中可谓名噪一时。好像是哪天还获得了开源社区的大奖。该工具出自IBM,后来捐献给了开源社区。第一优点是速度快,占用内存相对来说比较少,各自平台都有版本。它并没有采用Java的SWING或者AWT界面开发,而是自己的SWT。界面效果很不错。其次它的架构设想非常不错,基于插件机制。通过安装不同的插件可以很简单的支持其他语言的开发,比如有CDT,PDT等单独版本,还有PyDEv等第三方插件。其实对开发者来说IDE最基础的功能应该有:语法着色、代码提示这些就已足矣,毕竟只是工具而已。要是觉得经常开着IDE繁琐,而且耗费太多资源的话可以尝试下Vim,Vi的扩展版。同样也是基于插件机制,通过装不同的插件支持的功能也足够强大。尤其是修改单个文件或者简单的程序,Vim确实是居家必备啊。喜欢其他编辑器的人表拍我哦 :)

full ...

2009/03/25

Web项目开发与架构杂谈 (一)

前言

     随着互联网的流行,看看新闻,搜索资料,侃大山,还是购物,很多这样基于Web的应用越来越走进生活当中。随着应用的点击与使用量越来越庞大,带来的升级与更新也愈来愈显得重要。对于用户来说第一是内容和表面的展示,必须得有吸引人的地方,这个是根本。其次得快速的获得相应,一个页面如果等待个几十秒或者更久,估计很少又人会再次回来。其实自己对这些也没啥太多大道理可谈,简单共享下几年以来在开发上的一些经验,这里不讨论集群、负载方面以及硬件部分的话题,对此不懂 :)


Web服务器

     根据一些排名可以看出,Apache依然是此类中老大,当然不乏很多后起之秀,比如Nginx、Lighttpd等。这里列出的都是自己尝试过的,当然还有其他很优秀的(IIS之类)没啥经验就不做评论了。现在主流网站大部分还是基于Apache,其优点是稳定,可扩展性强,模块巨多等特点,主要有两个版本:1.3和2.x,1.3已经不再更新,不过依然有很多站点还是采用这个版本,这里 推荐使用2.x新版本,毕竟有了很多新功能,比如MPM机制,提升了不少性能,而且扩展也更为规范,也把其中老版本的代码单独拖出APR项目。当然也有其不足的地方,比如并发量太大,优化不足的时候明显相应变慢,传统的多进程模式消耗内存也会增加不少,而线程模式还不是很稳定高效。这时候可以尝试下轻量级的Web服务器,现在最火爆的当属Nginx和Lighttpd。国内外很多知名网站也都纷纷采用,比如YouTube、网易、新浪、MOP等。二者共同之处是高效,小巧以及快速。尤其在静态文件方面跟Apache不是一个量级的,在动态语言方面都采用FastCGI模式,效率也提升不少,在占用内存方面也都控制的不错。两者功能以及扩展模块也相对比较完善。Lighttpd可以看做是Apache的缩小版,适合从Apache转过来的人。Nginx在反向代理方面可以说是猛的很。当然不能光看两者强悍之处,在稳定性以及文档方面都不如Apache。

     说了那么多废话,大概总结下:如果对稳定性要求高的推荐使用Apache,而在图片、HTML或者CSS等静态文件方面则推荐使用Nginx和Lighttpd。可以采用相结合的方式获取最大性能。

full ...

2009/03/12

optimize rand (for mysql select)

table name: blog_post
table rows: 7389147

1. rand()
select * from blog_post order by rand() limit 1;
1 min 26.08 sec

2. max() * rand()
select * from blog_post where postid >= (select floor(rand() * ((select max(postid) from blog_post) - (select min(postid) from blog_post)) + (select min(postid) from blog_post))) order by postid limit 1;
0.01 sec


3. join
select * from blog_post as t1 join(select round(rand() * ((select max(postid) from blog_post) - (select min(postid) from blog_post)) + (select min(postid) from blog_post)) as postid) as t2 where t1.postid >= t2.postid order by t1.postid limit 1;
0.03 sec

full ...

scripts for mysql skip slave error

when slave has some errors, can try skip it, also like this:
slave stop;
set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
slave start;

if have more than 2 servers, trouble to update everyone, write small scripts and save,like:

#!/usr/bin/env perl
use strict;
use warnings;

my @hosts = qw/
192.168.1.123:root:tt1234
192.168.1.124:root:tt1234
/;

foreach (@hosts) {
    my ($ip, $usr, $pass) = split ':';
    print "// ----- $ip\n";
    slaveskip($ip, $usr, $pass);
    print "\n";
}

# mysql slave skip
sub slaveskip {
    my ($ip, $usr, $pass) = @_;
    my $info = `mysql -u$usr -p$pass -h$ip -e 'show slave status\\G;'`;
    # Slave_SQL_Running is No
    if (($info =~ /Slave_IO_Running: Yes/) && ($info =~ /Slave_SQL_Running: No/)) {
        my $errno = $1 if $info =~ /Last_Errno: (\d*)/;
        my $error = $1 if $info =~ /Last_Error: (.*)/;
        if ($errno > 0 && length($error) > 0) {
            print "slave error**\n";
            print "errno : $errno\nerror : $error\n";
            system("mysql -u$usr -p$pass -h$ip -e 'slave stop;'");
            system("mysql -u$usr -p$pass -h$ip -e 'set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;'");
            system("mysql -u$usr -p$pass -h$ip -e 'slave start;'");
        }
    } else {
        print "salve ok.\n";
    }
}

exit;

full ...