随着互联网web2.0网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速。而传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,例如:
1、High performance – 对数据库高并发读写的需求
web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。其实对于普通的BBS网站,往往也存在对高并发写请求的需求,例如像JavaEye网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,因此这是一个相当普遍的需求。
2、Huge Storage – 对海量数据的高效率存储和访问的需求
类似Facebook,twitter,Friendfeed这样的SNS网站,每天用户产生海量的用户动态,以Friendfeed为例,一个月就达到了2.5亿条用户动态,对于关系数据库来说,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。再例如大型web网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付。
3、High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求
在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,为什么数据库不能通过不断的添加服务器节点来实现扩展呢?
在上面提到的“三高”需求面前,关系数据库遇到了难以克服的障碍,而对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地,例如:
1、数据库事务一致性需求
很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低,有些场合对写一致性要求也不高。因此数据库事务管理成了数据库高负载下一个沉重的负担。
2、数据库的写实时性和读实时性需求
对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,比方说发一条消息之后,过几秒乃至十几秒之后,我的订阅者才看到这条动态是完全可以接受的。
3、对复杂的SQL查询,特别是多表关联查询的需求
任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询,特别是SNS类型的网站,从需求以及产品设计角度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。
因此,关系数据库在这些越来越多的应用场景下显得不那么合适了,为了解决这类问题的非关系数据库应运而生,现在这两年,各种各样非关系数据库,特别是键值数据库(Key-Value Store DB)风起云涌,多得让人眼花缭乱。前不久国外刚刚举办了NoSQL Conference,各路NoSQL数据库纷纷亮相,加上未亮相但是名声在外的,起码有超过10个开源的NoSQLDB,例如:
Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud, KiokuDB,Scalaris, Kai, ThruDB , ……
这些NoSQL数据库,有的是用C/C++编写的,有的是用Java编写的,还有的是用Erlang编写的,每个都有自己的独到之处,看都看不过来了,这些NoSQL数据库大致可以分为以下的三类:
一、满足极高读写性能需求的Kye-Value数据库:Redis,Tokyo Cabinet, Flare
高性能Key-Value数据库的主要特点就是具有极高的并发读写性能,Redis,Tokyo Cabinet, Flare,这3个Key-Value DB都是用C编写的,他们的性能都相当出色,但出了出色的性能,他们还有自己独特的功能:
1、Redis
Redis是一个很新的项目,刚刚发布了1.0版本。Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读写操作,是我知道的性能最快的Key-Value DB。
Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存List链表和Set集合的数据结构,而且还支持对List进行各种操作,例如从List两端push和pop数据,取List区间,排序等等,对Set支持各种集合的并集交集操作,此外单个value的最大限制是1GB,不像memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能,比方说用他的List来做FIFO双向链表,实现一个轻量级的高性能消息队列服务,用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一个功能加强版的memcached来用。
Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,并且它没有原生的可扩展机制,不具有scale(可扩展)能力,要依赖客户端来实现分布式读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。目前使用Redis的网站有github,Engine Yard。
2、Tokyo Cabinet和Tokoy Tyrant
TC和TT的开发者是日本人Mikio Hirabayashi,主要被用在日本最大的SNS网站mixi.jp上,TC发展的时间最早,现在已经是一个非常成熟的项目,也是Kye-Value数据库领域最大的热点,现在被广泛的应用在很多很多网站上。TC是一个高性能的存储引擎,而TT提供了多线程高并发服务器,性能也非常出色,每秒可以处理4-5万次读写操作。
TC除了支持Key-Value存储之外,还支持保存Hashtable数据类型,因此很像一个简单的数据库表,并且还支持基于column的条件查询,分页查询和排序功能,基本上相当于支持单表的基础查询功能了,所以可以简单的替代关系数据库的很多操作,这也是TC受到大家欢迎的主要原因之一,有一个Ruby的项目miyazakiresistance将TT的hashtable的操作封装成和ActiveRecord一样的操作,用起来非常爽。
TC/TT在mixi的实际应用当中,存储了2000万条以上的数据,同时支撑了上万个并发连接,是一个久经考验的项目。TC在保证了极高的并发读写性能的同时,具有可靠的数据持久化机制,同时还支持类似关系数据库表结构的hashtable以及简单的条件,分页和排序操作,是一个很棒的NoSQL数据库。
TC主要的缺点是没有scale的能力,如果单机无法满足要求,只能通过主从复制的方式扩展,另外有人提到TC的性能会随着数据量的增加而下降,当数据量上亿条以后,性能会有比较明显的下降。
这个是Tim Yang做的一个Memcached,Redis和Tokyo Tyrant的简单的性能评测,仅供参考
3、Flare
TC是日本第一大SNS网站mixi开发的,而Flare是日本第二大SNS网站green.jp开发的,有意思吧。Flare简单的说就是给TC添加了scale功能。他替换掉了TT部分,自己另外给TC写了网络服务器,Flare的主要特点就是支持scale能力,他在网络服务端之前添加了一个node server,来管理后端的多个服务器节点,因此可以动态添加数据库服务节点,删除服务器节点,也支持failover。如果你的使用场景必须要让TC可以scale,那么可以考虑flare。
flare唯一的缺点就是他只支持memcached协议,因此当你使用flare的时候,就不能使用TC的table数据结构了,只能使用TC的key-value数据结构存储。
二、满足海量存储需求和访问的面向文档的数据库:MongoDB,CouchDB
面向文档的非关系数据库主要解决的问题不是高性能的并发读写,而是保证海量数据存储的同时,具有良好的查询性能。MongoDB是用C++开发的,而CouchDB则是Erlang开发的:
1、MongoDB
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
Mongo主要解决的是海量数据的访问效率问题,根据官方的文档,当数据量达到50GB以上的时候,Mongo的数据库访问速度是MySQL的10倍以上。Mongo的并发读写效率不是特别出色,根据官方提供的性能测试表明,大约每秒可以处理0.5万-1.5次读写请求。
因为Mongo主要是支持海量数据存储的,所以Mongo还自带了一个出色的分布式文件系统GridFS,可以支持海量的数据存储,但我也看到有些评论认为GridFS性能不佳,这一点还是有待亲自做点测试来验证了。
最后由于Mongo可以支持复杂的数据结构,而且带有强大的数据查询功能,因此非常受到欢迎,很多项目都考虑用MongoDB来替代MySQL来实现不是特别复杂的Web应用,比方说why we migrated from MySQL to MongoDB就是一个真实的从MySQL迁移到MongoDB的案例,由于数据量实在太大,所以迁移到了Mongo上面,数据查询的速度得到了非常显著的提升。
MongoDB也有一个ruby的项目MongoMapper,是模仿Merb的DataMapper编写的MongoDB的接口,使用起来非常简单,几乎和DataMapper一模一样,功能非常强大易用。
2、CouchDB
CouchDB现在是一个非常有名气的项目,似乎不用多介绍了。但是我却对CouchDB没有什么兴趣,主要是因为CouchDB仅仅提供了基于HTTP REST的接口,因此CouchDB单纯从并发读写性能来说,是非常糟糕的,这让我立刻抛弃了对CouchDB的兴趣。
三、满足高可扩展性和可用性的面向分布式计算的数据库:Cassandra,Voldemort
面向scale能力的数据库其实主要解决的问题领域和上述两类数据库还不太一样,它首先必须是一个分布式的数据库系统,由分布在不同节点上面的数据库共同构成一个数据库服务系统,并且根据这种分布式架构来提供online的,具有弹性的可扩展能力,例如可以不停机的添加更多数据节点,删除数据节点等等。因此像Cassandra常常被看成是一个开源版本的Google BigTable的替代品。Cassandra和Voldemort都是用Java开发的:
1、Cassandra
Cassandra项目是Facebook在2008年开源出来的,随后Facebook自己使用Cassandra的另外一个不开源的分支,而开源出来的Cassandra主要被Amazon的Dynamite团队来维护,并且Cassandra被认为是Dynamite2.0版本。目前除了Facebook之外,twitter和digg.com都在使用Cassandra。
Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra的一个写操作,会被复制到其他节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能是比较简单的事情,只管在群集里面添加节点就可以了。我看到有文章说Facebook的Cassandra群集有超过100台服务器构成的数据库群集。
Cassandra也支持比较丰富的数据结构和功能强大的查询语言,和MongoDB比较类似,查询功能比MongoDB稍弱一些,twitter的平台架构部门领导Evan Weaver写了一篇文章介绍Cassandra:http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/,有非常详细的介绍。
Cassandra以单个节点来衡量,其节点的并发读写性能不是特别好,有文章说评测下来Cassandra每秒大约不到1万次读写请求,我也看到一些对这个问题进行质疑的评论,但是评价Cassandra单个节点的性能是没有意义的,真实的分布式数据库访问系统必然是n多个节点构成的系统,其并发性能取决于整个系统的节点数量,路由效率,而不仅仅是单节点的并发负载能力。
2、Voldemort
Voldemort是个和Cassandra类似的面向解决scale问题的分布式数据库系统,Cassandra来自于Facebook这个SNS网站,而Voldemort则来自于Linkedin这个SNS网站。说起来SNS网站为我们贡献了n多的NoSQL数据库,例如Cassandar,Voldemort,Tokyo Cabinet,Flare等等。Voldemort的资料不是很多,因此我没有特别仔细去钻研,Voldemort官方给出Voldemort的并发读写性能也很不错,每秒超过了1.5万次读写。
从Facebook开发Cassandra,Linkedin开发Voldemort,我们也可以大致看出国外大型SNS网站对于分布式数据库,特别是对数据库的scale能力方面的需求是多么殷切。前面提到,web应用的架构当中,web层和app层相对来说都很容易横向扩展,唯有数据库是单点的,极难scale,现在Facebook和Linkedin在非关系型数据库的分布式方面探索了一条很好的方向,这也是为什么现在Cassandra这么热门的主要原因。
<?php
/*
* 每5分钟自动刷新58同城网火车票交易信息,可显示电话号码,可发短信到手机
* 作者博客:http://blog.guangla.com
* 演示地址:http://apps.guangla.com/huoche
* */
function getfile($url){
if (function_exists(‘curl_init’)) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, ‘Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB5′);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl,CURLOPT_REFERER,$url);
$tmpInfo = curl_exec($curl);
curl_close($curl);
if(FALSE !== stristr($tmpInfo,”HTTP/1.1 200 OK”)){ //正确返回数据
return $tmpInfo;
}else{
return $tmpInfo;
//return file_get_contents($url);
}
}else{
return file_get_contents($url);
}
}
$myphone = “”;//手机号
$mypass = “”; //飞信密码
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : “list”;
if(“list” == $action){
$startstation = isset($_REQUEST['startstation']) ? $_REQUEST['startstation'] : “北京”; //始发站
$endstation = isset($_REQUEST['endstation']) ? $_REQUEST['endstation'] :”南昌”; //到达站
$time =isset($_REQUEST['time']) ? intval($_REQUEST['time']) :5; //始发日期
$url = “http://bj.ganji.com/piao/zz_”.urlencode($startstation).”-”.urlencode($endstation).”/”;
$content = getfile($url);
//echo $content;
preg_match_all(‘/<dt><a href=\”(.*?)\” target=\”_blank\”>(.*?)<\/a><\/dt>/i’,$content,$out);
$count = count($out[0]);
$lasturl =”";
$html = ‘<meta HTTP-EQUIV=REFRESH CONTENT=”‘.(60*$time).’;URL=?startstation=’.urlencode($startstation).’&endstation=’.urlencode($endstation).’&action=list”><a href=”?startstation=’.urlencode($startstation).’&endstation=’.urlencode($endstation).’&action=list”>立即刷新</a> | <a href=”http://blog.guangla.com/?p=212″ target=”_blank”>程序源码</a><form action=”?” method=”get”>始发站:<input type=”text” name=”startstation”/>,终点站:<input type=”text” name=”endstation”/>;自动刷新时间<input type=”text” size=”2″ name=”time” value=”5″/>分钟<input type=”hidden” name=”action” value=”list”/><input type=”submit” value=”查询”/></form>’;
$flag = “新”;
for($i=0;$i<$count;$i++){
if($flag==”新” && isset($_COOKIE['ganji_lasturl']) && $_COOKIE['ganji_lasturl'] == $out[1][$i]){
$flag = “”;
}
if(“” == $lasturl){
$lasturl = $out[1][$i];
setcookie(“ganji_lasturl”,$lasturl,(time()+3600));
}
$content = ‘<p>(‘.$flag.’)’.$out[2][$i].’ , <a href=”http://bj.ganji.com’.$out[1][$i].’” target=”_blank”>查看详情</a> 电话:<iframe style=border:0px;” scrolling=”no” width=”160″ height=”30″ src=”?action=phone&url=’.urlencode($out[1][$i]).’”></iframe></p>’;
if(“新” == $flag){
//发短信功能,开启请去掉注释
//getfile(“http://apps.guangla.com/fetion/fetion.php?username=”.$myphone.”&password=”.$mypass.”&sendto=”.$myphone.”&message=”.strip_tags($content));
}
$html .= $content;
}
header(“Content-type: text/html; charset=utf-8″);
echo $html;
}elseif(“phone” == $action){
$content = getfile(urldecode(“http://bj.ganji.com”.$_REQUEST['url']));
preg_match(‘/<dd class=\”phoneNum\”>(.*?)<\/dd>/i’,$content,$out);
if($out[1]){
echo ‘<body style=”padding:0px;margin:0px;”>’.str_replace(“/tel”,”http://bj.ganji.com/tel”,$out[1]).’</body>’;
}
}elseif(“getpic” == $action){
echo getfile(urldecode($_REQUEST['url']));
}else{
echo ‘<form action=”?” method=”get”>始发站:<input type=”text” name=”startstation”/>,终点站:<input type=”text” name=”endstation”/><input type=”hidden” name=”action” value=”list”/><input type=”submit” value=”查询”/></form>’;
}
<?php
/*
* 每5分钟自动刷新58同城网火车票交易信息,可显示电话号码,可发短信到手机
* 作者博客:http://blog.guangla.com
* 演示地址:http://apps.guangla.com/huoche
* */
function getfile($url){
if (function_exists(‘curl_init’)) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, ‘Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB5′);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl,CURLOPT_REFERER,$url);
$tmpInfo = curl_exec($curl);
curl_close($curl);
if(FALSE !== stristr($tmpInfo,”HTTP/1.1 200 OK”)){ //正确返回数据
return $tmpInfo;
}else{
return $tmpInfo;
//return file_get_contents($url);
}
}else{
return file_get_contents($url);
}
}
$myphone = “”;//手机号
$mypass = “”; //飞信密码
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : “list”;
if(“list” == $action){
$startstation = isset($_REQUEST['startstation']) ? $_REQUEST['startstation'] : “北京”; //始发站
$endstation = isset($_REQUEST['endstation']) ? $_REQUEST['endstation'] :”南昌”; //到达站
$time =isset($_REQUEST['time']) ? intval($_REQUEST['time']) :5; //始发日期
$url = “http://bj.58.com/huochepiao/a1/?StartStation=”.urlencode($startstation).”&EndStation=”.urlencode($endstation).”&StartTime=”.$starttime;
$content = getfile($url);
//echo $content;
preg_match_all(‘/<td class=\”t\” style=\”padding:0 0 0 5px;\”><a href=\”(.*?)\” target=\”_blank\” class=\”t\”>(.*?)<\/a>(.*?)<\/td>/i’,$content,$out);
$count = count($out[0]);
$lasturl =”";
$html = ‘<meta HTTP-EQUIV=REFRESH CONTENT=”‘.(60*$time).’;URL=?startstation=’.urlencode($startstation).’&endstation=’.urlencode($endstation).’&action=list”><a href=”?startstation=’.urlencode($startstation).’&endstation=’.urlencode($endstation).’&action=list”>立即刷新</a><form action=”?” method=”get”>始发站:<input type=”text” name=”startstation”/>,终点站:<input type=”text” name=”endstation”/>;自动刷新时间<input type=”text” size=”2″ name=”time” value=”5″/>分钟<input type=”hidden” name=”action” value=”list”/><input type=”submit” value=”查询”/></form>’;
$flag = “新”;
for($i=0;$i<$count;$i++){
if($flag==”新” && isset($_COOKIE['lasturl']) && $_COOKIE['lasturl'] == $out[1][$i]){
$flag = “”;
}
if(“” == $lasturl){
$lasturl = $out[1][$i];
setcookie(“lasturl”,$lasturl,(time()+3600));
}
$content = ‘<p>(‘.$flag.’)’.$out[2][$i].’ (票主所在地:’.strip_tags($out[3][$i]).’), <a href=”‘.$out[1][$i].’” target=”_blank”>查看详情</a> 电话:<iframe scrolling=”no” width=”160″ height=”30″ src=”?action=phone&url=’.urlencode($out[1][$i]).’”></iframe></p>’;
if(“新” == $flag){
//发短信功能,开启请去掉注释
//getfile(“http://apps.guangla.com/fetion/fetion.php?username=”.$myphone.”&password=”.$mypass.”&sendto=”.$myphone.”&message=”.strip_tags($content));
}
$html .= $content;
}
header(“Content-type: text/html; charset=utf-8″);
echo $html;
}elseif(“phone” == $action){
$content = getfile(urldecode($_REQUEST['url']));
preg_match(‘/<img src=\’http:\/\/image.58.com\/showphone\.aspx(.*?)\’ \/>/i’,$content,$out);
if($out[1]){
echo ‘<body style=”padding:0px;margin:0px;”><img src=\’?action=getpic&url=’.urlencode(‘http://image.58.com/showphone.aspx’.$out[1]).’\'/></body>’;
}else{
preg_match(‘/<td class=\”t\”>联系电话:<\/td><td class=\”phone\”><span>(.*?)<\/span>(.*?)<\/td><\/tr>/i’,$content,$out);
if($out[1]){
echo ‘<body style=”padding:0px;margin:0px;”>’.$out[1].’</body>’;
}
}
}elseif(“getpic” == $action){
echo getfile(urldecode($_REQUEST['url']));
}else{
echo ‘<form action=”?” method=”get”>始发站:<input type=”text” name=”startstation”/>,终点站:<input type=”text” name=”endstation”/><input type=”hidden” name=”action” value=”list”/><input type=”submit” value=”查询”/></form>’;
}
血的教训,在一台应用服务器上做单机mysql主从,原以为效果会好些,耐扛些。
结果,同步延的非常,后来还是老老实实用一个mysql,做了些优化。稳定的运行了。
(附:pv200万左右,mysql每小时200万左右的query,内存2G,双核2G普通cpu)
铁路售票处实习记完整篇—多以京始发列车为例(可当做购票指南来参考)
关于放票时间
我们可能只知道“提前10天售火车票”这个信息,也就是说,火车票只在开车前10天放一次票。事实上远非如此。我把目前观察到的放票时间在这里列给大家:
1.提前20天晚上19:00,放20天后的动车组车票和Z字头车票。这个时间,一般不会有什么人抢动车组车票(毕竟动车组不会很抢手)。但一些重点线路(客流量大,车少,车次时间合适)的Z车车票在这个时间已经会被包走相当可观的数量。比如Z37,Z77
,这两次车是发往武昌、汉口的直达车,夕发朝至,并且挂许多节硬卧车厢,湖北客流量一向较大,所以这两次车的硬卧提前20天就会被包走三分之一 (在单位和票贩子手里)。剩余的留在网上,当出行高峰来临时(比如暑运),在开车前15天左右就会被全部卖光(这也就是为什么提前“很多”天依然买不到Z 车硬卧票的原因)。
2.提前18天早晨8:00,放18天后的动车异地票以及一小部分Z车异地票。但多是跨局列车票,比如沈阳北-太原D191的动车票[跨沈京两 局];管内[一个铁路局之内]的动车票不一定这个时候放,比如济南-青岛的D6001,提前18天有时能在北京买到,有时就买不到。至于具体什么时候放, 要看车次所在铁路局的政策。
3.提前12天早晨8:00,放12天后的D[管内部分]、Z车异地票。因为铁路是计划运输,每列车几乎都会给出一些全国范围的“共享票额”,也 就是这些票额只供始发站之外的全国各站用,始发站不可以用。这样,比如提前12天的时候,在天津买不到Z41到上海的票,可是这时候在北京(甚至在某些边 远的站,如西宁),还是可以调用全国共享票额打出来票。返程票也是同样道理。比如提前12天就可以买12天后的南昌-北京西Z68,但得到的多是上铺。
4.提前10天晚上19:00,放10天后的T、K和普通列车始发票。这是极其重要的放票黄金时间!! 基本上除了T17、T47、T69、T41这样的极紧张车次之外,绝大多数车都可以在这个时间打出票来。我们所谓的“提前10天排队买票去”,说的就是在 这个时间去窗口趴票。不过晚七点一到,马上前几手票都必定是票贩子的。运气好的排在前面的乘客,可能会在19:15分左右(当然是在票贩子和熟人的票基本 搞定之后)抢到几张剩余的自己需要的票(往往是硬卧上铺等残羹冷炙……)。
5.提前10天晚上19:20~20:00,这是“捡票”时间。有那些七点时被别人抢走,挂上了,但最终没出票,又放回票池的那些票,这个时候还 有希望被重新抢回来。不要以为这个时候来算是来晚了,尤其是要买那些相对偏僻地区车次的旅客,这个时候很有可能再捡回几张“漏儿”。比如我曾亲自在 19:35分的时候捡到两张2189到乌兰浩特的硬卧(京通线和白阿线的时间合适的始发空调车,卧铺相当难买)。为什么会捡到?因为去这些地方虽然票紧, 但毕竟去的人不是很多,所以票贩子很有可能抢到手之后再把票放回来(毕竟他们的行动是取决于购票人需求的)。
6.提前9天早晨8:00,放9天后的T、K和普通列车异地票。这个时候可以随意打全国任意车次的票,而且不用抢,因为买异地票的旅客现在还不算 多。加上早晨代售点不忙,因此这个时候是买异地票的最佳时机。不过不一定每辆车每种席位都有给全国公用的预留票额,比如我曾在第一时间看到T197郑州- 乌鲁木齐的车只给异地留硬卧和软卧,想买硬座是买不到的。
7.提前3天晚上20:00,这是第二个黄金时间。这时车站会把给各大旅行社和各部委的预留票没有卖出去的部分放出来。一般而言,每趟始发车这时 候都会有机会抢到票,但往往只放出来15张左右,而且还建立在这样一个前提之上——预留票没有被公家买走用掉。如果那次车恰好被公家包走,那么这时候抢也 是白抢,就比如T41这类车,内部已经都把预留票买走了,因为不剩,所以就不放出来。
8.提前1天中午12:00,这是第三个黄金时间。这时候车站会把给铁路系统内部预留的票(给路局以及相关部门)没有用的剩余部分放出来。和提前 3天抢票类似,如果没能有剩余的,那么也就不会放出来。一般而言,这个时候抢票抢到的几率相对大些(当然只是相对的,和提前10天第一时间抢票抢到的份额 显然不是一个数量级),因为铁路内部并没有那么多人要出去。
9.提前1天下午17:00,放某些特定车次的加挂车厢。铁路部门会统计和分析每天各线路的客流情况,在一些线路的重点列车上加挂1-2节硬座或 硬卧车厢。比较容易放加挂的车是湘鄂赣桂等地区,比如T5、T189、Z37等车,如果加挂了,那么就意味着有100多张票放出来,这个时候抢票会抢到大 份额。但问题是放不放加挂,哪辆车放加挂,哪天放记挂,这是没有固定规律的,如果能够探听到铁路部门的内部消息当然最好,如果完全不知道,就只能靠经验推 断(比如 T5 Z59 T189等都是放过加挂的车,尤其T5是经常放加挂的车),这时候到了五点死蹲这些车次,就能弄出来票。
10.提前1天下午18:00,放车站“窗口票”“抽屉票”。车站有时会把自己提前打出来的票之中的剩余部分在这个时候放到网上去,还有就是把窗口的退票(平时没有时间放到网上去或是故意留着给内部认识人)统一放回去。再有就是12:00没有放完的
部分(有时领导中午决定不了第二天走不走,如果这时候决定了不走,就会把预留票放出来)。但总之这个时候抢到票的概率比较小。
11.提前1天凌晨0:00。这个时间是最绝的,往往在高峰期才会在这个时候放“死票”(又叫“机动预留票”,这种票在网上能查到有多少张,但就是打不出来,是车站不给。和前文所述“预留票”不同,预留票究竟有多少完全是暗箱操作,售票网上根本
查不出来)(也就是没有被任何人订走,但被车站提前锁定的那些‘机动票’,比如Z29等车常常被锁住的硬卧票[上中下各30张左右])。这些票的 具体用途,车站也说不很清楚,只是希望票别都散出去买的那么快,万一内部或是机关部门有个什么临时安排需要出行,而内部预留票又不够的时候,再动用这些 票。如果这些票在开车前一天晚上还是没有人要,那么就在零点放出去。
12.开车前24小时,打破“区段限售”,也称“松绑”。比如T7在预售期内给石家庄、郑州各预留20张座位(这些座位只卖给去石家庄、郑州的乘 客,去郑州以远的乘客不能买),但这些预留座位如果没有卖光,那么在开车前24小时的时候这些票就会变成不限售的公用票(也就是说这些座票也可以卖给去成 都等地的乘客了)。松绑相当于一次放票。
13.开车前4个半小时,每辆车各放出最后六张“底牌”。这些“底牌”往往是站长手里攥着的特批票,如果没有用,就会在开车前4个半小时放到网上去。这也就是为什么有时临走前直接去车站买票还会很幸运地买到十天前都抢不到的票的原因。
今天,Google在英文的官方博客声称,Google已经做出决定,重新检讨在中国开展业务的可行性,如有必要,可能会关闭Google.cn,并撤出在中国的办事处。
Google称其业务系统遭受到来自中国有针对性的攻击,导致知识产品被盗,Google在2006年进入中国,是为了让中国人能够在更加开放的互联网 中获取信息,基于这种理念,Google可以容忍部分审查,但Google会密切注视中国新的法律对Google服务的限制情况,现在Google已经确 认,Google已经到了重新考虑评估中国业务运营可行性的时候了。
在过去的一年里,对于互联网言论自由的限制已经完全突破了 Google的底线,其在中国的运营一直不顺利,先后经历了牌照门,偷税门,搜狗门,涉黄门等一系列波折。谷歌大中华区总裁李开复也于去年宣布离职。Google公司已经决定,不愿再审查Google.cn上的搜索结果,因此,如果可能,Google将在未来几周时间和中国政府谈 判,要求能够在中国法律框架内运营未经过滤审查的搜索引擎。Google承认这很可能意味着必须关闭Google.cn,撤出Google在中国的办公 室。
看来,中国的互联网环境之恶劣,连国际互联网巨头Google都无法忍受了,Google的这个决定首次对中国的互联网政策说了声 “不”。如果未来Google真的撤出中国,不仅仅Google会损失掉中国的业务,中国自身的经济发展也会受到冲击,国际形象会有负面影响,对于广大依 靠Google AdSense业务生存的个人网站来说也是致命一击,中国的个人网站可能真的要走向灭亡了。
而事实上,对于谷歌考虑退出中国的消息已经在业内传过多次。最近的一次是,资深互联网人士胡延平去年10月份在新浪微博上透露,谷歌将撤走中国境内的全部服务器。不过,谷歌中国公关负责人对此事予以否认。
对于谷歌考虑退出中国,业内人士几乎一致认为不太可能。
互联网资深人士方兴东接受媒体采访时表示,中国是全球最大的市场,谷歌在中国有很多业务,每年也有数亿元的收入,中国市场对于谷歌未来的发展有战略性意义。“从理性的角度看,谷歌不太可能退出中国”。
电信产业咨询公司Frost & Sullivan中国首席咨询顾问王煜全表示,“谷歌不太可能完全撤出中国市场,即使中国在谷歌全球的市场份额并不高,但完全撤出甚至关闭中国的办事处并不理智。”
本人工作环境:ubuntu9.10 + php5.1
一:安装 mongodb
1. 获取mongodb
sudo wget http://downloads.mongodb.org/linux/mongodb-linux-i686-latest.tgz
2. 解压
tar xzf mongodb-linux-i386-latest.tgz
3. 创建数据库目录
mkdir -p /home/shenzhe/mongodb
4. 运行
bin/mongod run –dbpath=/home/shenzhe/mongodb &
5. 使用自带客户端连接
bin/mongo
6. 测试
db.foo.save( { a : 1 } )
db.foo.findOne()
二:php添加mongo扩展
1. 安装扩展
sudo pecl install mongo
2. 加入到php.ini
把extension=mongo.so加入到php.ini重启 apache
三:运行测试
建立一个php文档,输入
<?php
// connect
$m = new Mongo();
// select a database
$db = $m->comedy;
$collection = $db->cartoons;
// find everything in the collection
$cursor = $collection->find();
// iterate through the results
foreach ($cursor as $obj) {
print_r($obj);
echo $obj["title"] . “\n”;
}
// disconnect
$m->close();
运行,查看效果
mongo官网 && 参考文档 http://www.mongodb.org/display/DOCS/Installing+the+PHP+Driver
今天在安装 wine和jdk时,都报错了,发现是ttf-mscorefonts-installer安装不了
替代方法
wget -c http://dl.getdropbox.com/u/313781/ttf-mscorefonts-installer_3.1_all.deb
sudo dpkg -i ttf-mscorefonts-installer_3.1_all.deb