Jun
16
用date +%s可以得到UNIX的时间戳,
[/home/javalee/myshell] # date +%s
1060510783
而用
date -d '1970-01-01 UTC '$1' seconds' +"%Y-%m-%d %T"
[/home/javalee/myshell] #utc 1047335700
2003-03-11 06:35:00
可以把UNIX时间戳转换成当前系统时间!
awk日期和时间戳转换
2011-03-23 15:36
strftime 将时间戳转日期
awk 'BEGIN{print strftime("%Y-%m-%d",systime())}'
将日期转为时间戳
awk 'BEGIN {printf("%d\n",mktime(2006" "8" "5" "15" "09" "0))}'
[/home/javalee/myshell] # date +%s
1060510783
而用
date -d '1970-01-01 UTC '$1' seconds' +"%Y-%m-%d %T"
[/home/javalee/myshell] #utc 1047335700
2003-03-11 06:35:00
可以把UNIX时间戳转换成当前系统时间!
awk日期和时间戳转换
2011-03-23 15:36
strftime 将时间戳转日期
awk 'BEGIN{print strftime("%Y-%m-%d",systime())}'
将日期转为时间戳
awk 'BEGIN {printf("%d\n",mktime(2006" "8" "5" "15" "09" "0))}'
Jun
16
crontab是linux自带的计划任务程序,可以实现分,时,日,周,月。
但是crontab有两个缺陷:
1.最小粒度为分,对于秒不支持
2.若是上一个任务的执行时间超过下一个任务的开始时间的话,就会出现两个任务并行的现象,这样任务会越积越多,最后系统挂了。
这周在项目里需要实现每隔10秒去执行任务的功能,因此写了个shell程序:
1.可以自定义程序执行时间间隔,
2.使用的是deamon方式,产生两个进程,父进程监控子进程,若是子进程挂了,父进程重新启动子进程,子进程负责每隔10秒钟执行任务;
3.而且当任务执行时间超长时,不会出现两个任务同时执行的现象,下一个任务只会延后。也可以用后台运行方式运行任务,这样和crontab的效果一样
4.若是时间间隔为10秒,而任务只执行了1秒,则sleep 9秒后,执行下一次任务
5.若是把sleep改为usleep的话可以精确到微秒
但是crontab有两个缺陷:
1.最小粒度为分,对于秒不支持
2.若是上一个任务的执行时间超过下一个任务的开始时间的话,就会出现两个任务并行的现象,这样任务会越积越多,最后系统挂了。
这周在项目里需要实现每隔10秒去执行任务的功能,因此写了个shell程序:
1.可以自定义程序执行时间间隔,
2.使用的是deamon方式,产生两个进程,父进程监控子进程,若是子进程挂了,父进程重新启动子进程,子进程负责每隔10秒钟执行任务;
3.而且当任务执行时间超长时,不会出现两个任务同时执行的现象,下一个任务只会延后。也可以用后台运行方式运行任务,这样和crontab的效果一样
4.若是时间间隔为10秒,而任务只执行了1秒,则sleep 9秒后,执行下一次任务
5.若是把sleep改为usleep的话可以精确到微秒
引用
#运行执行 sh /Application/sdns/trigger/task_crontab.sh >> /Application/sdns/log/crontab.log 2>&1
#要定时执行的脚本,注意:不使用后台运行,则若是超过10秒的话,下一次会延迟,若是使用后台执行的话,有可能出现两个任务并行的问题
dlc_cmdline="sh /Application/sdns/trigger/dotask.sh >> /Application/sdns/log/dotask.log";
#本shell脚本的执行路径
dlc_thiscmd="sh /Application/sdns/trigger/task_crontab.sh >> /Application/sdns/log/crontab.log 2>&1"
#任务执行时间间隔
dlc_task_timeout=10;
#是否后台执行deamon
is_deamon=$1;
#deamon,父进程
if [ "$is_deamon" == "--deamon" ]
then
echo "deamon start"
while [ 1 ]
do
date +"%F %T $dlc_thiscmd is started";
#调用子进程
$dlc_thiscmd
date +"%F %T $dlc_thiscmd is ended";
done
fi
#子进程的代码
while [ 1 ]
do
date +"%F %T $dlc_cmdline is started" ;
#记录本次程序开始时间
dlc_start_time=`date +%s`
#执行任务
$dlc_cmdline
#计算和时间间隔的差距
dlc_sleep_time=$(($dlc_task_timeout+$dlc_start_time-`date +%s`));
echo "sleep_time=[$dlc_sleep_time]";
#不够10秒,则sleep到10秒
if [ "$dlc_sleep_time" -gt 0 ]
then
sleep $dlc_sleep_time;
fi
date +"%F %T $dlc_cmdline is ended";
done
转自:http://blog.chinaunix.net/space.php?uid=11121450&do=blog&id=274490
#要定时执行的脚本,注意:不使用后台运行,则若是超过10秒的话,下一次会延迟,若是使用后台执行的话,有可能出现两个任务并行的问题
dlc_cmdline="sh /Application/sdns/trigger/dotask.sh >> /Application/sdns/log/dotask.log";
#本shell脚本的执行路径
dlc_thiscmd="sh /Application/sdns/trigger/task_crontab.sh >> /Application/sdns/log/crontab.log 2>&1"
#任务执行时间间隔
dlc_task_timeout=10;
#是否后台执行deamon
is_deamon=$1;
#deamon,父进程
if [ "$is_deamon" == "--deamon" ]
then
echo "deamon start"
while [ 1 ]
do
date +"%F %T $dlc_thiscmd is started";
#调用子进程
$dlc_thiscmd
date +"%F %T $dlc_thiscmd is ended";
done
fi
#子进程的代码
while [ 1 ]
do
date +"%F %T $dlc_cmdline is started" ;
#记录本次程序开始时间
dlc_start_time=`date +%s`
#执行任务
$dlc_cmdline
#计算和时间间隔的差距
dlc_sleep_time=$(($dlc_task_timeout+$dlc_start_time-`date +%s`));
echo "sleep_time=[$dlc_sleep_time]";
#不够10秒,则sleep到10秒
if [ "$dlc_sleep_time" -gt 0 ]
then
sleep $dlc_sleep_time;
fi
date +"%F %T $dlc_cmdline is ended";
done
转自:http://blog.chinaunix.net/space.php?uid=11121450&do=blog&id=274490
Jun
16
今天编译内核后重启IPTABLES时却无法启动如下:
[root@localhost ~]# service iptables restart
Flushing firewall rules:
[ OK ]
Setting chains to policy ACCEPT: filter [ OK ]
Unloading iptables modules: [ OK ]
Applying iptables firewall rules: iptables-restore: line 31 failed
[FAILED]
配置文件是:
[root@localhost ~]# vi /etc/sysconfig/iptables
# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 20 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 2049 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 137 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 138 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 139 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 445 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 23 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5601 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5602 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
这个问题查了很久,后来 strace iptables-restore /etc/sysconfig/iptables 发现问题。
open("/lib/iptables/libipt_RH-Firewall-1-INPUT.so", O_RDONLY) = -1 ENOENT (No such file or directory)
这个libipt_RH-Firewall-1-INPUT.so我的2.6.25.2的内核没有编译出来(或者可能就没有)。
但是其实这个.so文件没有也可以正常工作的。后来我在H-Firewall-1-INPUT正常的CentOS5.1上也没看到这个.so文件。
RH-Firewall-1-INPUT是个自定义的子链。
可以通过
#iptables -N RH-Firewall-1-INPUT
#service iptables save
#service iptables restart
c)ip_conntrack_netbios_n
[root@localhost ~]# service iptables restart
Flushing firewall rules: [ OK ]
Setting chains to policy ACCEPT: filter [ OK ]
Unloading iptables modules: [ OK ]
Applying iptables firewall rules: [ OK ]
Loading additional iptables modules: ip_conntrack_netbios_n[FAILED]
调试/etc/rc.d/init.d/iptables查找问题。
发现:
# Load additional modules (helpers)
if [ -n "$IPTABLES_MODULES" ]; then
echo -n $"Loading additional $IPTABLES modules: "
ret=0
for mod in $IPTABLES_MODULES; do
echo -n "$mod "
modprobe $mod > /dev/null 2>&1
let ret+=$?;
done
[ $ret -eq 0 ] && success || failure
echo
fi
touch $VAR_SUBSYS_IPTABLES
return $ret
modprobe ip_conntrack_netbios_ns > /dev/null 2>&1
而ip_conntrack_netbios_ns这个文件我没有的,奇怪的是IPTABLES_MODULES这个参数在/etc/rc.d/init.d/iptables我没有找到赋值的地方。原来是在/etc/sysconfig/iptables-config
注释掉。
IPTABLES_MODULES="ip_conntrack_netbios_ns"
好像是配置netbios穿越NAT用的,一般用不到的。
ip_conntrack_netbios_ns 这个模块在make menuconfig 中是IP_NF_NETBIOS_NS。
/etc/rc.d/init.d/iptables restart
[root@localhost ~]# /etc/rc.d/init.d/iptables restart
Flushing firewall rules: [ OK ]
Setting chains to policy ACCEPT: filter [ OK ]
Unloading iptables modules: [ OK ]
Applying iptables firewall rules: [ OK ]
去掉脚本中的调试语句。OK
[root@localhost ~]# service iptables restart
Flushing firewall rules:
[ OK ]
Setting chains to policy ACCEPT: filter [ OK ]
Unloading iptables modules: [ OK ]
Applying iptables firewall rules: iptables-restore: line 31 failed
[FAILED]
配置文件是:
[root@localhost ~]# vi /etc/sysconfig/iptables
# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 20 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 2049 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 137 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m udp -p udp --dport 138 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 139 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 445 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 23 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5601 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5602 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
这个问题查了很久,后来 strace iptables-restore /etc/sysconfig/iptables 发现问题。
open("/lib/iptables/libipt_RH-Firewall-1-INPUT.so", O_RDONLY) = -1 ENOENT (No such file or directory)
这个libipt_RH-Firewall-1-INPUT.so我的2.6.25.2的内核没有编译出来(或者可能就没有)。
但是其实这个.so文件没有也可以正常工作的。后来我在H-Firewall-1-INPUT正常的CentOS5.1上也没看到这个.so文件。
RH-Firewall-1-INPUT是个自定义的子链。
可以通过
#iptables -N RH-Firewall-1-INPUT
#service iptables save
#service iptables restart
c)ip_conntrack_netbios_n
[root@localhost ~]# service iptables restart
Flushing firewall rules: [ OK ]
Setting chains to policy ACCEPT: filter [ OK ]
Unloading iptables modules: [ OK ]
Applying iptables firewall rules: [ OK ]
Loading additional iptables modules: ip_conntrack_netbios_n[FAILED]
调试/etc/rc.d/init.d/iptables查找问题。
发现:
# Load additional modules (helpers)
if [ -n "$IPTABLES_MODULES" ]; then
echo -n $"Loading additional $IPTABLES modules: "
ret=0
for mod in $IPTABLES_MODULES; do
echo -n "$mod "
modprobe $mod > /dev/null 2>&1
let ret+=$?;
done
[ $ret -eq 0 ] && success || failure
echo
fi
touch $VAR_SUBSYS_IPTABLES
return $ret
modprobe ip_conntrack_netbios_ns > /dev/null 2>&1
而ip_conntrack_netbios_ns这个文件我没有的,奇怪的是IPTABLES_MODULES这个参数在/etc/rc.d/init.d/iptables我没有找到赋值的地方。原来是在/etc/sysconfig/iptables-config
注释掉。
IPTABLES_MODULES="ip_conntrack_netbios_ns"
好像是配置netbios穿越NAT用的,一般用不到的。
ip_conntrack_netbios_ns 这个模块在make menuconfig 中是IP_NF_NETBIOS_NS。
/etc/rc.d/init.d/iptables restart
[root@localhost ~]# /etc/rc.d/init.d/iptables restart
Flushing firewall rules: [ OK ]
Setting chains to policy ACCEPT: filter [ OK ]
Unloading iptables modules: [ OK ]
Applying iptables firewall rules: [ OK ]
去掉脚本中的调试语句。OK
Jun
1
一、 web2.0网站常用可用性功能模块分析
Web 2.0网站是指将传统的网站构架(平台、内容源、用户、传播方式等)转化到以用户为核心的网站构架上来,包括一系列体现web2.0概念的元素、定位和创 意。web2.0网站在构架上须体现两大宗旨,即强大的后台系统和简单的前台页面,也即提供良好的用户体验,体现以人为本,技术服务人类的宗旨。
web2.0网站常用功能块通常包括以下几大项:
1. Tag标签功能块
Tag(中文叫做”标签”) 是一种新的组织和管理在线信息的方式。它不同于传统的、针对文件本身的关键字检索,而是一种模糊化、智能化的分类。
网页使用Tag标签的好处:
为页面设置一个或者多个Tag标签可以引导读者阅读更多相关文章,为别人带去流量同理也为自己带来流量。
可以帮助读者及时了解一些未知的概念和知识点,提高用户体验。
Tag是人的意志和趋向的体现,Tag可以帮助你找到兴趣相投的人。
基于以上优势,Tag标签代替了传统的分类法,成为web2.0网站使用率最高的功能块(与其说是功能块倒不如说是一种内容导航和内容组织形式)。
一句话:Tag标签是一种更灵活的分类方法,功能在于引导,特点是无处不在,体现智能性、模糊性和趋向性。
2. RSS订阅功能块
RSS是在线共享内容的一种简易方式(也叫聚合内容,Really Simple Syndication)。通常在时效性比较强的内容上使用RSS订阅能更快速获取信息,网站提供RSS输出,有利于让用户获取网站内容的最新更新。网络 用户可以在客户端借助于支持RSS的聚合工具软件(例如SharpReader,NewzCrawler、FeedDemon),在不打开网站内容页面的 情况下阅读支持RSS输出的网站内容。
RSS订阅的方式:
订阅到客户端软件如周伯通、遨游浏览器RSS阅读、Foxmail RSS阅读等,此方式使用者较多
订阅到在线阅读(聚合类)门户网站如Google Reader,Yahoo Reader,抓虾、Gougou等,省去了安装RSS阅读器的麻烦
订阅到在线单用户聚合器如Lilina等,比较灵活
RSS订阅功能的最大好处是定向投递,也就是说RSS机制更能体现用户的意愿和个性,获取信息的方式也最直接和简单,这是RSS订阅功能备受青睐的 一大主要原因。
3. 推荐和收藏功能块
说到推荐功能,不仅web2.0网站在大量使用,传统的以cms平台为代表的内容模式的网站也在大量使用,推荐功能主要是指向一些网摘或者聚合类门 户网站推荐自己所浏览到的网页。当然,一种变相的推荐就是阅读者的自我收藏行为,在共享的模式下也能起到推荐的作用。
比较有名的推荐目标有以del.icio.us为代表的网摘类网站包括国内比较有名气的365key、和讯网摘、新浪vivi、天极网摘等。这里值 得一提的是前段时间曾涌现了大批网摘类网站,但他们坚持活下来的好像没有几个了,推荐使用前面提到的这几个网摘门户,人气基本上是使最旺的。
4. 评论和留言功能块
web2.0强调参与性,强调发挥用户的主导作用,这里的参与性除了所谓的订阅、推荐功能外更多地体现在用户对内容的评价和态度,这就要靠评论功能 块来完成。一个典型的web2.0网站或者说一个能体现人气的web2.0网站都会花大量篇幅来体现用户的观点和视觉。这里尤其要提到web2.0中的带 头老大web blog,评论功能已经成为博客主人与浏览者交流的主要阵地,是体现网站人气的最直观因素。
评论功能块应用在博客系统中实际上已经和博客内容相分离,而更好的应用恰恰是一些以点评为主的web2.0网站比如豆瓣、点评网等,这里的评论功能 块直接制造了内容也极大地体现了网站的人气,所以说评论功能块是web2.0网站最有力的武器。
5. 站内搜索功能块
搜索是信息来源最直接的方式之一,无论你的网站是否打上web2.0的烙印,搜索对于一个体系庞大、内容丰富的大型网站都是非常必要的。Tag标签 在某种程度上起到搜索的作用,它能够有效聚合以此Tag为关键词的内容,但这种情况的前提是此Tag标签对浏览者是可见的,也就是说当Tag标签摆在浏览 者的眼前时才成立,而对于那些浏览者想要的信息却没有Tag标签来引导时搜索就是达到此目的的最好方法。
对于web2.0网站,站内搜索以标题或者Tag为搜索域都能起到好的效果,但本人不建议使用内容搜索域,因为这不符合搜索的高效性原则。同时,具 有突出关键词的内容往往都可以用Tag标签来引导,因此使用内容域来搜索实际上是一种浪费服务器资源的行为,而且搜索结果的准确性将大打折扣。
6. 群组功能块
我为什么要把群组作为web2.0网站的功能块来分析呢,因为群组是web2.0网站的一大特点,也是web2.0所要体现的服务宗旨所在。一个 web2.0网站,博客也好、播客也好、点评也好,抑或是网摘、聚合门户,他们都强调人的参与性。物以类聚、人以群分,每个参与者都有自己的兴趣趋 向,web2.0网站的另一主要功能就是帮助这些人找到同样兴趣的人并形成一个活跃的群体,这是web2.0网站的根本。
总结:web2.0网站倡导的是集体创作、共享资源,靠的是人气,体现的是参与性,一个没有参与性的web2.0网站都不足以成为web2.0。以 上提到的这几个功能块就是以吸引用户参与和引导用户参与为目的的,真正的web2.0不是什么深奥的东西,只有一点,那就是如何让浏览者沸腾起来。
二、 Flickr的幕后故事
我们都看到 Flickr 的成功,而又有多少”精英”们了解过 Flickr 背后的过程是多么充满艰险。
Flickr 是全 CGI 的动态构架,并以一种 .gne 的脚本作为 CGI 程序语言。不管网站制作菜鸟还是高手都会疑惑:gne 是哪种程序语言?答案:gne 不是一种语言,Flickr 是以极为经典的 PHP + MySQL 方式实现的,在被 Yahoo 收购服务器搬入美国之前,使用了 21 台(69.90.111.101-121) Apache/PHP 做 Web、23 台图片服务器、另有 MySQL 服务器组成的数据库集群的服务器数量未知。现在估计使用的是 Yahoo 的负载均衡系统,对外只有一个 Web 的 IP 和图片服务器的 IP 了。
那为何 .php 的文件要改成 .gne 呢?以往有大型网站为向后兼容性考虑,隐藏以程序语言命名的脚本文件扩展名,比如 Baidu 隐藏了 .php(Google 的 http 服务器是自己写的,整合了脚本程序,个别页面是 .py–Python);还有一些网站是改成自己网站名相关的扩展名,如 MSN 的群组则是 .msnw,榕树下是 .rs。
那 Flickr 的 gne 是什么意思?我在维基百科的 Flickr 条目上找到了答案(中文 Flickr 条目上没有写明) 。原来 GNE 是 Game NeverEnding 的缩写,Flickr 的开发者 Ludicorp 在 2002-2004 年一直在开发这套以 Game NerverEnding 为名称的大型多人在线角色扮演游戏–一套基于浏览器的 Web 游戏系统,个人以为应该就是当年九城的虚拟城市。但是开发近 3 年后该计划不得不破产,最终只发布了一个 Beta 版,而 Ludicorp 将这套系统稍加移植,就有了 Flickr。呵呵,原来 gne 是一个项目的名称。关于 GNE 的一些连接:http://del.icio.us/schee/gne。
早期的 Flickr 想做成在类似聊天室的地方让网友分享、交流自己的照片,注重社区形式和保护照片不被外部引用(见徐子涵2004年的文章),可能是看到了 Hello 的模式吧。但是聪明的 Flickr 团队不久就改变了策略,淡化了传统的社区形式–如聊天室、而加强了现在使其功成名就的 Tag 组织形式,一种更自由更随兴更轻松好玩的大社区形式,或者叫它广义社区吧,我随便叫的,可能太学究,看着别太在意就是了。另外,将原来照片只能在 Flash 内浏览的限制区除了,并大力推荐用户将照片引用到自己的 Blog,这无疑对于挑战传统相册系统有决定性意义。减少 Flash 后的网页更多地引进了新兴的 Ajax 技术,使界面操作变得非常 Cool。
这就是 Flickr 的历史,清晰地看到了他们对于优秀产品的执著。有了技术和经验积累,加上不断坚持,总有一天时来运转,你的产品会成为新潮流的里程碑。
还有一句话要告诉 Yupoo 等:把 Flickr 想成一个有 Tag 功能的在线相册就已经错远了;复制粘贴者们想当然将 Flickr 去其糟粕取其精华,结果无关紧要的拿来了,将令人激动的优点都去掉了,结果剩下什么?
三、 YouTube 的架构扩展
在西雅图扩展性的技术研讨会上,YouTube 的 Cuong Do 做了关于 YouTube Scalability 的报告。视频内容在 Google Video 上有(地址),可惜国内用户看不到。
Kyle Cordes 对这个视频中的内容做了介绍。里面有不少技术性的内容。值得分享一下。(Kyle Cordes 的介绍是本文的主要来源)
简单的说 YouTube 的数据流量, “一天的YouTube流量相当于发送750亿封电子邮件.”, 2006 年中就有消息说每日 PV 超过 1 亿,现在? 更夸张了,”每天有10亿次下载以及6,5000次上传”, 真假姑且不论, 的确是超乎寻常的海量. 国内的互联网应用,但从数据量来看,怕是只有 51.com 有这个规模. 但技术上和 YouTube 就没法子比了.
1. Web 服务器
YouTube 出于开发速度的考虑,大部分代码都是 Python 开发的。Web 服务器有部分是 Apache, 用 FastCGI 模式。对于视频内容则用 Lighttpd 。据我所知,MySpace 也有部分服务器用 Lighttpd ,但量不大。YouTube 是 Lighttpd 最成功的案例。(国内用 Lighttpd 站点不多,豆瓣用的比较舒服。by Fenng)
2. 视频
视频的缩略图(Thumbnails)给服务器带来了很大的挑战。每个视频平均有4个缩略图,而每个 Web 页面上更是有多个,每秒钟因为这个带来的磁盘 IO 请求太大。YouTube 技术人员启用了单独的服务器群组来承担这个压力,并且针对 Cache 和 OS 做了部分优化。另一方面,缩略图请求的压力导致 Lighttpd 性能下降。通过 Hack Lighttpd 增加更多的 worker 线程很大程度解决了问题。而最新的解决方案是起用了 Google 的 BigTable, 这下子从性能、容错、缓存上都有更好表现。看人家这收购的,好钢用在了刀刃上。
出于冗余的考虑,每个视频文件放在一组迷你 Cluster 上,所谓 “迷你 Cluster” 就是一组具有相同内容的服务器。最火的视频放在 CDN 上,这样自己的服务器只需要承担一些”漏网”的随即访问即可。YouTube 使用简单、廉价、通用的硬件,这一点和 Google 风格倒是一致。至于维护手段,也都是常见的工具,如 rsync, SSH 等,只不过人家更手熟罢了。
3. 数据库
YouTube 用 MySQL 存储元数据–用户信息、视频信息什么的。数据库服务器曾经一度遇到 SWAP 颠簸的问题,解决办法是删掉了 SWAP 分区! 管用。
最初的 DB 只有 10 块硬盘,RAID 10 ,后来追加了一组 RAID 1。够省的。这一波 Web 2.0 公司很少有用 Oracle 的(我知道的只有 Bebo,参见这里). 在扩展性方面,路线也是和其他站点类似,复制,分散 IO。最终的解决之道是”分区”,这个不是数据库层面的表分区,而是业务层面的分区(在用户名字或者 ID 上做文章,应用程序控制查找机制)
YouTube 也用 Memcached.
很想了解一下国内 Web 2.0 网站的数据信息,有谁可以提供一点 ?
四、 mixi.jp:使用开源软件搭建的可扩展SNS网站
Mixi目前是日本排名第三的网站,全球排名42,主要提供SNS服务:日记,群组,站内消息,评论,相册等等,是日本最大的SNS网站。Mixi 从2003年12月份开始开发,由现在它的CTO – Batara Kesuma一个人焊,焊了四个月,在2004年2月份开始上线运行。两个月后就注册了1w用户,日访问量60wPV。在随后的一年里,用户增长到了 21w,第二年,增长到了200w。到今年四月份已经增长到370w注册用户,并且还在以每天1.5w人的注册量增长。这些用户中70%是活跃用户(活跃 用户:三天内至少登录一次的用户),平均每个用户每周在线时间为将近3个半小时。
下面我们来看它的技术架构。Mixi采用开源软件作为架构的基础:Linux 2.6,Apache 2.0,MySQL,Perl 5.8,memcached,Squid等等。到目前为止已经有100多台MySQL数据库服务器,并且在以每月10多台的速度增长。Mixi的数据库连 接方式采用的是每次查询都进行连接,而不是持久连接。数据库大多数是以InnoDB方式运行。Mixi解决扩展问题主要依赖于对数据库的切分。
首先进行垂直切分,按照表的内容将不同的表划分到不同的数据库中。然后是水平切分,根据用户的ID将不同用户的内容再划分的不同的数据库中,这是比 较通常的做法,也很管用。划分的关键还是在于应用中的实现,需要将操作封装在在数据层,而尽量不影响业务层。当然完全不改变逻辑层也不可能,这时候最能检 验以前的设计是否到位,如果以前设计的不错,那创建连接的时候传个表名,用户ID进去差不多就解决问题了,而以前如果sql代码到处飞,或者数据层封装的 不太好的话那就累了。
这样做了以后并不能从根本上解决问题,尤其是对于像mixi这种SNS网站,页面上往往需要引用大量的用户信息,好友信息,图片,文章信息,跨表, 跨库操作相当多。这个时候就需要发挥memcached的作用了,用大内存把这些不变的数据全都缓存起来,而当修改时就通知cache过期,这样应用层基 本上就可以解决大部分问题了,只会有很小一部分请求穿透应用层,用到数据库。Mixi的经验是平均每个页面的加载时间在0.02秒左右(当然根据页面大小 情况不尽相似),可以说明这种做法是行之有效的。Mixi一共在32台机器上有缓存服务器,每个Cache Server 2G内存,这些Cache Server与App Server装在一起。因为Cache Server对CPU消耗不大,而有了Cache Server的支援,App Server对内存要求也不是太高,所以可以和平共处,更有效的利用资源。
图片的处理就显得相对简单的多了。对于mixi而言,图像主要有两部分:一部分是经常要使用到的,像用户头像,群组的头像等等,大概有100多 GB,它们被Squid和CDN所缓存,命中率相对比较高;另一部分是用户上传的大量照片,它们的个体访问量相对而言比较小,命中率也比较低,使用 Cache不划算,所以对于这些照片的策略是直接在用户上传的时候分发到到图片存储服务器上,在用户访问的时候直接进行访问,当然图片的位置需要在数据库 中进行记录,不然找不到放在哪台服务器上就郁闷了。
Web 2.0网站是指将传统的网站构架(平台、内容源、用户、传播方式等)转化到以用户为核心的网站构架上来,包括一系列体现web2.0概念的元素、定位和创 意。web2.0网站在构架上须体现两大宗旨,即强大的后台系统和简单的前台页面,也即提供良好的用户体验,体现以人为本,技术服务人类的宗旨。
web2.0网站常用功能块通常包括以下几大项:
1. Tag标签功能块
Tag(中文叫做”标签”) 是一种新的组织和管理在线信息的方式。它不同于传统的、针对文件本身的关键字检索,而是一种模糊化、智能化的分类。
网页使用Tag标签的好处:
为页面设置一个或者多个Tag标签可以引导读者阅读更多相关文章,为别人带去流量同理也为自己带来流量。
可以帮助读者及时了解一些未知的概念和知识点,提高用户体验。
Tag是人的意志和趋向的体现,Tag可以帮助你找到兴趣相投的人。
基于以上优势,Tag标签代替了传统的分类法,成为web2.0网站使用率最高的功能块(与其说是功能块倒不如说是一种内容导航和内容组织形式)。
一句话:Tag标签是一种更灵活的分类方法,功能在于引导,特点是无处不在,体现智能性、模糊性和趋向性。
2. RSS订阅功能块
RSS是在线共享内容的一种简易方式(也叫聚合内容,Really Simple Syndication)。通常在时效性比较强的内容上使用RSS订阅能更快速获取信息,网站提供RSS输出,有利于让用户获取网站内容的最新更新。网络 用户可以在客户端借助于支持RSS的聚合工具软件(例如SharpReader,NewzCrawler、FeedDemon),在不打开网站内容页面的 情况下阅读支持RSS输出的网站内容。
RSS订阅的方式:
订阅到客户端软件如周伯通、遨游浏览器RSS阅读、Foxmail RSS阅读等,此方式使用者较多
订阅到在线阅读(聚合类)门户网站如Google Reader,Yahoo Reader,抓虾、Gougou等,省去了安装RSS阅读器的麻烦
订阅到在线单用户聚合器如Lilina等,比较灵活
RSS订阅功能的最大好处是定向投递,也就是说RSS机制更能体现用户的意愿和个性,获取信息的方式也最直接和简单,这是RSS订阅功能备受青睐的 一大主要原因。
3. 推荐和收藏功能块
说到推荐功能,不仅web2.0网站在大量使用,传统的以cms平台为代表的内容模式的网站也在大量使用,推荐功能主要是指向一些网摘或者聚合类门 户网站推荐自己所浏览到的网页。当然,一种变相的推荐就是阅读者的自我收藏行为,在共享的模式下也能起到推荐的作用。
比较有名的推荐目标有以del.icio.us为代表的网摘类网站包括国内比较有名气的365key、和讯网摘、新浪vivi、天极网摘等。这里值 得一提的是前段时间曾涌现了大批网摘类网站,但他们坚持活下来的好像没有几个了,推荐使用前面提到的这几个网摘门户,人气基本上是使最旺的。
4. 评论和留言功能块
web2.0强调参与性,强调发挥用户的主导作用,这里的参与性除了所谓的订阅、推荐功能外更多地体现在用户对内容的评价和态度,这就要靠评论功能 块来完成。一个典型的web2.0网站或者说一个能体现人气的web2.0网站都会花大量篇幅来体现用户的观点和视觉。这里尤其要提到web2.0中的带 头老大web blog,评论功能已经成为博客主人与浏览者交流的主要阵地,是体现网站人气的最直观因素。
评论功能块应用在博客系统中实际上已经和博客内容相分离,而更好的应用恰恰是一些以点评为主的web2.0网站比如豆瓣、点评网等,这里的评论功能 块直接制造了内容也极大地体现了网站的人气,所以说评论功能块是web2.0网站最有力的武器。
5. 站内搜索功能块
搜索是信息来源最直接的方式之一,无论你的网站是否打上web2.0的烙印,搜索对于一个体系庞大、内容丰富的大型网站都是非常必要的。Tag标签 在某种程度上起到搜索的作用,它能够有效聚合以此Tag为关键词的内容,但这种情况的前提是此Tag标签对浏览者是可见的,也就是说当Tag标签摆在浏览 者的眼前时才成立,而对于那些浏览者想要的信息却没有Tag标签来引导时搜索就是达到此目的的最好方法。
对于web2.0网站,站内搜索以标题或者Tag为搜索域都能起到好的效果,但本人不建议使用内容搜索域,因为这不符合搜索的高效性原则。同时,具 有突出关键词的内容往往都可以用Tag标签来引导,因此使用内容域来搜索实际上是一种浪费服务器资源的行为,而且搜索结果的准确性将大打折扣。
6. 群组功能块
我为什么要把群组作为web2.0网站的功能块来分析呢,因为群组是web2.0网站的一大特点,也是web2.0所要体现的服务宗旨所在。一个 web2.0网站,博客也好、播客也好、点评也好,抑或是网摘、聚合门户,他们都强调人的参与性。物以类聚、人以群分,每个参与者都有自己的兴趣趋 向,web2.0网站的另一主要功能就是帮助这些人找到同样兴趣的人并形成一个活跃的群体,这是web2.0网站的根本。
总结:web2.0网站倡导的是集体创作、共享资源,靠的是人气,体现的是参与性,一个没有参与性的web2.0网站都不足以成为web2.0。以 上提到的这几个功能块就是以吸引用户参与和引导用户参与为目的的,真正的web2.0不是什么深奥的东西,只有一点,那就是如何让浏览者沸腾起来。
二、 Flickr的幕后故事
我们都看到 Flickr 的成功,而又有多少”精英”们了解过 Flickr 背后的过程是多么充满艰险。
Flickr 是全 CGI 的动态构架,并以一种 .gne 的脚本作为 CGI 程序语言。不管网站制作菜鸟还是高手都会疑惑:gne 是哪种程序语言?答案:gne 不是一种语言,Flickr 是以极为经典的 PHP + MySQL 方式实现的,在被 Yahoo 收购服务器搬入美国之前,使用了 21 台(69.90.111.101-121) Apache/PHP 做 Web、23 台图片服务器、另有 MySQL 服务器组成的数据库集群的服务器数量未知。现在估计使用的是 Yahoo 的负载均衡系统,对外只有一个 Web 的 IP 和图片服务器的 IP 了。
那为何 .php 的文件要改成 .gne 呢?以往有大型网站为向后兼容性考虑,隐藏以程序语言命名的脚本文件扩展名,比如 Baidu 隐藏了 .php(Google 的 http 服务器是自己写的,整合了脚本程序,个别页面是 .py–Python);还有一些网站是改成自己网站名相关的扩展名,如 MSN 的群组则是 .msnw,榕树下是 .rs。
那 Flickr 的 gne 是什么意思?我在维基百科的 Flickr 条目上找到了答案(中文 Flickr 条目上没有写明) 。原来 GNE 是 Game NeverEnding 的缩写,Flickr 的开发者 Ludicorp 在 2002-2004 年一直在开发这套以 Game NerverEnding 为名称的大型多人在线角色扮演游戏–一套基于浏览器的 Web 游戏系统,个人以为应该就是当年九城的虚拟城市。但是开发近 3 年后该计划不得不破产,最终只发布了一个 Beta 版,而 Ludicorp 将这套系统稍加移植,就有了 Flickr。呵呵,原来 gne 是一个项目的名称。关于 GNE 的一些连接:http://del.icio.us/schee/gne。
早期的 Flickr 想做成在类似聊天室的地方让网友分享、交流自己的照片,注重社区形式和保护照片不被外部引用(见徐子涵2004年的文章),可能是看到了 Hello 的模式吧。但是聪明的 Flickr 团队不久就改变了策略,淡化了传统的社区形式–如聊天室、而加强了现在使其功成名就的 Tag 组织形式,一种更自由更随兴更轻松好玩的大社区形式,或者叫它广义社区吧,我随便叫的,可能太学究,看着别太在意就是了。另外,将原来照片只能在 Flash 内浏览的限制区除了,并大力推荐用户将照片引用到自己的 Blog,这无疑对于挑战传统相册系统有决定性意义。减少 Flash 后的网页更多地引进了新兴的 Ajax 技术,使界面操作变得非常 Cool。
这就是 Flickr 的历史,清晰地看到了他们对于优秀产品的执著。有了技术和经验积累,加上不断坚持,总有一天时来运转,你的产品会成为新潮流的里程碑。
还有一句话要告诉 Yupoo 等:把 Flickr 想成一个有 Tag 功能的在线相册就已经错远了;复制粘贴者们想当然将 Flickr 去其糟粕取其精华,结果无关紧要的拿来了,将令人激动的优点都去掉了,结果剩下什么?
三、 YouTube 的架构扩展
在西雅图扩展性的技术研讨会上,YouTube 的 Cuong Do 做了关于 YouTube Scalability 的报告。视频内容在 Google Video 上有(地址),可惜国内用户看不到。
Kyle Cordes 对这个视频中的内容做了介绍。里面有不少技术性的内容。值得分享一下。(Kyle Cordes 的介绍是本文的主要来源)
简单的说 YouTube 的数据流量, “一天的YouTube流量相当于发送750亿封电子邮件.”, 2006 年中就有消息说每日 PV 超过 1 亿,现在? 更夸张了,”每天有10亿次下载以及6,5000次上传”, 真假姑且不论, 的确是超乎寻常的海量. 国内的互联网应用,但从数据量来看,怕是只有 51.com 有这个规模. 但技术上和 YouTube 就没法子比了.
1. Web 服务器
YouTube 出于开发速度的考虑,大部分代码都是 Python 开发的。Web 服务器有部分是 Apache, 用 FastCGI 模式。对于视频内容则用 Lighttpd 。据我所知,MySpace 也有部分服务器用 Lighttpd ,但量不大。YouTube 是 Lighttpd 最成功的案例。(国内用 Lighttpd 站点不多,豆瓣用的比较舒服。by Fenng)
2. 视频
视频的缩略图(Thumbnails)给服务器带来了很大的挑战。每个视频平均有4个缩略图,而每个 Web 页面上更是有多个,每秒钟因为这个带来的磁盘 IO 请求太大。YouTube 技术人员启用了单独的服务器群组来承担这个压力,并且针对 Cache 和 OS 做了部分优化。另一方面,缩略图请求的压力导致 Lighttpd 性能下降。通过 Hack Lighttpd 增加更多的 worker 线程很大程度解决了问题。而最新的解决方案是起用了 Google 的 BigTable, 这下子从性能、容错、缓存上都有更好表现。看人家这收购的,好钢用在了刀刃上。
出于冗余的考虑,每个视频文件放在一组迷你 Cluster 上,所谓 “迷你 Cluster” 就是一组具有相同内容的服务器。最火的视频放在 CDN 上,这样自己的服务器只需要承担一些”漏网”的随即访问即可。YouTube 使用简单、廉价、通用的硬件,这一点和 Google 风格倒是一致。至于维护手段,也都是常见的工具,如 rsync, SSH 等,只不过人家更手熟罢了。
3. 数据库
YouTube 用 MySQL 存储元数据–用户信息、视频信息什么的。数据库服务器曾经一度遇到 SWAP 颠簸的问题,解决办法是删掉了 SWAP 分区! 管用。
最初的 DB 只有 10 块硬盘,RAID 10 ,后来追加了一组 RAID 1。够省的。这一波 Web 2.0 公司很少有用 Oracle 的(我知道的只有 Bebo,参见这里). 在扩展性方面,路线也是和其他站点类似,复制,分散 IO。最终的解决之道是”分区”,这个不是数据库层面的表分区,而是业务层面的分区(在用户名字或者 ID 上做文章,应用程序控制查找机制)
YouTube 也用 Memcached.
很想了解一下国内 Web 2.0 网站的数据信息,有谁可以提供一点 ?
四、 mixi.jp:使用开源软件搭建的可扩展SNS网站
Mixi目前是日本排名第三的网站,全球排名42,主要提供SNS服务:日记,群组,站内消息,评论,相册等等,是日本最大的SNS网站。Mixi 从2003年12月份开始开发,由现在它的CTO – Batara Kesuma一个人焊,焊了四个月,在2004年2月份开始上线运行。两个月后就注册了1w用户,日访问量60wPV。在随后的一年里,用户增长到了 21w,第二年,增长到了200w。到今年四月份已经增长到370w注册用户,并且还在以每天1.5w人的注册量增长。这些用户中70%是活跃用户(活跃 用户:三天内至少登录一次的用户),平均每个用户每周在线时间为将近3个半小时。
下面我们来看它的技术架构。Mixi采用开源软件作为架构的基础:Linux 2.6,Apache 2.0,MySQL,Perl 5.8,memcached,Squid等等。到目前为止已经有100多台MySQL数据库服务器,并且在以每月10多台的速度增长。Mixi的数据库连 接方式采用的是每次查询都进行连接,而不是持久连接。数据库大多数是以InnoDB方式运行。Mixi解决扩展问题主要依赖于对数据库的切分。
首先进行垂直切分,按照表的内容将不同的表划分到不同的数据库中。然后是水平切分,根据用户的ID将不同用户的内容再划分的不同的数据库中,这是比 较通常的做法,也很管用。划分的关键还是在于应用中的实现,需要将操作封装在在数据层,而尽量不影响业务层。当然完全不改变逻辑层也不可能,这时候最能检 验以前的设计是否到位,如果以前设计的不错,那创建连接的时候传个表名,用户ID进去差不多就解决问题了,而以前如果sql代码到处飞,或者数据层封装的 不太好的话那就累了。
这样做了以后并不能从根本上解决问题,尤其是对于像mixi这种SNS网站,页面上往往需要引用大量的用户信息,好友信息,图片,文章信息,跨表, 跨库操作相当多。这个时候就需要发挥memcached的作用了,用大内存把这些不变的数据全都缓存起来,而当修改时就通知cache过期,这样应用层基 本上就可以解决大部分问题了,只会有很小一部分请求穿透应用层,用到数据库。Mixi的经验是平均每个页面的加载时间在0.02秒左右(当然根据页面大小 情况不尽相似),可以说明这种做法是行之有效的。Mixi一共在32台机器上有缓存服务器,每个Cache Server 2G内存,这些Cache Server与App Server装在一起。因为Cache Server对CPU消耗不大,而有了Cache Server的支援,App Server对内存要求也不是太高,所以可以和平共处,更有效的利用资源。
图片的处理就显得相对简单的多了。对于mixi而言,图像主要有两部分:一部分是经常要使用到的,像用户头像,群组的头像等等,大概有100多 GB,它们被Squid和CDN所缓存,命中率相对比较高;另一部分是用户上传的大量照片,它们的个体访问量相对而言比较小,命中率也比较低,使用 Cache不划算,所以对于这些照片的策略是直接在用户上传的时候分发到到图片存储服务器上,在用户访问的时候直接进行访问,当然图片的位置需要在数据库 中进行记录,不然找不到放在哪台服务器上就郁闷了。
Jun
1
一、不要过设计:never over design
这是一个常常被提及的话题,但是只要想想你的架构里有多少功能是根本没有用到,或者最后废弃的,就能明白其重要性了,初涉架构设计,往往倾向于设计 大而化一的架构,希望设计出具有无比扩展性,能适应一切需求的增加架构Web开发领域是个非常动态的过程,我们很难预测下个星期的变化,而又需要对变化做 出最快最有效的响应。
eBay的工程师说过,他们的架构设计从来都不能满足系统的增长,所以他们的系统永远都在推翻重做。请注意,不是eBay架构师的能力有问题,他们 设计的架构总是建立旧版本的瓶颈上,希望通过新的架构带来突破,然而新架构带来的突破总是在很短的时间内就被新增需求淹没,于是他们不得不又使用新的架 构。
Web开发,是个非常敏捷的过程,变化随时都在产生,用户需求千变万化,许多方面偶然性非常高,较之软件开发,希望用一个架构规划以后的所有设计, 是不现实的。
二、Web架构生命周期:Web architecture‘s life cycle
既然要杜绝过设计,又要保证一定的前瞻性,那么怎么才能找到其中的平衡呢?希望下面的web架构生命周期能够帮到你。
所设计的架构需要在1-10倍的增长下,通过简单的增加硬件容量就能够胜任,而在5-10倍的增长期间,请着手下一个版本的架构设计,使之能承受下 一个10倍间的增长。
google之所以能够称霸,不完全是因为搜索技术和排序技术有多先进,其实包括baidu和yahoo,所使用的技术现在也已经大同小异,然 而,google能在一个月内通过增加上万台服务器来达到足够系统容量的能力确是很难被复制的。
三、缓存:Cache
空间换取时间,缓存永远计算机设计的重中之重,从CPU到IO,到处都可以看到缓存的身影,Web架构设计重,缓存设计必不可少,关于怎样设计合理 的缓 存,JBossCache的创始人,淘宝的创始人是这样说的:其实设计Web缓存和企业级缓存是非常不同的,企业级缓存偏重于逻辑,而Web缓存,简单快 速为好。
缓存带来的问题是什么?是程序的复杂度上升,因为数据散布在多个进程,所以同步就是一个麻烦的问题,加上集群,复杂度会进一步提高,在实际运用中, 采用怎样的同步策略常常需要和业务绑定。
老钱为搜狐设计的帖子设计了链表缓存,这样既可以满足灵活插入的需要,又能够快速阅读,而其他一些大型社区也经常采用类此的结构来优化帖子列 表,MemCache也是一个常常用到的工具。
Cache的常用的策略是:让数据在内存中,而不是在比较耗时的磁盘上。从这个角度讲,My SQL提供的heap引擎(存储方式)也是一个值得思考的方法,这种存储方法可以把数据存储在内存中,并且保留sql强大的查询能力,是不是一举两得呢?
我们这里只说到了读缓存,其实还有一种写缓存,在以内容为主的社区里比较少用到,因为这样的社区最主要需要解决的问题是读问题,但是在处理能力低于 请求能力时,或者单个希望请求先被缓存形成块,然后批量处理时,写缓存就出现了,在交互性很强的社区设计里我们很容易找到这样的缓存。
四、核心模块一定要自己开发:DIY your core module
这点我们是深有体会。钱宏武和云风也都有谈到,我们经常倾向于使用一些开源模块,如果不涉及核心模块,确实是可以的。如果涉及,那么就要小心了,因 为当访问量达到一定的程度,这些模块往往都有这样那样的问题,当然我们可以把问题归结为对开源的模块不熟悉,但是不管怎样,核心出现问题的时候,不能完全 掌握其代码是非常可怕的。
五、合理选择数据存储方式:reasonable data storage
我们一定要使用数据库吗,不一定,雷鸣告诉我们搜索不一定需要数据库,云风告诉我们,游戏不一定需要数据库,那么什么时候我们才需要数据库呢,为什 么不干脆用文件来代替他呢?
首先我们需要先承认,数据库也是对文件进行操作。我们需要数据库,主要是使用下面这几个功能:一个是数据存储,一个是数据检索。
在关系数据库中,我们其实非常在乎数据库的复杂搜索的能力,看看一个统计用的TSQL就知道了。
select c.Class_name,d.Class_name_2,a.Creativity_Title,b.User_name,(select count(Id) from review where Reviewid=a.Id) as countNum from Creativity as a,User_info as b,class as c,class2 as d where a.user_id=b.id and a.Creativity_Class=c.Id and a.Creativity_Class_2=d.Id
select a.Id,max(c.Class_name),(max(d.Class_name_2),max(a.Creativity_Title),max(b.User_name),count(e.Id) as countNum from Creativity as a,User_info as b,class as c,class2 as d,review as e where a.user_id=b.id and a.Creativity_Class=c.Id and a.Creativity_Class_2=d.Id and a.Id=e.Reviewid group by a.Id ……………………………………….
我们可以看出需要数据库关联,排序的能力,这个能力在某些情况下非常重要,但是如果你的网站的常规操作,全是这样复杂的逻辑,那效率一定是非常低 的,所以我们常常在数据库里加入许多冗余字段,来减小简单查询时关联等操作带来的压力,我们看看下面这张图,可以看到数据库的设计重心,和网站(指内容型 社区)需要面对的问题实际是有一些偏差的。
同样其他一些软件产品也遇到同样的问题所以具我了解,有许多特殊的运用都有自己设计的特殊数据存储结构与方法,比如有的大型服务程序采取树形数据存 储结构,Lucene使用文件来存储索引和文件。
从另外一个角度上看,使用数据库,意味着数据和表现是完全分离的(这当然是经典的设计思路),也就是说当需要展示数据时,不得不需要一个转换的过 程,也可以说是绑定的过程,当网站具备一定规模的时候,数据库往往成为效率的瓶颈,所以许多网站也采用直接书写静态文件的方法来避免读取操作时的绑定。
这并不是说我们从今天起就可以把我们亲爱的数据库打入冷宫,而是我们在设计数据的持久化时,需要根据实际情况来选择存储方式,而数据库不过是其中一 个选项。
六、搞清楚谁是最重要的人:Who’s the most important guy?
在用例需求分析的时候常常讲到涉众,就是和你的设计息息相关的人,在Web中我们一定以为最重要的涉众莫过于用户了。在一个传统的互动社区开发中, 最重要的东西是内容,用户产生内容,所以用户就是上帝,至于内容挑选工具,不就是给坐我后面三排的妹妹们用的吗?凑或行了,实在有问题我就在数据里手动帮 你加得了。
这大概是眼下许多小型甚至中型网站技术人员的普遍想法。钱宏武在他的讲座里谈到了这个问题:实际上网站每天产生的内容非常的多,普通人是不可能看完 的,而编辑负责把精华的内容推荐到首页上,所以很多用户读到的内容其实都依赖于编辑的推荐,所以设计让编辑工作方便的工具也是非常重要, 有时甚至是最重要的。
七、不要执着于文档:Don’t be crazy about document
Web开发的文档重要吗?什么文档最重要?我的看法是Web开发中交流>文档,现在大的软件公司比较流行的做法是:
注重产品设计文档,在这种方法里,产品文档非常详尽,并且没有歧义,开发人员基于设计文档开发,测试人员基于设计文档制定测试方案,任何新人都可以 通过阅读产品设计文档来了解项目的概况。
而Web项目从概念到实现的时间是非常短的,而且越短越好,并且由于变化迅速,要想写出完整的产品和需求文档是几乎不可能的,大多数情况是等你写出 完备的文档,项目早就是另外一个样子,但是没有文档的问题是,如果团队发生变化,添加新成员怎样才能了解软件的结构和概念呢?一种是每个人都了解软件的整 个结构,除非你的团队整体消失,否则任何一个人都能够担当培养新人的责任,这种面对面交流比文档有效率很多。
于是就有了前office开发者,现任yahoo中国某产品开发负责人的刘振飞所感觉到的落差,他说:“我们的项目是吵出来的”,我听完会心一笑。
八、团队:team
不要专家团队,而要外科手术式的团队。你的团队里一定要有清道夫,需要有弓箭手,让他们和项目一起成长,才是项目负责人的最大成就。
总 结:架构是一种权衡
Web开发的特点是是:没有太复杂的技术难点,一切在于迅速的把握需求,其实这正式敏捷开发的要旨所在,一切都可以非常快速的建立,非常快速的重 构,我们的开发工具,底层库和框架,包括搜索引擎和web文档提供的帮助,都提我们供给了敏捷的能力。
此外,相应的,最有效率的交流方式必须留给 Web开发,那就是面对面,不要太担心你的设计不能被完备的文档所保留下来,他们会以交流,代码和小卡片的方式保存下来。
人的因素会更加重要,无论是对用户的需求,还是开发人员的素质。
这是一个常常被提及的话题,但是只要想想你的架构里有多少功能是根本没有用到,或者最后废弃的,就能明白其重要性了,初涉架构设计,往往倾向于设计 大而化一的架构,希望设计出具有无比扩展性,能适应一切需求的增加架构Web开发领域是个非常动态的过程,我们很难预测下个星期的变化,而又需要对变化做 出最快最有效的响应。
eBay的工程师说过,他们的架构设计从来都不能满足系统的增长,所以他们的系统永远都在推翻重做。请注意,不是eBay架构师的能力有问题,他们 设计的架构总是建立旧版本的瓶颈上,希望通过新的架构带来突破,然而新架构带来的突破总是在很短的时间内就被新增需求淹没,于是他们不得不又使用新的架 构。
Web开发,是个非常敏捷的过程,变化随时都在产生,用户需求千变万化,许多方面偶然性非常高,较之软件开发,希望用一个架构规划以后的所有设计, 是不现实的。
二、Web架构生命周期:Web architecture‘s life cycle
既然要杜绝过设计,又要保证一定的前瞻性,那么怎么才能找到其中的平衡呢?希望下面的web架构生命周期能够帮到你。
所设计的架构需要在1-10倍的增长下,通过简单的增加硬件容量就能够胜任,而在5-10倍的增长期间,请着手下一个版本的架构设计,使之能承受下 一个10倍间的增长。
google之所以能够称霸,不完全是因为搜索技术和排序技术有多先进,其实包括baidu和yahoo,所使用的技术现在也已经大同小异,然 而,google能在一个月内通过增加上万台服务器来达到足够系统容量的能力确是很难被复制的。
三、缓存:Cache
空间换取时间,缓存永远计算机设计的重中之重,从CPU到IO,到处都可以看到缓存的身影,Web架构设计重,缓存设计必不可少,关于怎样设计合理 的缓 存,JBossCache的创始人,淘宝的创始人是这样说的:其实设计Web缓存和企业级缓存是非常不同的,企业级缓存偏重于逻辑,而Web缓存,简单快 速为好。
缓存带来的问题是什么?是程序的复杂度上升,因为数据散布在多个进程,所以同步就是一个麻烦的问题,加上集群,复杂度会进一步提高,在实际运用中, 采用怎样的同步策略常常需要和业务绑定。
老钱为搜狐设计的帖子设计了链表缓存,这样既可以满足灵活插入的需要,又能够快速阅读,而其他一些大型社区也经常采用类此的结构来优化帖子列 表,MemCache也是一个常常用到的工具。
Cache的常用的策略是:让数据在内存中,而不是在比较耗时的磁盘上。从这个角度讲,My SQL提供的heap引擎(存储方式)也是一个值得思考的方法,这种存储方法可以把数据存储在内存中,并且保留sql强大的查询能力,是不是一举两得呢?
我们这里只说到了读缓存,其实还有一种写缓存,在以内容为主的社区里比较少用到,因为这样的社区最主要需要解决的问题是读问题,但是在处理能力低于 请求能力时,或者单个希望请求先被缓存形成块,然后批量处理时,写缓存就出现了,在交互性很强的社区设计里我们很容易找到这样的缓存。
四、核心模块一定要自己开发:DIY your core module
这点我们是深有体会。钱宏武和云风也都有谈到,我们经常倾向于使用一些开源模块,如果不涉及核心模块,确实是可以的。如果涉及,那么就要小心了,因 为当访问量达到一定的程度,这些模块往往都有这样那样的问题,当然我们可以把问题归结为对开源的模块不熟悉,但是不管怎样,核心出现问题的时候,不能完全 掌握其代码是非常可怕的。
五、合理选择数据存储方式:reasonable data storage
我们一定要使用数据库吗,不一定,雷鸣告诉我们搜索不一定需要数据库,云风告诉我们,游戏不一定需要数据库,那么什么时候我们才需要数据库呢,为什 么不干脆用文件来代替他呢?
首先我们需要先承认,数据库也是对文件进行操作。我们需要数据库,主要是使用下面这几个功能:一个是数据存储,一个是数据检索。
在关系数据库中,我们其实非常在乎数据库的复杂搜索的能力,看看一个统计用的TSQL就知道了。
select c.Class_name,d.Class_name_2,a.Creativity_Title,b.User_name,(select count(Id) from review where Reviewid=a.Id) as countNum from Creativity as a,User_info as b,class as c,class2 as d where a.user_id=b.id and a.Creativity_Class=c.Id and a.Creativity_Class_2=d.Id
select a.Id,max(c.Class_name),(max(d.Class_name_2),max(a.Creativity_Title),max(b.User_name),count(e.Id) as countNum from Creativity as a,User_info as b,class as c,class2 as d,review as e where a.user_id=b.id and a.Creativity_Class=c.Id and a.Creativity_Class_2=d.Id and a.Id=e.Reviewid group by a.Id ……………………………………….
我们可以看出需要数据库关联,排序的能力,这个能力在某些情况下非常重要,但是如果你的网站的常规操作,全是这样复杂的逻辑,那效率一定是非常低 的,所以我们常常在数据库里加入许多冗余字段,来减小简单查询时关联等操作带来的压力,我们看看下面这张图,可以看到数据库的设计重心,和网站(指内容型 社区)需要面对的问题实际是有一些偏差的。
同样其他一些软件产品也遇到同样的问题所以具我了解,有许多特殊的运用都有自己设计的特殊数据存储结构与方法,比如有的大型服务程序采取树形数据存 储结构,Lucene使用文件来存储索引和文件。
从另外一个角度上看,使用数据库,意味着数据和表现是完全分离的(这当然是经典的设计思路),也就是说当需要展示数据时,不得不需要一个转换的过 程,也可以说是绑定的过程,当网站具备一定规模的时候,数据库往往成为效率的瓶颈,所以许多网站也采用直接书写静态文件的方法来避免读取操作时的绑定。
这并不是说我们从今天起就可以把我们亲爱的数据库打入冷宫,而是我们在设计数据的持久化时,需要根据实际情况来选择存储方式,而数据库不过是其中一 个选项。
六、搞清楚谁是最重要的人:Who’s the most important guy?
在用例需求分析的时候常常讲到涉众,就是和你的设计息息相关的人,在Web中我们一定以为最重要的涉众莫过于用户了。在一个传统的互动社区开发中, 最重要的东西是内容,用户产生内容,所以用户就是上帝,至于内容挑选工具,不就是给坐我后面三排的妹妹们用的吗?凑或行了,实在有问题我就在数据里手动帮 你加得了。
这大概是眼下许多小型甚至中型网站技术人员的普遍想法。钱宏武在他的讲座里谈到了这个问题:实际上网站每天产生的内容非常的多,普通人是不可能看完 的,而编辑负责把精华的内容推荐到首页上,所以很多用户读到的内容其实都依赖于编辑的推荐,所以设计让编辑工作方便的工具也是非常重要, 有时甚至是最重要的。
七、不要执着于文档:Don’t be crazy about document
Web开发的文档重要吗?什么文档最重要?我的看法是Web开发中交流>文档,现在大的软件公司比较流行的做法是:
注重产品设计文档,在这种方法里,产品文档非常详尽,并且没有歧义,开发人员基于设计文档开发,测试人员基于设计文档制定测试方案,任何新人都可以 通过阅读产品设计文档来了解项目的概况。
而Web项目从概念到实现的时间是非常短的,而且越短越好,并且由于变化迅速,要想写出完整的产品和需求文档是几乎不可能的,大多数情况是等你写出 完备的文档,项目早就是另外一个样子,但是没有文档的问题是,如果团队发生变化,添加新成员怎样才能了解软件的结构和概念呢?一种是每个人都了解软件的整 个结构,除非你的团队整体消失,否则任何一个人都能够担当培养新人的责任,这种面对面交流比文档有效率很多。
于是就有了前office开发者,现任yahoo中国某产品开发负责人的刘振飞所感觉到的落差,他说:“我们的项目是吵出来的”,我听完会心一笑。
八、团队:team
不要专家团队,而要外科手术式的团队。你的团队里一定要有清道夫,需要有弓箭手,让他们和项目一起成长,才是项目负责人的最大成就。
总 结:架构是一种权衡
Web开发的特点是是:没有太复杂的技术难点,一切在于迅速的把握需求,其实这正式敏捷开发的要旨所在,一切都可以非常快速的建立,非常快速的重 构,我们的开发工具,底层库和框架,包括搜索引擎和web文档提供的帮助,都提我们供给了敏捷的能力。
此外,相应的,最有效率的交流方式必须留给 Web开发,那就是面对面,不要太担心你的设计不能被完备的文档所保留下来,他们会以交流,代码和小卡片的方式保存下来。
人的因素会更加重要,无论是对用户的需求,还是开发人员的素质。