你也许认为这是NoSQL (Not Only SQL)广告宣传的另一个博客。
是,这的确是。
但是如果这个时候你仍就为寻找一个可行的NoSQL解决方案而苦恼,读完这篇后你就知道该做什么了。
当我以前参与Perfect Market的内容处理平台时,我拼命地尝试寻找一个极端快速(从延时和处理时间上)和可扩展的NoSQL数据库方案,去支持简单地键/值查询。
在开始前我预定义了需求:
- 快速数据插入(Fast data insertion)。有些数据集可能包含上亿的行(KV键值对),虽然每行数据很小,但如果数据插入很慢,那将这个数据集传入数据库将需要花几天时间,这是不可接受的。
- 大数据集上的快速随机读取(Extermely fast random reads on large datesets)。
- 在所有数据集上的一致的读写速度。这个意思是说,读写速度不能因为数据如何保持和index如何组织就在某个数据量上拥有很好的值,读写速度应该在所有的数据量上均衡。
- 有效的数据存储。原始的数据大小和数据被导入数据库中的大小应该相差不大。
- 很好的扩展性。我们在EC2的内容处理节点可能产生大量的并发线程访问数据节点,这需要数据节点能很好的扩展。同时,不是所有的数据集是只读的,某些数据节点必须在合适的写负载下很好的扩展。
- 容易维护。我们的内容处理平台利用了本地和EC2资源。在不同的环境里,同时打包代码,设置数据,和运行不同类型的节点是不容易的。预期的方案必须很容易维护,以便满足高自动化的内容处理系统。
- 拥有网络接口。只用于库文件的方案是不充足的。
- 稳定。必须的。
我开始寻找时毫无偏见,因为我从未严格地使用过NoSQL产品。经过同事的推荐,并且阅读了一堆的博客后,验证的旅程开始于Tokyo Cabinet,然后是 Berkeley DB库, MemcacheDB, Project Voldemort, Redis,MongoDB。
其实还存在很多流行的可选项,比如Cassandra, HBase, CouchDB…还有很多你能列出来的,但我们没没有必要去尝试,因为我们选择的那些已经工作得很好。结果出来相当的不错,这个博客共享了我测试的一些细节。
为了解释选择了哪个以及为什么选择这个,我采纳了同事Jay Budzik(CTO)的建议,创建了一张表来比较所有方案在每一个需求上的情况。虽然这张表是一个事后的事情,但它展示了基本原理,同时也会对处于决策的人们带来帮助。
请注意这个表不是100%的客观和科学。它结合了测试结果和我的直觉推导。很有趣,我开始验证时没有偏见,但测试完所有的后,我也许有了一点偏心(特别是基于我的测试用例)。
另一个需要注意的是这里的磁盘访问是I/O密集性工作负载里最慢的一个操作。相对于内存访问, 这是毫秒与纳秒的关系。为了处理包含上亿行的数据集合,你最好给你的机器配置足够的内存。如果你的机器只有4G内存而你想处理50GB的数据且期望较好的速度,那你要么摇晃你的机器,要么用个更好的,否则只能扔到下面所有的方案,因为它们都不会工作。

看了这张表,你也许能猜到我选了哪个方案。不要着急,让我详细说明每一个方案。
Tokyo Cabinet (TC)是一个非常好的方案也是我第一个验证的。我现在仍然很喜欢它,虽然这不是我最后选择的。它的质量惊人的高。哈希表数据库对于小数据集(低于2千万行)惊人的快,水平扩展能力也很好。TC的问题是当数据量增加时,读写的性能下降的特别快。
Berkeley DB(BDB)和MemcacheDB (BDB的远程接口)是一个较老的结合物。如果你熟悉BDB,并且不是非常依赖速度和功能集合,比如你愿意等几天去加载大数据集到数据库里并且你接受一般但不优秀的读速度,你仍可以使用它。对于我们,事实是它花了太长的时间来加载初始数据。
Project Voldemort是唯一一个基于Java和云计算的方案。在验证前我有很高的期望,但是结果却有点失望,原因是:
- BDB Java版本让我的数据膨胀得太厉害(大概是1比4,而TC只有1比1.3)。基本上存储效率非常低。对于大数据集,它就是灾难。
- 当数据变得很大的时候,插入速度降低得很快。
- 当大数据集被加载时偶尔由于无法预测的异常而崩溃。
当数据膨胀得太厉害并且偶尔系统崩溃时,数据加载还没有完成。只有四分之一的数据被传播,它读速度还可以但不出色。在这个时候我想我最好放弃它。否则,除了上面列的那些需要优化,JVM可能让我操更多的心让我的头发灰的更多,虽然我已经为Sun工作了五年。
Redis是一个极好的缓存解决方案,我们也采用了它。Redis将所有的哈希表存在内存里,背后有一个线程按照预设的时间定时将哈希表中的快照存到磁盘上。如果系统重启,它可以从磁盘上加载快照到内存,就像启动时保温的缓存。它要花几分钟来恢复20GB的数据,当然也依赖你的磁盘速度。这是一个非常好的主意,Redis有一个合适的实现。
但是在我们的用例里,它工作得并不好。后台的保存程序仍妨碍了我们,特别是当哈希表变得更大时。我担心它会负面地影响读速度。使用logging style persistence而不是保存整个快照,可以减缓这些数据转存的影响,但是数据大小将会膨胀,如果太频繁,将最终影响恢复时间。单线程模式听起来不是可伸缩的,虽然在我的测试里它水平方向扩展的很好:支持几百个并发读。
另一个事情干扰我的是Redis的整个数据集必须适合物理内存。这点使得它不容易被管理,象在我们这样在不同的产品周期造成的多样化的环境里。Redis最近的版本可能减轻了这方面的问题。
MongoDB是至今我最喜欢的,在我所验证的所有解决方案中,它是胜出者,我们的产品也正在使用。
MongoDB提供了不同寻常的插入速度,可能原因是延迟写入和快速文件扩展(每个集合结构有多个文件)。只要你拥有足够的内存,上亿的数据行能在几小时内插入,而不是几天。我应该在这提供确切的数据,但数据太具体(与我们的项目有关)不见得对别人有帮助。但相信我,MongoDB提供了非常快的大数据量插入操作。
MongoDB使用内存映射文件,它一般花纳秒级的时间来解决微小的页面错误,让文件系统缓存的页面映射到MongoDB的内存空间。相比于其它方案,MongoDB不会和页面缓存竞争,因为它使用和只读块相同的内存。在其它方案里,如果你分配给太多的内存给工具自身,那盒子里的页面缓存就变得很少,并且一般来说想让工具的缓存完全地预热不是很容易,或者没有一个有效地方法(你绝对不想事先去从数据库里读取每一行)。
对于MongoDB,可以非常容易地做一些简单的技巧让所有的数据加载到页面缓存。一旦在这个状态,MongoDB就很像Redis,在随机读上有较好的性能。
在我另一个测试中,200并发客户在大数据集(上亿行数据)做持续的随机读取,MongoDB表现了总体上的400,000QPS。测试中,数据在页面缓存里预热(事先加载)。在随后的测试中,MongoDB同样显示了在适度的写负载下拥有非常好的随机读取速度。在相对来说一个大的负载下,我们压缩了数据然后将它存入MongoDB,这样就减少了数据大小所以更多的东西能放入内存。
MongoDB提供了一个方便的客户端工具(类似MySQL的),非常好用。它也提供了高级的查询功能,处理大型文档的功能,但是我们还没有用到这些。MongoDB非常稳定,基本不需要维护,处理你可能要监控数据量增大时的内存使用情况。MongoDB对不同的语言有很好的客户端API支持,这使得它很容易使用。我不用列举它所有的功能,但我想你会得到你想要的。
虽然MongoDB方案可以满足大多数NoSQL的需求,但它不是唯一的一个。如果你只需要处理小数据量,Tokyo Cabinet最合适。如果你需要处理海量数据(PB千兆兆)并拥有很多机器,而且延时不是个问题,你也不强求极好的响应时间,那么Cassandra和HBase都可以胜任。
最后,如果你仍需要考虑事务处理,那就不要弄NoSQL, 直接用Oracle。
引自 Jun Xu of http://perfectmarket.com/blog/not_only_nosql_review_solution_evaluation_guide_chart
posted @ 2011-12-02 19:27 Sail 阅读(18) 评论(0)
编辑
(转http://www.jb51.net/article/25093.htm)
第一种模式:工厂方式
复制代码 代码如下:
var lev=function(){
return "脚本之家";
};
function Parent(){
var Child = new Object();
Child.name="脚本";
Child.age="4";
Child.lev=lev;
return Child;
};
var x = Parent();
alert(x.name);
alert(x.lev());
说明:
1.在函数中定义对象,并定义对象的各种属性,,虽然属性可以为方法,但是建议将属性为方法的属性定义到函数之外,这样可以避免重复创建该方法
2.引用该对象的时候,这里使用的是 var x = Parent()而不是 var x = new Parent();因为后者会可能出现很多问题(前者也成为工厂经典方式,后者称之为混合工厂方式),不推荐使用new的方式使用该对象
3.在函数的最后返回该对象
4.不推荐使用这种方式创建对象,但应该了解
第二种模式:构造函数方式
复制代码 代码如下:
var lev=function(){
return "脚本之家";
};
function Parent(){
this.name="脚本";
this.age="30";
this.lev=lev;
};
var x =new Parent();
alert(x.name);
alert(x.lev());
说明:
1.与工厂方式相比,使用构造函数方式创建对象,无需再函数内部重建创建对象,而使用this指代,并而函数无需明确return
2.同工厂模式一样,虽然属性的值可以为方法,扔建议将该方法定义在函数之外
3..同样的,不推荐使用这种方式创建对象,但仍需要了解
第三种模式:原型模式
复制代码 代码如下:
var lev=function(){
return "脚本之家";
};
function Parent(){
};
Parent.prototype.name="李小龙";
Parent.prototype.age="30";
Parent.prototype.lev=lev;
var x =new Parent();
alert(x.name);
alert(x.lev());
说明:
1.函数中不对属性进行定义
2.利用prototype属性对属性进行定义
3.同样的,不推荐使用这样方式创建对象
第四种模式:混合的构造函数,原型方式(推荐)
复制代码 代码如下:
function Parent(){
this.name="脚本";
this.age=4;
};
Parent.prototype.lev=function(){
return this.name;
};;
var x =new Parent();
alert(x.lev());
说明:1.该模式是指混合搭配使用构造函数方式和原型方式
2.将所有属性不是方法的属性定义在函数中(构造函数方式)
将所有属性值为方法的属性利用prototype在函数之外定义(原型方式)
3.推荐使用这样方式创建对象,这样做有好处和为什么不单独使用构造函数方式和原型方式,由于篇幅问题这里不予讨论
第五种模式:动态原型方式
复制代码 代码如下:
function Parent(){
this.name="脚本";
this.age=4;
if(typeof Parent._lev=="undefined"){
Parent.prototype.lev=function(){
return this.name;
}
Parent._lev=true;
}
};
var x =new Parent();
alert(x.lev());
说明:
1.动态原型方式可以理解为混合构造函数,原型方式的一个特例
2.该模式中,属性为方法的属性直接在函数中进行了定义,但是因为
复制代码 代码如下:
if(typeof Parent._lev=="undefined"){
Parent._lev=true;}
从而保证创建该对象的实例时,属性的方法不会被重复创建
3.,推荐使用这种模式
详细出处参考:http://www.jb51.net/article/25093.htm
posted @ 2011-11-26 21:02 Sail 阅读(3) 评论(0)
编辑
关于获取各种浏览器可见窗口大小的一点点研究。
在我本地测试当中:
在IE、FireFox、Opera下都可以使用
document.body.clientWidth
document.body.clientHeight
即可获得,很简单,很方便。
而在公司项目当中:
Opera仍然使用
document.body.clientWidth
document.body.clientHeight
可是IE和FireFox则使用
document.documentElement.clientWidth
document.documentElement.clientHeight
原来是W3C的标准在作怪啊 http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 如果在页面中添加这行标记的话
在IE中:
document.body.clientWidth ==> BODY对象宽度
document.body.clientHeight ==> BODY对象高度
document.documentElement.clientWidth ==> 可见区域宽度
document.documentElement.clientHeight ==> 可见区域高度
在FireFox中:
document.body.clientWidth ==> BODY对象宽度
document.body.clientHeight ==> BODY对象高度
document.documentElement.clientWidth ==> 可见区域宽度
document.documentElement.clientHeight ==> 可见区域高度 ?
在Opera中:
document.body.clientWidth ==> 可见区域宽度
document.body.clientHeight ==> 可见区域高度
document.documentElement.clientWidth ==> 页面对象宽度(即BODY对象宽度加上Margin宽)
document.documentElement.clientHeight ==> 页面对象高度(即BODY对象高度加上Margin高)
而如果没有定义W3C的标准,则 IE为:
document.documentElement.clientWidth ==> 0
document.documentElement.clientHeight ==> 0
FireFox为:
document.documentElement.clientWidth ==> 页面对象宽度(即BODY对象宽度加上Margin宽)
document.documentElement.clientHeight ==> 页面对象高度(即BODY对象高度加上Margin高)
Opera为:
document.documentElement.clientWidth ==> 页面对象宽度(即BODY对象宽度加上Margin宽)
document.documentElement.clientHeight ==> 页面对象高度(即BODY对象高度加上Margin高)
真是一件麻烦事情,其实就开发来看,宁可少一些对象和方法,不使用最新的标准要方便许多啊。
posted @ 2011-11-22 13:35 Sail 阅读(4) 评论(0)
编辑
来源:cnblogs.com/cx361
作为Web开发中应用最广泛的语言之一,PHP有着大量的粉丝,那么你是一名优秀的程序员吗?在进行自我修炼的同时,你是否想过面对各种各样的问题,我该如何突破自身的瓶颈,以便更好的发展呢? PHP工程师面临成...
作为Web开发中应用最广泛的语言之一,PHP有着大量的粉丝,那么你是一名优秀的程序员吗?在进行自我修炼的同时,你是否想过面对各种各样的问题,我该如何突破自身的瓶颈,以便更好的发展呢?
PHP工程师面临成长瓶颈
先明确这里所指的PHP工程师,是指主要以PHP进行Web系统的开发,没有使用其的语言工作过。工作经验大概在3~4年,普通的Web系统(百万级访问,千成级数据以内或业务逻辑不是特别复杂)开发起基本得心应手,没有什么问题。但他们会这样的物点:
◆除了PHP不使用其它的语言,可能会点shell 脚本。
◆对PHP的掌握不精(很多PHP手册都没有看完,库除外)。
◆知识面比较窄(面对需求,除开使用PHP和mysql ,不知道其它的解决办法)。
◆PHP代码以过程为主,认为面向对象的实现太绕,看不懂。
这些PHPer在遇到需要高性能,处理高并发,大量数据的项目或业务逻辑比较复杂(系统需要解决多领域业务的问题)时,缺少思路。不能分析问题的本质,技术判断力比较差,对于问题较快能找出临时的解决办法,但常常在不断临时性的解决办法中,系统和自己一步步走向崩溃。那怎么提高自己呢?怎么可以挑战难度更高的系统?
更高的挑战在那里?
结合我自己的经验,我列出一些具体挑战,让大家先有个感性的认识。
高性能系统的挑战在那里?
◆如何选择Web服务器?要不要使用fast-cgi 模式;
◆要不要使用反向代理服务?选择全内存缓存还是硬盘缓存?
◆是否需要负载均衡?是基于应用层,还是网络层? 如何保证高可靠性?
◆你的PHP代码性能如何,使用优化工具后怎么样? 性能瓶颈在那里? 是否需要写成C的扩展?
◆用户访问有什么特点,是读多还是写多?是否需要读写分离?
◆数据如何存储?写入速度和读出速度如何? 数据增涨访问速读如何变化?
◆如何使用缓存? 怎么样考虑失效?数据的一致性怎么保证?
高复杂性系统的挑战在那里?
◆能否识别业务所对应的领域?是一个还是多个?
◆能否合理对业务进行抽象,在业务规则变化能以很小的代价实现?
◆数据的一致性、安全性可否保证?
◆是否撑握了面向对象的分析和设计的方法
这里所列出的问题,你都能肯定的回答,说明在技术上你基本已经可能成为架构师了。如何你还不能回答,你需要在以下几个方向加强。
怎么样提高,突破瓶颈
如何你还不能回答,你需要在以下几个方向加强:
◆分析你所使用的技术其原理和背后运行的机制,这样可以提高你的技术判断力,提高你技术方案选择的正确性;
◆学习大学期间重要的知识, 操作系统原理,数据结构和算法。知道你以前学习都是为了考试,但现在你需要为自己学习,让自己知其所以然;
◆重新开始学习C语言,虽然你在大学已经学过。这不仅是因为你可能需要写PHP扩展,而且还因为,在做C的应用中,有一个时刻关心性能、内存控制、变量生命周期、数据结构和算法的环境;
◆学习面向对象的分析与设计,它是解决复杂问题的有效的方法。学习抽象,它是解决复杂问题的唯一之道。
如何有效的学习是一个大问题。“以架构为中心,用例驱动,迭代开发”,借用这个思想,关于有效的学习的方法,可以这样来表述:以原理、模型或机制为中心,任务驱动,迭代学习。有点抽象,举个例子来说明如何学习。
目的: 学习如何提高处理性能。
可迭代驱动的任务: 通过IP找到所在地域。这是Web应用常见的任务,IP数据库是10左右万行的记录。
第一次迭代: 不考虑性能的情况下实现功能(通过PHP来实现)
因为无法直接通过KEY(IP)进行查找地域,所以直接放到数据或通过关联数组这种简单的方法都是不行的。思路还是先把数据进行排序,然后再进行查找:
◆如何通过IP查找?已序的数据,二分查找是最快的。
◆如何排序?用库函数sort当然是可以,但是即然是学习,那还是自己实现快速排序吧。
学习目标: 排序算法,查找算法
PHPer数据结构和算法基础比较差,平时也没有这方面的任务,自己也不学习,因此这方面的知识很缺乏。但是,编程解决的问题,最终都会归结到数据结构和对这种数据结构操作的算法。如果数据结构算法常在心中,那遇到问题就能清晰认识到它内在的结构,解决方法就会自然产生。
第二次迭代:优化数据的加载与排序
如果做到第一步,那基本上还是不可用,因为数据每次都需要的加载和排序,这样太耗时间。解决的思路是,数据一次加载排序后,放到每个PHP进程能访问到的地方。放到Memcache这是大家容易想到问题。其实放到共享内存(EA等加速器都支持)中是更快的方式,因为memcache还多了网络操作。 数据是整体放入到共享内存,还是分块放入,如何测试性能? 如何分析瓶颈所在(xdebug)? 在这些问题的驱动下你会学习到。
学习目标: 检测、定位、优化PHP性能的方法; PHP实现结构对性能的影响。
第三次迭代: 编写PHP的扩展
性能还是上不去,不得不进入C/C++的世界了,不过从此你将不只是PHPer 而服务端的全能型工程师,当然这对没有做过C/C++的同学挑战是巨大的。
学习目标:C/C++的学习,PHP扩展的编写
怎么确定需要学习的机制和原理呢? 怎么找到驱动学习任务呢?我对需要学习的东西,都没有什么概念,怎么回答以上的两个问题?从这个技术的定位来找出需要学习的重点,即它怎么做到(机制)的和它为什么能这样做到。列出这个技术最常见的应用,做为学习的任务,从简到难进行实践。
假如我需要学习JavaScript,我对于HTML,CSS有点感性认识。首要要了解的是,JavaScript是Web领域的动态语言,主要解决网页的动态交互的。那要学习的要点如下:
◆JavaScript如何与HTML进行交互 (机制)
◆JavaScript的动态特性在那里,与其它动态语言有何区别?(语言模型)
如果完全自学,找到需要学习的要点(机制、模型、原理)设定学习任务的确不是那么容易把握。如果找到一个有经验的人来指导你或加一个学习型的团队,那学习的速度的确会大大提高。
posted @ 2011-11-15 00:21 Sail 阅读(9) 评论(0)
编辑
PHP与MYSQL事务处理
/*
MYSQL的事务处理主要有两种方法。
1、用begin,rollback,commit来实现
begin 开始一个事务
rollback 事务回滚
commit 事务确认
2、直接用set来改变mysql的自动提交模式
MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过
set autocommit=0 禁止自动提交
set autocommit=1 开启自动提交
来实现事务的处理。
当你用 set autocommit=0 的时候,你以后所有的SQL都将做为事务处理,直到你用commit确认或rollback结束。
注意当你结束这个事务的同时也开启了个新的事务!按第一种方法只将当前的作为一个事务!
个人推荐使用第一种方法!
MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其他的类型是不支持的!
***:一般MYSQL数据库默认的引擎是MyISAM,这种引擎不支持事务!如果要让MYSQL支持事务,可以自己手动修改:
方法如下:1.修改c:\appserv\mysql\my.ini文件,找到skip-InnoDB,在前面加上#,后保存文件。
2.在运行中输入:services.msc,重启mysql服务。
3.到phpmyadmin中,mysql->show engines;(或执行mysql->show variables like 'have_%'; ),查看InnoDB为YES,即表示数据库支持InnoDB了。
也就说明支持事务transaction了。
4.在创建表时,就可以为Storage Engine选择InnoDB引擎了。如果是以前创建的表,可以使用mysql->alter table table_name type=InnoDB;
或 mysql->alter table table_name engine=InnoDB;来改变数据表的引擎以支持事务。
*/
/*************** transaction--1 ***************/
$conn = mysql_connect('localhost','root','root') or die ("数据连接错误!!!");
mysql_select_db('test',$conn);
mysql_query("set names 'GBK'"); //使用GBK中文编码;
//开始一个事务
mysql_query("BEGIN"); //或者mysql_query("START TRANSACTION");
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$sql2 = "INSERT INTO `user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//这条我故意写错
$res = mysql_query($sql);
$res1 = mysql_query($sql2);
if($res && $res1){
mysql_query("COMMIT");
echo '提交成功。';
}else{
mysql_query("ROLLBACK");
echo '数据回滚。';
}
mysql_query("END");
/**************** transaction--2 *******************/
/*方法二*/
mysql_query("SET AUTOCOMMIT=0"); //设置mysql不自动提交,需自行用commit语句提交
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$sql2 = "INSERT INTO `user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//这条我故意写错
$res = mysql_query($sql);
$res1 = mysql_query($sql2);
if($res && $res1){
mysql_query("COMMIT");
echo '提交成功。';
}else{
mysql_query("ROLLBACK");
echo '数据回滚。';
}
mysql_query("END"); //事务处理完时别忘记mysql_query("SET AUTOCOMMIT=1");自动提交
/******************对于不支持事务的MyISAM引擎数据库可以使用表锁定的方法:********************/
//MyISAM & InnoDB 都支持,
/*
LOCK TABLES可以锁定用于当前线程的表。如果表被其它线程锁定,则造成堵塞,直到可以获取所有锁定为止。
UNLOCK TABLES可以释放被当前线程保持的任何锁定。当线程发布另一个LOCK TABLES时,或当与服务器的连接被关闭时,所有由当前线程锁定的表被隐含地解锁。
*/
mysql_query("LOCK TABLES `user` WRITE");//锁住`user`表
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$res = mysql_query($sql);
if($res){
echo '提交成功。!';
}else{
echo '失败!';
}
mysql_query("UNLOCK TABLES");//解除锁定
posted @ 2011-11-12 12:01 Sail 阅读(26) 评论(0)
编辑
摘要: 美国数据加密标准(DES)是对称密码算法,就是加密密钥能够从解密密钥中推算出来,反过来也成立。密钥较短,加密处理简单,加解密速度快,适用于加密大量数据的场合。RSA是非对称算法,加密密钥和解密密钥是不一样的,或者说不能由其中一个密钥推导出另一个密钥。密钥尺寸大,加解密速度慢,一般用来加密少量数据,比如DES的密钥。SHA1 和 MD5 是散列算法,将任意大小的数据映射到一个较小的、固定长度的唯一值。加密性强的散列一定是不可逆的,这就意味着通过散列结果,无法推出任何部分的原始信息。任何输入信息的变化,哪怕仅一位,都将导致散列结果的明显变化,这称之为雪崩效应。散列还应该是防冲突的,即找不出具有相同
阅读全文
posted @ 2011-11-11 20:53 Sail 阅读(31) 评论(0)
编辑
摘要: 作者:薛忠胜 2005-02-01 11:25:04 来自:linuxforum.netExim是基于GPL协议的开放源代码软件,由英国剑桥大学的Philip Hazel开发,目前最新版4.24。Exim是一个MTA(Message Transfer Agent),即消息传输代理,负责邮件的路由、转发和投递。Exim被作者设计成可运行于绝大多数的类Unix系统上,包括Solaris,AIX,Linux等。 Exim与其它开源的MTA(QMail、Postfix)相比,最大的特点是配置极其灵活。Exim的配置文件也是一个文本文件,但它支持一种称为String Expansion的技术。Stri.
阅读全文
posted @ 2011-10-30 15:57 Sail 阅读(14) 评论(0)
编辑
摘要: 一、Socket 简介1、socket只不过是一个数据结构。2、使用这个socket数据结构去开始一个客户端和服务器之间的会话。3、服务器是一直在监听准备产生一个新的会话。当一个客户端连接服务器,它就打开服务器正在进行监听的一个端口进行会话。4、服务器端接受客户端的连接请求,那么就进行一次循环。现在这个客户端就能够发送信息到服务器,服务器也能发送信息给客户端。二、Socket 变量产生一个Socket,你需要三个变量:一个协议、一个socket类型和一个公共协议类型。1、协议AF_INET//产生socket的协议,使用TCP或UDP来传输,用在IPv4的地址AF_INET6//产生socke
阅读全文
posted @ 2011-05-24 19:20 Sail 阅读(197) 评论(0)
编辑
摘要: 在网站建设的实际应用中,容易出现很多小小的失误,就像mysql当初优化不到位,影响整体网站的浏览效果一样,其实,网站的常规http状态码的表现也是一样,Google无法验证网站几种解决办法,提及到由于404状态页面设置不正常,导致了google管理员工具无法验证的情况,当然,影响的不仅仅是这一方面,影响的更是网站的整体浏览效果。因此,比较清楚详细的了解http状态码的具体含义,对于一个网站站长来说,这是很有必要俱备的网站制作基础条件。 如果某项请求发送到您的服务器要求显示您网站上的某个网页(例如,用户通过浏览器访问您的网页或 Googlebot 抓取网页时),服务器将会返回 HTTP 状态码响
阅读全文
posted @ 2011-05-24 19:18 Sail 阅读(12) 评论(0)
编辑
摘要: robots.txt是一个纯文本文件,在这个文件中网站管理者可以声明该网站中不想被robots访问的部分,或者指定搜索引擎只收录指定的内容。 当一个搜索机器人(有的叫搜索蜘蛛)访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在,搜索机器人就会按照该文件中的内容来确定访问的范围;如果该文件不存在,那么搜索机器人就沿着链接抓取。 另外,robots.txt必须放置在一个站点的根目录下,而且文件名必须全部小写。 robots.txt写作语法 首先,我们来看一个robots.txt范例:http://www.csswebs.org/robots.txt 访问以上具体地址,
阅读全文
posted @ 2011-05-24 19:17 Sail 阅读(20) 评论(0)
编辑