2008年10月31日星期五

让垃圾留言远离您的网站和用户

转载自谷歌中文网站管理员博客
发表者: Jason Morrison,搜索质量组


原文: Keeping comment spam off your site and away from users

假设您已经在您的网站上开辟了一个论坛,或者在您的博客上激活了评论功能。您精心准备了一两篇帖子,点击了提交按钮,然后开始屏住呼吸等待评论的到来。

评论真的来了。您的一个博友发表了友好的评论,您参加的在线角色扮演游戏的盟友发来了新的消息,Millie阿姨发来了星期四晚上聚餐的提醒…但同时您还收到另外一些东西…一些让您头疼的东西。比如一些鼓吹得天花乱坠的广告信息,乱七八糟不知所云的信息,甚至还有一些暴露的图片。可以这样说,您已经陷入可怕的垃圾留言里了。

垃圾留言对您来说是有害的,因为它加重了您的工作负担。垃圾留言对您的用户来说也是有害的,因为他们只是来您的网站来寻找感兴趣的内容,而这些毫不相关的内容只会影响他们的注意力。垃圾留言对整个网络来说也是有害的,因为它使网站管理员们不敢轻易开放自己的网站,这给人们在论坛和博客上自由发表自己的观点带来了不便。

那么作为一个网站管理员,您可以做些什么呢?

注:下面的解决办法是一个很好的起点,但可能并不是全部的解决方案。互联网上有许多不同的博客,论坛和BBS 我们不可能对每一种系统都提供详尽的指导,以下是较广泛通用的解决办法。

确保是真正的人而不是机器在您的网站上留言

  • 添加一个输入验证码环节(CAPTCHA)CAPTCHA要求用户阅读一段模糊的文字并输入相应的文字,这种办法能够验证对方究竟是真正的人类还是机器程序。如果您的博客或论坛没有植入验证环节的话,您可以使用Recaptcha这个插件。验证环节并不能解决所有的问题,但是它可以有效地制止垃圾留言制造者的猖狂行为。您可以了解更多类型的CAPTCHAS,但是请记住仅仅是添加这么一个环节,就可以起到很大的作用。
  • 阻止可疑行为。许多论坛允许您设置两次发贴之间的最小时间间隔。您也可以通过安装插件,监控那些来自于同一IP地址或proxy的异常巨大的流量,以及其他更可能来自于机器程序而不是人类访问者的异常行为。

使用自动过滤系统

  • 通过将一些关键词加入黑名单能够帮助您阻止一些明显的不恰当的留言。垃圾制者们有时候会故意模糊所使用的词语,所以这个方法也不是万能的,不过您也不妨一试。
  • 使用能够自动删除垃圾留言的插件或系统特性。垃圾制造者们使用自动程序的方式来侵扰您的站点,那我们为什么不也用自动的方式来保护自己呢?像Akismet(有很多针对博客和论坛的插件)这样的系统和TypePad Antispam(开源并兼容Akismet),很容易安装,并能帮您完成大部分的工作。

将您的设置调整地更严格一些

  • 禁止跟踪不被信任的链接。许多系统有这样的功能,可以给链接添加"nofollow"的属性。这样做可以防止某种类型的垃圾留言,但并不是唯一可行的方式。
  • 您可以考虑要求用户在发帖前必须登录,这样可以防止用户任意地发表留言。但是,这样做也会使信噪比提高。
  • 改变您的设置,使留言必须经过您的批准才能展示。如果您是一个规模较小的网站,并且没有太多的留言的话,这是一个使自己网站留言保持高水平的很好的办法。您可以允许自己的员工或者值得信赖的用户能够自助批准自己的留言,这样能减轻您一部分工作负担。
  • 可以考虑禁止某些类型的留言。比如,您可以将那些比较陈旧、已经不太可能有高质量评论的帖子冻结。在博客上,您可以把引用通告等功能暂停,因为这是极易吸引网络垃圾的地方。

及时更新您的网站

  • 请您花些时间将您的软件及时更新,并关注那些重大的安全升级。一些网络垃圾制造者会利用旧版本博客、论坛或内容管理系统的安全漏洞攻击您的网站。您可以在网站安全快速检查清单上找到更多相应的解决方案。

您可能需要权衡您的软件、您的用户群,及您的经验等多种因素来选择实施各种方法。无论您是一个小型的个人博客,还是一个大型的多用户的网站,不加任何保护地就贸然开放您的网站留言是有很大风险的。另外,如果您的网站已经被成千上万条垃圾帖所侵蚀并且不再出现在Google搜索结果的话,当您已经彻底清除了这些不良内容并采取了相应保护措施的话,您可以考虑提交一个重新收录的申请

作为一个有较长时间经验的网站开发者和博客一员,我可以以我自己的切身体验告诉您,花一点点时间做一些预防措施会节省您将来大量的时间和精力。我是网站管理员中心组的一个较新的成员。我很乐意帮助我的网站管理员同行们,而且我对搜索质量也非常感兴趣(我已经在这一领域做了一些学术研究)。欢迎您在留言板里分享您对防止留言垃圾的心得,同时始终欢迎您访问Google网站管理员支持论坛并提出您的问题。

2008年10月30日星期四

设计完美商标图案的45条原则

  1. 不要使用超过3种颜色。
  2. 不是不可或缺的内容就无需展示。
  3. 字体务必清晰明了,让你奶奶都能看懂。
  4. 商标图案务必易于识别。
  5. 设计一个造型或者布局独特的商标图案。
  6. 独立思考,不要理会您父母爱人对你设计的想法。
  7. 保证商标图案看起来至少要能吸引三个人的注意。
  8. 不要将流行商标中的元素融入到设计中,并称为原创作品。
  9. 任何情况下都不要用剪贴画。
  10. 将商标图案设置为黑白两色时看起来依然效果良好。
  11. 反置商标图案后依然清晰明辨。
  12. 调整商标图案大小后依然清晰明辨。
  13. 如果商标图案中包含图标、符号或文字等元素,合理布局让他们相辅相成。
  14. 让您的设计避免沿袭最新流行的商标设计潮流,而要看起来能够经久不衰。
  15. 不要使用特殊效果(包括也并不局限于:斜体、阴影、反射和射线字)。
  16. 如果可能让商标呈方形布局,避免使用难以理解的布局。
  17. 避免复杂的细节。
  18. 考虑商标放置的不同地方和方式。
  19. 激发勇敢和自信的感觉,而不是无力呆板的感觉。
  20. 你应该知道你创作的商标图案绝不是完美的。
  21. 对于精明的生意采用锋利的线条,缓和的生意采用缓和的线条。
  22. 商标图案必须与其表现的主题有所关联。
  23. 照片不能做商标图案。
  24. 你要让顾客对你的设计有惊艳的感觉。
  25. 不要使用超过2种字体。
  26. 商标中的每个元素都应该排列地井井有条。左、中、右、上或底。
  27. 图标看起来浑然一体,没有拖尾元素。
  28. 在你构思设计商标之前要明确商标即将面对的群体。
  29. 强调功能胜过创新。
  30. 如果商标名字让人印象深刻,那么就用商标名字做商标图案。
  31. 镜像商标图案后依然清晰可见。
  32. 甚至大公司也需要小图案。
  33. 商标图案应该让所有人喜欢,而不仅仅为该商家喜欢而已。
  34. 创造变化。变化越多,你设计出来的商标就越适合。
  35. 商标图案在多个平台下看起来连贯。
  36. 商标图案必须轻易地描述出来。
  37. 不要在商标图案里用标志性语言。
  38. 在计算机上设计之前先把思路用铅笔在纸上绘制出来。
  39. 设计简约。
  40. 不要使用“嗖”或者“全球”符号。
  41. 商标图案不能够分散注意力。
  42. 在设计中应该如实表现设计内容。
  43. 商标图案应该视觉平衡。
  44. 避免使用明亮霓幻颜色,以及灰暗呆板颜色。
  45. 商标设计不能打破以上任何一条原则。

2008年10月29日星期三

面试中的陷阱:Java面试中的陷阱(一)

找工作要面试,有面试就有对付面试的办法。以下一些题目来自我和我朋友痛苦的面试经历,提这些问题的公司包括IBM, E*Trade, Siebel, Motorola, SUN, 以及其它大小公司。

面试是没什么道理可讲的,它的题目有的不合情理、脱离实际。有在纸上写的,有当面考你的,也有在电话里问的,给你IDE的估计很少(否则你赶快去买彩票, 说不定中)。所以如果你看完此文后,请不要抱怨说这些问题都能用IDE来解决。你必须在任何情况下准确回答这些问题,在面试中如果出现一两题回答不准确很 有可能你就被拒之门外了。

当然这些都是Java的基本题,那些面试的人大多数不会问你Hibernate有多先进,Eclipse的三个组成部分,或command design pattern,他们都是老一辈了,最喜欢问的就是基础知识。别小看了这些基础,我朋友水平一流,结果就栽在一到基础知识的问题下,和高薪无缘。

好了废话少说,开始正题。

第一,谈谈final, finally, finalize的区别。
最常被问到。

第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?

第三,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统)。

第四,&和&&的区别。
这个问得很少。

第五,HashMap和Hashtable的区别。
常问。

第六,Collection 和 Collections的区别。
你千万别说一个是单数一个是复数。

第七,什么时候用assert。
API级的技术人员有可能会问这个。

第八,GC是什么? 为什么要有GC?
基础。

第九,String s = new String("xyz");创建了几个String Object?

第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

第十一,short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
面试题都是很变态的,要做好受虐的准备。

第十二,sleep() 和 wait() 有什么区别?
搞线程的最爱。

第十三,Java有没有goto?
很十三的问题,如果哪个面试的问到这个问题,我劝你还是别进这家公司。

第十四,数组有没有length()这个方法? String有没有length()这个方法?

第十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
常问。

第十六,Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

第十七,给我一个你最常见到的runtime exception。
如果你这个答不出来,面试的人会认为你没有实际编程经验。

第十八,error和exception有什么区别?

第十九,List, Set, Map是否继承自Collection接口?

第二十,abstract class和interface有什么区别?
常问。

第二十一,abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

第二十二,接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

第二十三,启动一个线程是用run()还是start()?

第二十四,构造器Constructor是否可被override?

第二十五,是否可以继承String类?

第二十六,当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

第二十七,try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

第二十八,编程题: 用最有效率的方法算出2乘以8等於几?
有C背景的程序员特别喜欢

2008年10月19日星期日

无知者无畏——中国程序员和印度程序员的对话

一个在美国IBM工作过2年,在印度公司工作了4年的项目经理与我司资深软件开发经理有这样一段对话。
印方经理问:"你们每月生产多少行代码?"
我方经理掂量了很久,谦虚地说:"人均代码1万多行吧,不到2万行"。
印方经理听后,眼睛瞪得圆圆的:"喔!你们已经远远超过国际最高水平了。"
我方经理惴惴不安地反问:"你们的呢?"
印方经理很认真地回答:"我们公司目前的效率为每人每月300行。"
这是一个真实的故事,我想换了其他人(包括以前的我)也会给出同样的答案。
为什么与软件大国有这么大的差距呢?
首先我们没有生产率的概念。大多数人是这么算的,一天编400行-500行代码还不是小菜一碟。一个月有30天,这样每月1万多行还不是轻松搞掂?
殊不知,这个伟大的假设有两个致命的错误:第一、没有考虑需求分析、概要设计、详细设计、单元测试、集成测试、系统测试的时间,也没有考虑文档的时间,甚至都有可能不知道有这些过程。
这不是笑话,试问:我们有需求分析吗?我们有单元测试吗?我们有编程规范,但我们遵守了吗?
我们的代码花花绿绿,风格千奇百怪――
我们不是有"开发完了,还没有设计文档的经历"吗?
我们不是有"要转中试了,所有人才开始埋头苦干写文档"的经历吗?
我们不是有人在文档中写过,"该软件对人畜没有伤害"吗?
当然,我们更不可能想到有review的时间,根本考虑不到质量控制?
我 们最熟悉写程序、系统测试、维护,其他的都是多余。这是典型的小公司游击战的做法,一个人搞一个小软件,不需要任何流程,没有任何质量体系,除了写代码, 测试以外,什么都不需要,非常自由,自以为"牛得不行",这很easy,那很容易,"管理是罗嗦,流程是麻烦",但实际的结果是什么样大家都知道。
第二、一天能写400-500行代码,并不表示,你平均每个月能写12000-15000行代码,道理很简单,一个人100米速度是12秒,并不表示他的3000米速度是6分钟。我们不是机器人,写软件需要思考,写嵌入式软件尤其需要质量。
印度工程师是人,中国软件工程师也是人,我们的代码生产率与水平能高到哪里去呢?正如大家都是凡人,你突然说你比子弹还快,一蹦3层楼高。
这真是"无知"者"无畏"?
其 实我们的生产率很低,自己不觉得罢了,很多人并不相信我司的公开数字――月产代码才120行?如果算一算所有的人力,所有阶段的时间,我们就不会惊奇这个 数据了。不信的话,我们拿一个产品算一算!或许我们的经理自己都不知道在这个产品投了多少人力。华为有职业化的软件开发管理人才吗?目前几乎没有,或许我 们真的有月产2万行的编程高手,也有很多自以为能写2万行代码的"泡沫"高手,但我们没有真正专业的软件人才!
目前我们公司的销售情况很好,卖得 很火。但这是项目开发成功了吗?不是,可能更多的是市场的成功,以及产品预研立项人员的成功。生命周期内还要花那么多维护费用,这怎么能算成功?如果我们 造飞机,我们可能自己都不敢坐。衡量项目成功的标准与要素是什么?很多人并不知道。印度发展最快的Infosys公司告诉我们:衡量项目成功的标准是"质 量、成本与进?quot;,达到这一目标的重要条件是"流程、技术、人"。
我们做计划时,只有进度,或许会考虑一下成本,但从来没有考虑过质量。我们知道项目开发的质量活动是什么吗?我们不知道;我们知道我们的质量目标吗?我们也没有;我们知道如何控制我们的质量吗?我们没有干过。
所以我们才无所畏惧,百折不饶。但如果我们知道"折"一次要花100万,我们还会无所畏惧地"百折"吗?再回头看看一些业界标准:某印度合作公司通过了CMM5级,联合开发项目的生产率为每月400行。其中编码阶段,印度工程师每天可以写200至900行代码。
在4个月的联合开发过程中――
在编码速度上,我方优秀工程师与对方差不多,但别人教会了我们如何保证代码规范以及编程风格的一致;
在阅读协议标准方面,对方的速度是我们的4-5倍;
在设计方面,对方有明显的优势;
在质量控制,我们与他们就没有办法比较了;
在预测方面,对方估计工作量为36人月,我方估计为22人月,实际数为35人月。
通过对比,我的结论是:我们富有,因为我们有很多bug;我们快速,因为我们没有质量体系。
有些人还以为――
会使用配置工具sourcesafe,就知道什么是配置管理;
会画CANTT图/PERT图,就知道项目计划是怎么回事了;
填一下表格就是管理;
吃一顿饭就是沟通。
没有对质量整体的认识,不了解其为什么这么做,大家就根据自己的过去经验"理解"、"推测"、"认识"别人,有这么巨大的认识差距就不足为怪了。
目前,公司在质量体系方面的培训与推行力度的不断加强,印度所经验的不断推广,在很多方面,如流程建设、预测、质量控制、度量系统,我们已经初步了解该怎么做。但我们还要不断地宣传、不停地松土,让所有的人承认自己无知,只有这样,我们才能由"无知"变为"有识"。
"艺低人胆大",今后,我再也不想听这种大胆的豪言壮语:“我们每月代码1万行"!

2008年10月17日星期五

IE与FireFox的js和css(杂记)

png透明 AlphaImageLoader
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=bEnabled,sizingMethod=sSize,src=sURL)

enabled:可选项。布尔值(Boolean)。设置或检索滤镜是否激活。true:默认值。滤镜激活。false:滤镜被禁止。
sizingMethod:可选项。字符串(String)。设置或检索滤镜作用的对象的图片在对象容器边界内的显示方式。crop:剪切图片以适应对象尺寸。image:默认值。增大或减小对象的尺寸边界以适应图片的尺寸。scale:缩放图片以适应对象的尺寸边界。
src:必选项。字符串(String)。使用绝对或相对 url 地址指定背景图像。假如忽略此参数,滤镜将不会作用。

禁止选取网页内容
在IE中一般用js:obj.onselectstart=function(){return false;}
而firefox用CSS:-moz-user-select:none

滤镜的支持(例:透明滤镜)
IE:filter:alpha(opacity=10);
firefox:-moz-opacity:.10;

捕获事件
IE:obj.setCapture() 、obj.releaseCapture()
Firefox:document.addEventListener(”mousemove”,mousemovefunction,true);
document.removeEventListener(”mousemove”,mousemovefunction,true);

获取鼠标位置
IE:event.clientX、event.clientY
firefox:需要事件函数传递事件对象
obj.onmousemove=function(ev){
X= ev.pageX;Y=ev.pageY;
}

DIV等元素的边界问题
比如:设置一个div的CSS::{width:100px;height:100px;border:#000000 1px solid;}
IE中:div的宽度(包括边框宽度):100px,div的高度(包括边框宽度):100px;
而firefox:div的宽度(包括边框宽度):102px,div的高度(包括边框宽度):102px;

判断浏览器类型
var isIE=document.all ? true : false;
我写了一个变量,如果支持document.all语法那么isIE=true,否则isIE=false

在不同浏览器下的CSS处理
一般可以用!important来优先使用css语句(仅firefox支持)
比如:{border-width:0px!important;border-width:1px;}
在firefox下这个元素是没有边框的,在IE下边框宽度是1px

document.formName.item(”itemName”) 问题
问题说明:IE下,可以使用 document.formName.item(”itemName”) 或 document.formName.elements ["elementName"];Firefox下,只能使用document.formName.elements["elementName"]。
解决方法:统一使用document.formName.elements["elementName"]。

集合类对象问题
问题说明:IE下,可以使用()或[]获取集合类对象;Firefox下,只能使用[]获取集合类对象。
解决方法:统一使用 [] 获取集合类对象。

自定义属性问题
问题说明:IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用 getAttribute() 获取自定义属性;Firefox下,只能使用 getAttribute() 获取自定义属性。
解决方法:统一通过 getAttribute() 获取自定义属性。

eval(”idName”)问题
问题说明:IE下,可以使用 eval(”idName”) 或 getElementById(”idName”) 来取得 id 为 idName 的HTML对象;Firefox下,只能使用 getElementById(”idName”) 来取得 id 为 idName 的HTML对象。
解决方法:统一用 getElementById(”idName”) 来取得 id 为 idName 的HTML对象。

变量名与某HTML对象ID相同的问题
问题说明:IE下,HTML对象的ID可以作为 document 的下属对象变量名直接使用,Firefox下则不能;Firefox下,可以使用与HTML对象ID相同的变量名,IE下则不能。
解决方法:使用 document.getElementById(”idName”) 代替 document.idName。最好不要取HTML对象ID相同的变量名,以减少错误;在声明变量时,一律加上var关键字,以避免歧义。

const问题
问题说明:Firefox下,可以使用const关键字或var关键字来定义常量;IE下,只能使用var关键字来定义常量。
解决方法:统一使用var关键字来定义常量。

input.type属性问题
问题说明:IE下 input.type 属性为只读;但是Firefox下 input.type 属性为读写。
解决办法:不修改 input.type 属性。如果必须要修改,可以先隐藏原来的input,然后在同样的位置再插入一个新的input元素。

window.event问题
问题说明:window.event 只能在IE下运行,而不能在Firefox下运行,这是因为Firefox的event只能在事件发生的现场使用。
解决方法:在事件发生的函数上加上event参数,在函数体内(假设形参为evt)使用 var myEvent = evt?evt:(window.event?window.event:null)
示例:<input onclick="”doSomething(event)”/" type="”button”">
<script language="”javascript”"></script>
function doSomething(evt) {
var myEvent = evt ? evt: (window.event ? window.event : null)

}

event.x与event.y问题
问题说明:IE下,even对象有x、y属性,但是没有pageX、pageY属性;Firefox下,even对象有pageX、pageY属性,但是没有x、y属性。
解决方法:var myX = event.x ? event.x : event.pageX;var myY = event.y ? event.y:event.pageY;
如果考虑第8条问题,就改用myEvent代替event即可。

event.srcElement问题
问题说明:IE下,even对象有srcElement属性,但是没有target属性;Firefox下,even对象有target属性,但是没有srcElement属性。
解决方法:使用srcObj = event.srcElement ? event.srcElement : event.target;
如果考虑第8条问题,就改用myEvent代替event即可。

window.location.href问题
问题说明:IE或者Firefox2.0.x下,可以使用window.location或window.location.href;Firefox1.5.x下,只能使用window.location。
解决方法:使用 window.location 来代替 window.location.href。当然也可以考虑使用 location.replace()方法。

模态和非模态窗口问题
问题说明:IE下,可以通过showModalDialog和showModelessDialog打开模态和非模态窗口;Firefox下则不能。
解决方法:直接使用 window.open(pageURL,name,parameters) 方式打开新窗口。
如果需要将子窗口中的参数传递回父窗口,可以在子窗口中使用window.opener来访问父窗口。如果需要父窗口控制子窗口的话,使用var subWindow = window.open(pageURL,name,parameters);来获得新开的窗口对象。

frame和iframe问题
以下面的frame为例:
<frame src=”xxx.html” id=”frameId” name=”frameName” />
(1)访问frame对象
IE:使用window.frameId或者window.frameName来访问这个frame对象;
Firefox:使用window.frameName来访问这个frame对象;
解决方法:统一使用 window.document.getElementById(”frameId”) 来访问这个frame对象;

(2)切换frame内容
在IE和Firefox中都可以使用window.document.getElementById(”frameId”).src = “xxx.html”或window.frameName.location = “xxx.html”来切换frame的内容;
如果需要将frame中的参数传回父窗口,可以在frame中使用parent关键字来访问父窗口。

body载入问题
问题说明:Firefox的body对象在body标签没有被浏览器完全读入之前就存在;而IE的body对象则必须在body标签被浏览器完全读入之后才存在。
[注] 这个问题尚未实际验证,待验证后再来修改。
[注] 经验证,IE6、Opera9以及FireFox2中不存在上述问题,单纯的JS脚本可以访问在脚本之前已经载入的所有对象和元素,即使这个元素还没有载入完成。

事件委托方法
问题说明:IE下,使用 document.body.onload = inject;其中function inject()在这之前已被实现;在Firefox下,使用 document.body.onload = inject();
解决方法:统一使用 document.body.onload=new Function(”inject()”);或者 document.body.onload = function(){/* 这里是代码 */}
[注意] Function和function的区别

访问的父元素的区别
问题说明:在IE下,使用 obj.parentElement 或 obj.parentNode 访问obj的父结点;在firefox下,使用 obj.parentNode 访问obj的父结点。
解决方法:因为firefox与IE都支持DOM,因此统一使用obj.parentNode 来访问obj的父结点。

cursor:hand VS cursor:pointer
问题说明:firefox不支持hand,但ie支持pointer ,两者都是手形指示。
解决方法:统一使用pointer。

innerText的问题
问题说明:innerText在IE中能正常工作,但是innerText在FireFox中却不行。
解决方法:在非IE浏览器中使用textContent代替innerText。
示例:
if(navigator.appName.indexOf(”Explorer”) >-1){
document.getElementById(”element”).innerText = “my text”;
}else{
document.getElementById(”element”).textContent = “my text”;
}
[注] innerHTML 同时被ie、firefox等浏览器支持,其他的,如outerHTML等只被ie支持,最好不用。

对象宽高赋值问题
问题说明:FireFox中类似 obj.style.height = imgObj.height 的语句无效。
解决方法:统一使用 obj.style.height = imgObj.height + “px”;

Table操作问题
问题说明:ie、firefox以及其它浏览器对于 table 标签的操作都各不相同,在ie中不允许对table和tr的innerHTML赋值,使用js增加一个tr时,使用appendChild方法也不管用。
解决方法:
//向table追加一个空行:
var row = otable.insertRow(-1);
var cell = document.createElement(”td”);
cell.innerHTML = “”;
cell.className = “XXXX”;
row.appendChild(cell);
[注] 由于俺很少使用JS直接操作表格,这个问题没有遇见过。建议使用JS框架集来操作table,如JQuery。

ul和ol列表缩进问题
消除ul、ol等列表的缩进时,样式应写成:list-style:none;margin:0px;padding:0px;
其中margin属性对IE有效,padding属性对FireFox有效。← 此句表述有误,详细见↓
[注] 这个问题尚未实际验证,待验证后再来修改。
[注] 经验证,在IE中,设置margin:0px可以去除列表的上下左右缩进、空白以及列表编号或圆点,设置padding对样式没有影响;在Firefox 中,设置margin:0px仅仅可以去除上下的空白,设置padding:0px后仅仅可以去掉左右缩进,还必须设置list-style:none才 能去除列表编号或圆点。也就是说,在IE中仅仅设置margin:0px即可达到最终效果,而在Firefox中必须同时设置margin:0px、 padding:0px以及list-style:none三项才能达到最终效果。

CSS透明问题
IE:filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=60)。
FF:opacity:0.6。
[注] 最好两个都写,并将opacity属性放在下面。

CSS圆角问题
IE:ie7以下版本不支持圆角。
FF:-moz-border-radius:4px,或者-moz-border-radius-topleft:4px;-moz-border- radius-topright:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius- bottomright:4px;。
[注] 圆角问题是CSS中的经典问题,建议使用JQuery框架集来设置圆角,让这些复杂的问题留给别人去想吧。

推荐30个国外优秀的设计教程网站

1.Good-Tutorials

2. Pixel2life

3. Tutorialized

4. Luxa

5. TutorialOutpost

6. Graphic-Design-Links

6.FStutorials

7. PhotoshopRoadmap

8. Tutorial-center

9. TutorialGarden

10. TutorialKit

11. CGtutorials

12. PSlover

13. TotalTutorial

14. TutorialMan

15. Photoshop911

16. PureGraphics

17. PhotoshopTalent

18. TutorialSubmitter

19. CGlinks

20.T-tutorials

21. Tutorial-Inde

22. Tutorial-Mix

23. Tutorio

24. TutorialAdvisor

25. Pixel-Groovy

26. Tutorialing

27. TipClique

28. TutorialToday

29. GFXtuts

30. CapitalTutorials

应用htaccess给网站加上防盗链机制

以前在使用IIS服务器时,曾经使用过防盗链的工具,还算好用,现在转到Dreamhost之后,倒是很久没有用过防盗链了。

这几天Google了一下,最后看到A18制造的这个方法的确有效,目前本站就在使用。

具体的做法比较简单,就是在.htaccess文件中,添加下面这段代码。
然后自己做一张图片,放在网站根目录下,当其它网站盗用本站资源时,会用这张图片替换它所要求的文件,显示提示信息,请用户回到本网站获取更为准确的资讯。

如果你要使用这段代码,请自行修改有关的参数。
不要问我为什么这么写,我不懂,我只会用。
里面的网址都是允许外链的网站,如果要添加的话,请自行添加。

目前不允许外链的文件包括图片,压缩文件,和flash。
盗链不但是盗取内容还是盗取带宽,采取这个方法可以较好的处理这个问题。

RewriteEngine on RewriteCond %{REQUEST_URI} ^/outlink RewriteRule ^.*$ - [L] RewriteCond %{REQUEST_FILENAME} \.(gif|jpeg|png|swf|flv|zip|rar|txt|exe|7z)$ [NC] RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !g2soft\.net [NC] RewriteCond %{HTTP_REFERER} !google\.com [NC] RewriteCond %{HTTP_REFERER} !www\.baidu\.com [NC] RewriteCond %{HTTP_REFERER} !image\.baidu\.com [NC] RewriteCond %{HTTP_REFERER} !feedsky\.com [NC] RewriteCond %{HTTP_REFERER} !365bloglink\.com [NC] RewriteCond %{HTTP_REFERER} !yahoo\.com [NC] RewriteCond %{HTTP_REFERER} !msn\.com [NC] RewriteCond %{HTTP_REFERER} !bloglines\.com [NC] RewriteCond %{HTTP_REFERER} !feedburner\.com [NC] RewriteCond %{HTTP_REFERER} !xianguo\.com [NC] RewriteCond %{HTTP_REFERER} !zhuaxia\.com [NC] RewriteRule (.*) /outlink/outlink.png [R,NC,L] RewriteCond %{HTTP_REFERER} !^$ [NC]
RewriteCond %{HTTP_REFERER} !g2soft.net [NC]
RewriteCond %{HTTP_REFERER} !google.com [NC]
RewriteCond %{HTTP_REFERER} !www.baidu.com [NC]
RewriteCond %{HTTP_REFERER} !image.baidu.com [NC]
RewriteCond %{HTTP_REFERER} !yahoo.com [NC]
RewriteCond %{HTTP_REFERER} !msn.com [NC]
RewriteCond %{HTTP_REFERER} !bloglines.com [NC]
RewriteCond %{HTTP_REFERER} !feedburner.com [NC]
RewriteCond %{HTTP_REFERER} !feedsky.com [NC]
RewriteCond %{HTTP_REFERER} !xianguo.com [NC]
RewriteCond %{HTTP_REFERER} !zhuaxia.com [NC]
RewriteRule .(jpg|gif|png|bmp|swf|jpeg)$ http://seo\.g2soft\.net/outlink3.png [R,NC,L]

2008年10月15日星期三

sqlserver数据库:如何在SQL Server数据库中加密数据

为了防止某些别有用心的人从外部访问数据库,盗取数据库中的用户姓名、密码、信用卡号等其他重要信息,在我们创建数据库驱动的解决方案时,我们首先需要考虑的的第一条设计决策就是如何加密存储数据,以此来保证它的安全,免受被他人窥测。

SQL Server中有哪一种支持可以用于加密对象和数据?从一开始就讨论一下SQL Server欠缺什么是明智的,或者是对于SQL Server中的加密部分你不应该做什么。   

首先,SQL Server有两个内置的密码函数——即,pwdencrypt() 和 pwdcompare()。同时,还有两个SQL Server用来管理密码哈希的没有正式记录的函数:pwdencrypt() 将密码哈希过后进行存储; pwdcompare()将提供的字符串与哈希后的字符串进行比较。不幸的是,这个哈希函数不是非常安全,它可以通过字典攻击算法被破解(类似命令行应用 程序!)。

这些函数随着SQL Server的版本发展而不断进行修改,这也是另一个没有使用它们的原因。早期版本的SQL Server对密码进行的哈希,在后来的版本中无法解密,所以如果你依赖一个版本中的函数,那么当升级的时候,所有你的加密数据就都没有用了,除非你可以 首先对其解密——这也就违背了加密的最初的目的。   

第二,你可能会尝试去创建一个针对你的数据库的自制的加密解决方案,但是有以下三个理由说明你不要这样做:

除非你是加密专家,否则胡乱编写的加密系统只会提供非常低级的价值不高的保护。新鲜的是,单向密码哈希或者 "ROTx "形式的加密几乎不需要费事就可以被轻松打败。

如果由于你自己的能力的缺乏而导致加密被破解,那么你的数据就完蛋了。你需要将所有的东西进行没有加密的备份,是吗?(即使你加密了,那里有没有安全漏洞?)

当市面上提供有专业级别的,具有工业强度的加密解决方案的时候,你就不值得花费时间去自己做。把你的时间用于构建一个好的,坚固的数据库,而不是再重新发明一次车轮。

那么,什么才是好的加密数据的方式呢?

对于新手,微软提供了一个自己生成的加密解决方案,CryptoAPI 。对于轻量级的加密,军用级别的安全就不在考虑范围之内,它具有相对容易实现的优势:管理员可以安装一个名为CAPICOM 的ActiveX 控制,它可以在T-SQL存储过程中提供CryptoAPI 功能。CAPICOM 支持各种类型的双向加密和单向哈希算法,所以管理员可以挑选最适合应用程序的问题的部分。   

如果你对使用微软的解决方案不感兴趣,还有一些很好的第三方的方案可以使用。一家名为ActiveCrypt 的软件有限责任公司制造了XP_CRYPT ,它是SQL Server的插件,可以在视图、程序和触发器中通过扩展存储过程和用户自定义函数(在SQL Server 2000中)来完成加密。你可以下载一个支持无线的MD5,DES ,以及SHA1哈希的免费版本的应用程序; 其他的加密模型就是在比特深度上进行的。(完全版本是无限的。)在你自己的代码中,你可以使用XP_CRYPT,与ActiveX 控制一样(在受限的免费版本中)。对于ASP程序员来说,一个名为AspEncrypt 的组件提供了一种将高级加密整合到你的代码中的简单方式。

对数据库文件自身进行加密或者提供传输层上的安全保护怎么样?对于前者,大家可以在Windows系统中持续使用加密文件系统。然而,你必须保存加 密密钥的备份,在出现问题的时候,这个数据有可能会丢失。对于后者,有IPSec和SQL Server自己的SSL加密,都是SQL Server和Windows自带的大家的主要精力应该放在避免以明文存储敏感数据,因为从数据库中抽取没有加密的数据同样是最容易受到攻击的薄弱环节。

2008年10月13日星期一

马云语录:最大的失败就是放弃

*在创业的道路上,我们没有退路,最大的失败就是放弃。

*在我刚开始创业的那个时候,有人说如果阿里巴巴能够成功,无疑是把一艘万吨巨轮从喜马拉雅山脚下抬到珠穆朗玛峰顶,我就要让他们看看我是如何把这艘万吨巨轮从珠穆朗玛峰顶抬到山脚下。

*今天很残酷,明天更残酷,后天很美好,但是绝大多数人死在明天晚上,见不着后天的太阳

*1999至今在杭州设立研究开发中心,以香港为总部,创办阿里巴巴网站(Alibaba.com)孙正义跟我有同一个观点,一个方案是一流的Idea加三流的实施;另外一个方案,一流的实施,三流的Idea,哪个好?我们俩同时选择一流的实施,三流的Idea。

*如何把每一个人的才华真正地发挥作用,我们这就像拉车,如果有的人往这儿拉,有的人往那儿拉,互相之间自己给自己先乱掉了。当你有一个傻 瓜时,很傻的,你很会很痛苦;你有50个傻瓜是最幸福的,吃饭、睡觉、上厕所排着队去的;你有一个聪明人时很带劲,你有50个聪明人实际上是最痛苦的,谁 都不服谁。我在公司里的作用就象水泥,把许多优秀的人才粘合起来,使他们力气往一个地方使。

*网络公司将来要判断两个:第一它的team;第二,它有technology;第三它的concept,拥有这些东西,才是存在的必要。

*Judge一个人,一个公司是不是优秀,不要看他是不是Harvard,是不是Stanford.不要judge里面有多少名牌大学毕业生,而要judge这帮人干活是不是发疯一样干,看他每天下班是不是笑眯眯回家。

*30%的人永远不可能相信你。不要让你的同事为你干活,而让我们的同事为我们的目标干活,共同努力,团结在一个共同的目标下面,就要比团结在你一个企业家底下容易的多。所以首先要说服大家认同共同的理想,而不是让大家来为你干活。

*我认为,员工第一,客户第二。没有他们,就没有这个网站。也只有他们开心了,我们的客户才会开心。而客户们那些鼓励的言语,鼓励的话,又会让他们像发疯一样去工作,这也使得我们的网站不断地发展。

*看见10只兔子,你到底抓哪一只?有些人一会儿抓这个兔子,一会儿抓那个兔子,最后可能一只也抓不住。CEO的主要任务不是寻找机会而是对机会说NO。机会太多,只能抓一个。我只能抓一只兔子,抓多了,什么都会丢掉.

*我们公司是每半年一次评估,评下来,虽然你的工作很努力,也很出色,但你就是最后一个,非常对不起,你就得离开。在两个人和两百人之间,我只能选择对两个人残酷。

*您能用一句话概括您认为员工应该具备的基本素质吗?今天阿里巴巴的员工我们要求诚信,学习能力,乐观精神,和拥抱变化的态度!

*互联网是四乘一百米接力赛,你再厉害,只能跑一棒,应该把机会给年轻人。

*在前一百米的冲刺中,谁都不是对手,是因为跑的三千米的长跑。你跑着跑着,跑了四五百米后才能拉开距离的。

*我们花了两年的时间打地基,我们要盖什么样的楼,图纸没有公布过,但有些人已经在评论我们的房子怎么不好。有些公司的房子很好看,但地基不稳,一有大风就倒了。

*我们与竞争对手最大的区别就是我们知道他们要做什么,而他们不知道我们想做什么。我们想做什么,没有必要让所有人知道。
*网络上面就一句话,光脚的永远不怕穿鞋的。

*今天要在网上发财,概率并不是很大,但今天的网络,可以为大家省下很多成本。这个世界没有人能替你发财,只有你自己才能替你发财,你需要 的是投资和投入,spendtime,investtime,ontheinternet,把自己的时间投资在网络上面,网络一定会给大家省钱,但不一定 今天就能赚多少钱,赚钱是明天的事,省钱,你今天就看得到。

*电子商务最大的受益者应该是商人,我们该赚钱因为我们提供工具,但让我们做工具的人发了大财,而使用工具的人还糊里糊涂,这是不正常 的。所谓新经济,就是传统企业利用好网络这个工具,去创造出更大的经济效益,使其成几十倍地增长,这才是真的新经济的到来。今天新旧经济是两张皮。

*互联网上失败一定是自己造成的,要不就是脑子发热,要不就是脑子不热,太冷了。

*我觉得网络公司一定会犯错误,而且必须犯错误,网络公司最大的错误就是停在原地不动,最大的错误就是不犯错误。关键在于总结我们反思各种各样的错误,为明天跑的更好,错误还得犯,关键是不要犯同样的错误

*我们是教人钓鱼,而不是给人鱼。

*企业家是在现在的环境,改善这个环境,光投诉,光抱怨有什么用呢?国家现在要处理的事情太多了,失败只能怪你自己,要么大家都失败,现在有人成功了,而你失败了,就只能怪自己。就是一句话,哪怕你运气不好,也是你不对。

*中国电子商务的人必须要站起来走路,而不是老是手拉手,老是手拉着手要完蛋。

*我们知道当时可以敲几个锣,就可以围那么多人的时候,锣都敲得好,把戏还能不好?敲锣都敲出花来了。

*我是说阿里巴巴发现了金矿,那我们绝对不自己去挖,我们希望别人去挖,他挖了金矿给我一块就可以了。

*我深信不疑我们的模式会赚钱的,亚马逊是世界上最长的河,8848是世界上最高的山,阿里巴巴是世界上最富有的宝藏。一个好的企业靠输血是活不久的,关键是自己造血。

*我们说上市就像我们的加油站,不要到了加油站,就停下来不走,还得走,继续走。

*互联网是影响人类未来生活30年的3000米长跑,你必须跑得像兔子一样快,又要像乌龟一样耐跑。

*我为什么能活下来?第一是由于我没有钱,第二是我对INTERNET一点不懂,第三是我想得像傻瓜一样。

*发令枪一响,你是没时间看你的对手是怎么跑的。只有明天是我们的竞争对手。

*如果早起的那只鸟没有吃到虫子,那就会被别的鸟吃掉。

*If not now,when? If not me, who?

*互联网像一杯啤酒,有沫的时候最好喝。

*听说过捕龙虾富的,没听说过捕鲸富的。

*我们不能企求于灵感。灵感说来就来,就像段誉的六脉神剑一样。

*阿里巴巴的六脉神剑就是阿里巴巴的价值观:诚信、敬业、激情、拥抱变化、团队合作、客户第一。

*我永远相信只要永不放弃,我们还是有机会的。最后,我们还是坚信一点,这世界上只要有梦想,只要不断努力,只要不断学习,不管你长得如 何,不管是这样,还是那样,男人的长相往往和他的的才华成反比。今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今 天。

*男人的长相往往和他的的才华成反比

*在我看来有三种人,生意人:创造钱;商人:有所为,有所不为。企业家:为社会承担责任。企业家应该为社会创造环境。企业家必须要有创新的精神。

*三年以前我送一个同事去读MBA,我跟他说,如果毕业以后你忘了所学的东西,那你已经毕业了。如果你天天还想着所学的东西,那你就还没有毕业。学习MBA的知识,但要跳出MBA的局限。

*对所有创业者来说,永远告诉自己一句话:从创业得第一天起,你每天要面对的是困难和失败,而不是成功。我最困难的时候还没有到,但有一天一定会到。困难不是不能躲避,不能让别人替你去抗。九年创业的经验告诉我,任何困难都必须你自己去面对。创业者就是面对困难。

*ebay是大海里的鲨鱼,淘宝则是长江里的鳄鱼,鳄鱼在大海里与鲨鱼搏斗,结果可想而知,我们要把鲨鱼引到长江里来。

*一个公司在两种情况下最容易犯错误,第一是有太多的钱的时候,第二是面对太多的机会,一个CEO看到的不应该是机会,因为机会无处不在,一个CEO更应该看到灾难,并把灾难扼杀在摇篮里。

*淘宝网的主业决不该放在与对手的竞争上,而是把眼睛盯在提升客户体验上。

*上世纪80年代挣钱靠勇气,90年代靠关系,现在必须靠知识能力!

2008年10月12日星期日

工作中的十不要(适用于工作不久的同事)

第一:不要认为停留在心灵的舒适区域内是可以原谅的。
  
  每个人都有一个舒适区域,在这个区域内是很自我的,不愿意被打扰,不愿意被push,不愿意和陌生的面孔交谈,不愿意被人指责,不愿意按照规定的时限做事,不愿意主动的去关心别人,不愿意去思考别人还有什么没有想到。这在学生时代是很容易被理解的,有时候这样的同学还跟“冷酷”“个性”这些字眼沾边,算作是褒义。然而相反,在工作之后,你要极力改变这一现状。否则,你会很快变成鸡尾酒会上唯一没有人理睬的对象,或是很快因为压力而内分泌失调。但是,如果你能很快打破之前学生期所处的舒适区域,比别人更快的处理好业务、人际、**之间的关系,那就能很快的脱颖而出。
  
  在会议上,一个停留在心灵舒适区域的人会消极的听取领导的话语,消极的待命,很死的完成上级交给的事情,但从来不关心此事以外的任何事情,更不会想到多做一步,让接下来的别人的工作更加容易上手。而敢于打破这个舒适区域的人,敢于在适当的时候提出自己的看法和不理解,并在得到上级认可和指点之后把手头的工作尽快的完成,并随时接受别人的批评和调整。(注意:永远不要等待别人把你的想法说出来,这是典型的前者)
  
  在工作上,当前者遇到一名新的同事,他会装作没有看见,继续自己的工作。殊不知新来的同事不久就变成了自己的上司。而后者则大方客气的自我介绍,并了解对方和自己的关系。
  
  在聚会上,前者总是等待别人发言,并喜欢私下里评论对方的言语;如果这个桌子上没有人发言,那直到用餐结束,也没有人认识你。而后者是勇敢的和一同吃饭的开始介绍和闲谈,这看起来很困难,有时候会有失面子,但往往你会发现,对方是多么希望能和你说几句话。
  
  以上只是很小的几个例子,但是要说明的是,大学生在走出校园的同时就要在工作上把校园中的“随意性”从身边赶走,尽早的冲出自己的舒适区域,开始做好和这个社会交流的准备。
  

  第二:不要把“好像”;“有人会……”;“大概”;“晚些时候”;“或者”;“说不定”之类放在嘴边。尤其是和上级谈论工作的时候。
  
  我十分痛恨听到的一句话是:“我晚些时候会把这个文件发给所有的人”;因为这往往预示着我必须时刻提醒他不要忘记。同样,以下这些言辞也会让人觉得厌恶至极:
  “到时候有人会把那些东西都准备好”
  “大概是明天”
  “明天或者后天客户会过来拜访”
  “好像他说……”
  
  一般是人都会这样说话的,因为这样第一给自己留下了广阔的余地,第二也不会给别人造成很大的压迫感,好像什么事情一定要弄个水落石出似的。说实话大学里面再用功的人都有一半是混的。一个人要么是在课堂上是混的,要么下课之后是混的。两个都没有带有混的色彩的人,要么是超级牛人,要么是神经病。所以,就因为人人都在混的,所以校园是一个浪漫的地方,校园也容易让人单纯。所以学生社团的工作往往是效率很低的,我现在回想起学校里做的工作,当时还觉得挺卖力的,但工作了之后才开始感觉到什么是效率。当你进入了用金钱计算时间的地方之后,你要尽可能的避免在学校里养成的这种习惯。如果上级问你什么时候能实施你给他的承诺,而你回答“今晚或者明天早上”这样的答案对于他来说完全等同于你没有回答,并且还给他留下了一个坏印象。(当然,这样的回答往往在学校社团,学生会工作中是常见的)
  
  有一个寓言故事,一只小老鼠刚刚出世不久,老鼠妈妈问小老鼠:你现在能看见了吗? 小老鼠说:能。 老鼠妈妈说:那你能看到那块红薯吗? 小老鼠说:是的。老鼠妈妈说:那是一块石头,这说明你不但还看不见东西,你连嗅觉都还没有。
  
  似是而非的应答往往一样会暴露出你更多的弱点。可能是以下中的一个或几个:
  1.你之前没有想到这个工作,或者一直在拖延。
  2.你没有责任心,认为这些并不重要。
  3.你应付上级。
  4.你不敢说真话。
  5.你喜欢逞能,答应一些做不到的事情。
  6.你不能独立工作。
  
  当你的上级在以上选项中怀疑的时候,潜意识中你已经同时具备了以上所有的弱点了。
  
  相反的看来,这样的回答,总是让上司恼火。
  第一,他的问题没有得到回答,只是起到了提醒你的作用。
  第二,他依然需要记住提醒你,因为他不知道你是否真正已经落实了工作。
  第三,他不知道有多少你已经做了的事情中,都是这样没有落实的。(这点非常致命)
  第四,往往因为没有得到满意的答案,上司自己的计划不得不被耽搁或推迟或不能给出明朗的结束时间。
  
  所以---------
  甲问:你什么时候能把要这个漏洞修好?
  乙说:我已经通知他们了,他们大概明天就会来修的。
  一天后
  甲问:维修公司什么时候回来,你找的是哪家维修公司?
  乙说:好像他们说安排不出人来,如果可以的话,今天晚上或者明天下午就能过来。
  一天后
  甲问:漏洞怎么还没有修好?
  乙说:我晚点再问问他们。
  甲说:今天下午之前不解决,明天不用来上班了。
  
  
  第三:不要拖延工作
  
  很多人喜欢在学习和玩耍之间先选择后者,然后在最后时间一次性赶工把考试要复习的东西突击完成。但是在工作中请不要养成这样的习惯,因为工作是永远做不完的,容不得你“突击”。又或者,当你在徘徊和彷徨如何实施的时候,你的领导已经看不下去,自己去做了。----这是一个危险的信号。
  
  往往我们总是想把事情从头到尾全部想好了,才开始走第一步-----就摔倒了。
  
  举个例子:我小学的时候第一次给我一个喜欢的女孩子打电话的时候,想象了各种情况-------1,她接电话的时候在做作业。2,她在做作业,她妈妈接的电话。3. 她也很无聊,很想找人说话。4.她正在被父母训斥。 5.她正在想另外一个男孩。6.她父亲接电话。 7.她家正好来了什么亲戚,亲戚接了电话。 8.她接了电话,但父母就在身边,说话不方便。。。。。等等等等。我整整想了一个下午,想好了各种情况的心理准备和应对的策略。然后勇敢的拿起电话机,按下了那几个按钮。结果-------她不在家。
  
  所以,当你徘徊不前而手足无措的时候,你要意识到你正在拖延工作。徘徊是因为害怕这个事情可能发生的后果需要自己承担或应付。工作的时候需要一种起码的自信,相信自己有能力,不管下一步是什么状况,我都能把它引导到我需要的那条线上去的。另外,告诉自己,不要想太多时间,如果不知道,就赶快求助,或想办法,苦恼和忧虑会给你更多的压力也会把剩下的时间蚕食殆尽。
  
  
  另外,警告一下:永远不要想,我知道了,先把上级派的事情放一下,等这集《越狱》看完再说。----90%的情况下,你会忘记,或者来不及,因为这件事需要比你原先想象要更多的时间。说做就做,一直是很好的习惯。
  
  
  第四:不要认为理论上可以实施就大功告成了!
  
  这点太重要了,往往当真正实施的人开始做了才会发现计划完全等于鬼话。如果不亲自实践,做计划的人会早晚被实施的鄙视。永远需要提升自己的办实事的能力,而不是空谈。
  
  首先,如果你是做办公室工作的,或者做策划和计划的。请千万不要把你自己都认为不太可能或者很难做到的事情,让别人试试看。比如,用一个下午的时间在人流量很少的地方举办露天歌唱会。这会让执行的人觉得你在玩他,拿他做实验。没错,理论上,在任何地方都能举办歌唱会,但是,在不同的地方,执行的人的心情是不一样的。
  
  其次,和执行的人讨论你的安排。比如,新来的你的下属,你可以安排她坐在任何地方,但是如果那是一个很难和大家接触的角落,这可能比你什么都不安排更差。的确,理论上一个人要坐下来,需要的只是空间。但事实上远远不止那些。
  
  再次,不要奢望一切会随着你的计划进行。理论上这个会议会持续两个小时,但是,这是“不考虑在开场后的30分钟全场都在调试话筒”,或者“场下没有提出如此尖锐的问题”的前提下的状态。 大学生已经习惯了把事情做到 "理论上看上去很美"的程度了。 论文,ppt讲演,考试,辩论赛…… 这些校园智商大比拼,都是教我们如何完美的做好“纸上谈兵”的功夫。 你一定要相信自己能“搞定”事情的能力比想象的弱。
  
  如果你是在学校的学生,测试一下自己,能否能搞定以下这些状况:
  1.学校要制作一套校服,由你去寻找供应商,砍价,至少有三家公司的报价。
  2.学校保安抓住一个学生偷窃,怎么处理?
  3.学校的一个很重要路段的路灯坏了,你能否让它三天内继续亮起来。
  4.食堂需要请一位专门烧清真菜的厨师,一周内到岗位。
  
  当你开始思考以上这样的问题的时候,你会发现,他的思路和“看过去两年这个公司的业绩趋向,做出一个下个季度的市场策划方案”要相差极大。你会发现后者只要你做到“看上去很完美”,没有人知道按照你这样做结果会怎样。而上述的工作你只要一想,就会体会到不少的压力。因为你不处理好,结果就是明显的失败更大的问题就会相继发生。
  对了,这种感觉就是“工作”给你的感觉!这就是“工作”和“纸上谈兵”的差别!
  
  
  第五:不要让别人等你
  
  在任何情况下都不要让别人放下手头的工作来等你。在大学中可能只是同寝室的人的几句半开玩笑的抱怨,在工作上很可能导致你的潜在合作伙伴的丢失。
  
  你在做一个工作的同时要知道别人的进度,而永远不要落后。
  这不像是在考试,你比别人做的慢,别人可以先交卷,你到时间了做不完你自己承受扣分。在工作中的情况是这样的:这是一场没有人能做完的考试,所有的人,都分配做一张试卷的不同部分,有的人分到的是阅读理解,有的人做的是完形填空,有的人做的是语法…… 然后大家做完了相互抄,这样,所有人都做完了。如果大家都把各自的部分做完了,而你却还在没有做完,那么做得快的别人会开始做你的那部分题目,然后也是相互抄。慢慢地,大家会发现你的工作量完全可以由另外人来代替,整个团队中可以不需要你,这个时候,没有人从你这里得到试卷的答案,也没有人会给你他们的答案--------很不幸,你已经没有利用价值了。
  
  请一定记住这个例子。
  第六:不要认为细节不重要
  
  在大学里,往往做事粗枝大叶,看看差不多就行了。相反,在企业里管理的精髓就在于将简单的事情做到细节。一个慌忙寻找保险箱钥匙的动作就很有可能丧失你晋升财务主管的机会。
  
  公司的管理,其实需要的并不是把很难的事情做到90%----比如,优化管理层的核心工作流程、改变公司在当地政府面前的形象,提高产品质量,改善工作环境…… 而管理要做的是把每个简单的事情做到100%-----比如,把公司的每个人的档案都按照一定的规律整齐的存放起来、在门卫设立一个外来人员的签到台、把会议室多余的椅子拿走、和电视台讲好下个礼拜三来公司做采访、把试用装送到客户手里、在生产的咖啡上加一个口子、给下一期的封面人物拍照……等等如此。如果你能把所有细节的问题都如实做到,那你才有开口升职的本钱。
  
  很多人在毕业的时候不知道自己将来要做什么,于是就和自己说:我以后做管理吧!做管理?问一下自己,如果,公司资产被偷窃了,所有员工士气低下,办公室杂乱无章,公司电梯又坏了,打印机没墨了,采购计划超支了,产品滞销了,客户迟到了……你愿意解决这样的问题,并从小事开始做起吗?想好了这些再考虑是否把管理看得太空洞了。
  

  第七:不要表现得消极,仅仅因为你所做的事情不是你的兴趣所在。
  
  很显然,在学生时代,当做到自己喜欢的时候,我们会pay200%的精力去创造,但如果是枯燥的事务,我们便懒得理睬,最好能有办法应付过去。但在工作上80%你所做的事情都是繁琐而看似机械的,如果仅仅为此而表现的闷闷不乐,那么你会郁闷更久。要知道你的上司已经为这个项目够烦恼了,你还想让他看到你的表情吗?
  
  学会喜欢自己的工作,并把注意力放在日常工作能学到些什么上去。如果现在你努力的抱怨工作,那么接下来你就是努力的寻找工作。尽量少用“有趣”,“好奇”之类的词语来描述自己想要的工作,而是“充实”,“有成就感”,“乐意”
  之类。
  想想以下职位,你会发现生活中很多工作不是在等你有很好的状态下让你做的很有趣的事情:
  1.高速公路收费口的收费员:一天都是面对一个小窗口,把一张卡片送出去,这样要持续好几年。
  2.学校食堂厨师:永远在烧大排和鸡腿。烧一年。
  3.作家:交稿期要到了,我还在孕育灵感,两个星期没吃早饭了。
  4.外科医生:刚刚睡着,马上叫我做一个3小时的手术。这样至少一周一次。
  5.门市部销售:产品不好卖,8点上班来就坐在店门口,一个人,坐到晚上6点,今天没有一个人来,和昨天一样。
  6.公交司机:我开车不用你指挥。这条线路我开了三年了。
  7.宠物商店店员:生意不好,还要一早就过来听着20条狗的叫声一整天,听一年。
  8.公司职员:晚上两点下班,第二天还要8点上班。关键是路上还要一小时。这样已经一个月了。
  
  再想想自己是不是只是接触了这个工作一个月或者才碰到没几个困难,这个时候抱怨的声音最大。
  千万不要想着去选择一个有趣的职业,因为没有那样的工作存在。没有哪一“种”行业是开心的,因为如果有,那所有人都去干那个了。最多试着问问自己本身的兴趣吧。self exploration。
  
  
  第八:绝对不要把改善工作能力仅寄托在公司培训上
  
  人绝对不可能经过一次培训就脱胎换骨。相反,集体培训上学到的东西往往是最用不上的信息。 就像食堂烧大锅菜一样,总没有你最想吃的菜,因为这样做容易,并且不容易得罪人。
  
  很多学生很看重所选的公司有没有培训,这说明,你不但不知道这个公司做什么,你甚至不知道怎样学习这些技能。
  我的感悟是如果你不知道怎么学你想要的知识,也不知道你想要的知识是什么,你只会做出两种行为:1。等待别人来教你,并且等待别人发现你不知道的地方。2.寻找现成的答案并且拷贝。期待公司培训的人,就很大概率上是第一种人(不排除极少真正优秀的公司培训)
  
  许多的同学有这样的习惯思维:
  因为,这个公司的培训能结束达到多少多少的程度
  又因为,这个程度正好是我想达到的
  所以我尽力进这家公司
  因为我进了这家公司
  所以它自然会使我达到了这个期望的程度。
  
  我们把参加培训和达到效果很幼稚的画上了等号。其实往往集体培训上所得到的信息是最没有实际操作价值的。永远不要期望单靠听课,靠老师把同样的东西给所有的人,你会得到比别人更多。把更多的心思放在观察和思考自己的需要上,找到问题的所在再通过观察和实践得到的答案才是真正的知识。
  
  所以,刚刚开始工作,什么都不会,不要认为那样是正常的,因为公司还没有培训过呢!等我接受培训了之后,我就全都会了。如果你一无所知还等待别人会可怜你的无知而施舍你知识,那你会为你的无知而付出更多的智商。
  
  
  第九:不要推卸责任
  
  推卸责任是害怕的条件反射。不要认为别人看不出这点。
  
  我记得我小学里的一件事情。我一次作业没有带来,老师要训斥我,说:你怎么老是作业不带?
  我当时说:不是。。。。 当我正要支支吾吾时候,老师说:什么不是?你带来了没有?
  我说:没有
  老师说:那不就是没有带!什么不是!就是!
  
  之后我就发现,我只是害怕承担责任而条件反射似的就说了“不是”,仔细观察一下周围,你会发现,身边有无数的人在用“不是”作为被责问之后的第一反应。
  其实现在很多人面对工作也是这样,当上级责问的时候,很条件反射的就做出了推卸动作,然而这样的动作,接下来往往是无力的辩解,以及一些很粗糙的借口。这样会让上司感到你这个人很难沟通,并且很不真实。
  
  
  另外一种情况,就是无论什么情况下,我指责一个人,他永远是强调客观。其实这点才是学生最典型的特征。这说明他太容易受到其他事物的影响,并受它们决定。如果你和上司之间会出现以下类型的对话,想想是不是需要改一下你的处事方法。
  
  甲:为什么到现在还没有给副总看你的报告!
  乙:刚才c在打印,我在等他结束,现在他大概好了吧,我去看看
  乙:还有点东西要修改
  乙:b也要把东西给副总,我因为等他
  乙:a他说我报告不用给副总看(a是乙的同级同事)
  乙:不知道副总在不在哦,他的门关着。
  乙:d他叫我帮他打印文件!怪他!(d是乙的同级同事)
  乙:我的杯子突然找不到了,在找杯子。
  
  
  不愿意负责任的人的不利在于他会让上司怀疑他的忠诚程度,因为上司给他的命令往往会因为一个小事情而被搁置或者打折执行,转而被他人的意识所改变。
  
  
  第十:不要对自己说“我是大学生”
  
  这点包涵了很多信息。
  1.不要认为自己有多清高
  2.不要仍然以学生的标准要求自己
  3.不要感觉低人一等
  4.不要等待别人的关怀
  5.不要把这个作为犯错误自我安慰的借口
  6.不要忘记搞清楚,公司究竟给自己的待遇是多少,老练些,这不是在做志愿者。
  
  品格是处理好人际关系的基础,也是确保人际关系质量的关键。除此之外,人际交往的技巧也是尤为重要的。有些人做好事会让人感激一辈子,而有些人帮了别人却可能费力不讨好,不但得不到感激和回报,还让人心存嫉恨。将同样的产品以相同的价格推销给同一个客户,有些业务员可能被粗暴地赶出门,有些业务员却可能签到大单,甚至被客户奉为上宾。
  人际交往的技巧是一个非常庞杂的话题,囿于篇幅,在这里只能结合我的切身体会做一些简单的列举,挂一漏万在所难免了。
  1. 多给别人鼓励和表扬,尽量避免批评、指责和抱怨,不要逼别人认错。
  2. 要学会倾听。不要说得太多,想办法让别人多说。
  3. 如果你要加入别人的交谈,先要弄清楚别人究竟在说什么。
  4. 交谈之前尽量保持中立、客观。表明自己的倾向之前先要弄清楚对方真实的倾向。
  5. 注意对方的社交习惯并适当加以模仿。
  6. 不要轻易打断、纠正、补充别人的谈话。
  7. 别人有困难时,主动帮助,多多鼓励。
  8. 不要因为对方是亲朋好友而不注意礼节。
  9. 尽可能谈论别人想要的,教他怎样去得到他想要的。
  10. 始终以微笑待人。
  11. 做一个有幽默感的人。但是在讲笑话的时候千万不要只顾着自己笑。
  12. 做一个脱离低级趣味的人。
  13. 跟别人说话的时候尽量看着对方的眼睛,不管你是在说还是在听。
  14. 转移话题要尽量不着痕迹。
  15. 要学会聆听对方的弦外之音。也要学会通过弦外之音来委婉地表达自己的意思。
  16. 拜访别人一定要事先通知。
  17. 不要在别人可能忙于工作或者休息的时候打电话过去。除非是非常紧急的事情。
  18. 给别人打电话的时候,先问对方是否方便通话。
  19. 一件事情让两个人知道就不再是秘密。
  20. 你在背后说任何人的坏话都迟早有一天传入这个人的耳朵。
  21. 不要说尖酸刻薄的话。
  22. 牢记他人的名字。养成偶尔翻看名片簿、电话本的习惯。
  23. 尝试着跟你讨厌的人交往。
  24. 一定要尊重对方的隐私,不管是朋友还是夫妻。
  25. 很多人在一起的时候,当你与其中某个人交谈,请不要无视其他人的存在。
  26. 要勇于认错。
  27. 以谦卑的姿态面对身边的每一个人。
  28. 给予他人同情和谅解。
  29. 尽可能用“建议”取代“命令”。
  30. 不要轻易做出承诺。承诺的事情就一定要尽可能做到。

2008年10月10日星期五

YouTube Architecture

Update: YouTube: The Platform. YouTube adds a new rich set of APIs in order to become your video platform leader--all for free. Upload, edit, watch, search, and comment on video from your own site without visiting YouTube. Compose your site internally from APIs because you'll need to expose them later anyway.

YouTube grew incredibly fast, to over 100 million video views per day, with only a handful of people responsible for scaling the site. How did they manage to deliver all that video to all those users? And how have they evolved since being acquired by Google?

Information Sources

# Google Video

Platform

# Apache
# Python
# Linux (SuSe)
# MySQL
# psyco, a dynamic python->C compiler
# lighttpd for video instead of Apache

What's Inside?

The Stats

# Supports the delivery of over 100 million videos per day.
# Founded 2/2005
# 3/2006 30 million video views/day
# 7/2006 100 million video views/day
# 2 sysadmins, 2 scalability software architects
# 2 feature developers, 2 network engineers, 1 DBA

Recipe for handling rapid growth


while (true)
{
identify_and_fix_bottlenecks();
drink();
sleep();
notice_new_bottleneck();
}

This loop runs many times a day.

Web Servers

# NetScalar is used for load balancing and caching static content.
# Run Apache with mod_fast_cgi.
# Requests are routed for handling by a Python application server.
# Application server talks to various databases and other informations sources to get all the data and formats the html page.
# Can usually scale web tier by adding more machines.
# The Python web code is usually NOT the bottleneck, it spends most of its time blocked on RPCs.
# Python allows rapid flexible development and deployment. This is critical given the competition they face.
# Usually less than 100 ms page service times.
# Use psyco, a dynamic python->C compiler that uses a JIT compiler approach to optimize inner loops.
# For high CPU intensive activities like encryption, they use C extensions.
# Some pre-generated cached HTML for expensive to render blocks.
# Row level caching in the database.
# Fully formed Python objects are cached.
# Some data are calculated and sent to each application so the values are cached in local memory. This is an underused strategy. The fastest cache is in your application server and it doesn't take much time to send precalculated data to all your servers. Just have an agent that watches for changes, precalculates, and sends.

Video Serving

# Costs include bandwidth, hardware, and power consumption.
# Each video hosted by a mini-cluster. Each video is served by more than one machine.
# Using a a cluster means:
- More disks serving content which means more speed.
- Headroom. If a machine goes down others can take over.
- There are online backups.
# Servers use the lighttpd web server for video:
- Apache had too much overhead.
- Uses epoll to wait on multiple fds.
- Switched from single process to multiple process configuration to handle more connections.
# Most popular content is moved to a CDN (content delivery network):
- CDNs replicate content in multiple places. There's a better chance of content being closer to the user, with fewer hops, and content will run over a more friendly network.
- CDN machines mostly serve out of memory because the content is so popular there's little thrashing of content into and out of memory.
# Less popular content (1-20 views per day) uses YouTube servers in various colo sites.
- There's a long tail effect. A video may have a few plays, but lots of videos are being played. Random disks blocks are being accessed.
- Caching doesn't do a lot of good in this scenario, so spending money on more cache may not make sense. This is a very interesting point. If you have a long tail product caching won't always be your performance savior.
- Tune RAID controller and pay attention to other lower level issues to help.
- Tune memory on each machine so there's not too much and not too little.

Serving Video Key Points

# Keep it simple and cheap.
# Keep a simple network path. Not too many devices between content and users. Routers, switches, and other appliances may not be able to keep up with so much load.
# Use commodity hardware. More expensive hardware gets the more expensive everything else gets too (support contracts). You are also less likely find help on the net.
# Use simple common tools. They use most tools build into Linux and layer on top of those.
# Handle random seeks well (SATA, tweaks).

Serving Thumbnails

# Surprisingly difficult to do efficiently.
# There are a like 4 thumbnails for each video so there are a lot more thumbnails than videos.
# Thumbnails are hosted on just a few machines.
# Saw problems associated with serving a lot of small objects:
- Lots of disk seeks and problems with inode caches and page caches at OS level.
- Ran into per directory file limit. Ext3 in particular. Moved to a more hierarchical structure. Recent improvements in the 2.6 kernel may improve Ext3 large directory handling up to 100 times, yet storing lots of files in a file system is still not a good idea.
- A high number of requests/sec as web pages can display 60 thumbnails on page.
- Under such high loads Apache performed badly.
- Used squid (reverse proxy) in front of Apache. This worked for a while, but as load increased performance eventually decreased. Went from 300 requests/second to 20.
- Tried using lighttpd but with a single threaded it stalled. Run into problems with multiprocesses mode because they would each keep a separate cache.
- With so many images setting up a new machine took over 24 hours.
- Rebooting machine took 6-10 hours for cache to warm up to not go to disk.
# To solve all their problems they started using Google's BigTable, a distributed data store:
- Avoids small file problem because it clumps files together.
- Fast, fault tolerant. Assumes its working on a unreliable network.
- Lower latency because it uses a distributed multilevel cache. This cache works across different collocation sites.
- For more information on BigTable take a look at Google Architecture, GoogleTalk Architecture, and BigTable.

Databases

# The Early Years
- Use MySQL to store meta data like users, tags, and descriptions.
- Served data off a monolithic RAID 10 Volume with 10 disks.
- Living off credit cards so they leased hardware. When they needed more hardware to handle load it took a few days to order and get delivered.
- They went through a common evolution: single server, went to a single master with multiple read slaves, then partitioned the database, and then settled on a sharding approach.
- Suffered from replica lag. The master is multi-threaded and runs on a large machine so it can handle a lot of work. Slaves are single threaded and usually run on lesser machines and replication is asynchronous, so the slaves can lag significantly behind the master.
- Updates cause cache misses which goes to disk where slow I/O causes slow replication.
- Using a replicating architecture you need to spend a lot of money for incremental bits of write performance.
- One of their solutions was prioritize traffic by splitting the data into two clusters: a video watch pool and a general cluster. The idea is that people want to watch video so that function should get the most resources. The social networking features of YouTube are less important so they can be routed to a less capable cluster.
# The later years:
- Went to database partitioning.
- Split into shards with users assigned to different shards.
- Spreads writes and reads.
- Much better cache locality which means less IO.
- Resulted in a 30% hardware reduction.
- Reduced replica lag to 0.
- Can now scale database almost arbitrarily.

Data Center Strategy

# Used manage hosting providers at first. Living off credit cards so it was the only way.
# Managed hosting can't scale with you. You can't control hardware or make favorable networking agreements.
# So they went to a colocation arrangement. Now they can customize everything and negotiate their own contracts.
# Use 5 or 6 data centers plus the CDN.
# Videos come out of any data center. Not closest match or anything. If a video is popular enough it will move into the CDN.
# Video bandwidth dependent, not really latency dependent. Can come from any colo.
# For images latency matters, especially when you have 60 images on a page.
# Images are replicated to different data centers using BigTable. Code
looks at different metrics to know who is closest.

Lessons Learned

# Stall for time. Creative and risky tricks can help you cope in the short term while you work out longer term solutions.

# Prioritize. Know what's essential to your service and prioritize your resources and efforts around those priorities.

# Pick your battles. Don't be afraid to outsource some essential services. YouTube uses a CDN to distribute their most popular content. Creating their own network would have taken too long and cost too much. You may have similar opportunities in your system. Take a look at Software as a Service for more ideas.

# Keep it simple! Simplicity allows you to rearchitect more quickly so you can respond to problems. It's true that nobody really knows what simplicity is, but if you aren't afraid to make changes then that's a good sign simplicity is happening.

# Shard. Sharding helps to isolate and constrain storage, CPU, memory, and IO. It's not just about getting more writes performance.

# Constant iteration on bottlenecks:
- Software: DB, caching
- OS: disk I/O
- Hardware: memory, RAID

# You succeed as a team. Have a good cross discipline team that understands the whole system and what's underneath the system. People who can set up printers, machines, install networks, and so on. With a good team all things are possible.

Flickr Architecture

Update: Flickr hits 2 Billion photos served. That's a lot of hamburgers.

Flickr is both my favorite bird and the web's leading photo sharing site. Flickr has an amazing challenge, they must handle a vast sea of ever expanding new content, ever increasing legions of users, and a constant stream of new features, all while providing excellent performance. How do they do it?

Site: http://www.flickr.com/

Information Sources

# Flickr and PHP (an early document)
# Capacity Planning for LAMP
# Federation at Flickr: Doing Billions of Queries a Day by Dathan Pattishall.
# Building Scalable Web Sites by Cal Henderson from Flickr.
# Database War Stories #3: Flickr by Tim O'Reilly
# Cal Henderson's Talks. A lot of useful PowerPoint presentations.

Platform

# PHP
# MySQL
# Shards
# Memcached for a caching layer.
# Squid in reverse-proxy for html and images.
# Linux (RedHat)
# Smarty for templating
# Perl
# PEAR for XML and Email parsing
# ImageMagick, for image processing
# Java, for the node service
# Apache
# SystemImager for deployment
# Ganglia for distributed system monitoring
# Subcon stores essential system configuration files in a subversion repository for easy deployment to machines in a cluster.
# Cvsup for distributing and updating collections of files across a network.

The Stats

# More than 4 billion queries per day.
# ~35M photos in squid cache (total)
# ~2M photos in squid’s RAM
# ~470M photos, 4 or 5 sizes of each
# 38k req/sec to memcached (12M objects)
# 2 PB raw storage (consumed about ~1.5TB on Sunday
# Over 400,000 photos being added every day

The Architecture

# A pretty picture of Flickr's architecture can be found on this slide . A simple depiction is:
-- Pair of ServerIron's
---- Squid Caches
------ Net App's
---- PHP App Servers
------ Storage Manager
------ Master-master shards
------ Dual Tree Central Database
------ Memcached Cluster
------ Big Search Engine

- The Dual Tree structure is a custom set of changes to MySQL that allows scaling by incrementally adding masters without a ring architecture. This allows cheaper scaling because you need less hardware as compared to master-master setups which always requires double the hardware.
- The central database includes data like the 'users' table, which includes primary user
keys (a few different IDs) and a pointer to which shard a users' data can be found on.

# Use dedicated servers for static content.
# Talks about how to support Unicode.
# Use a share nothing architecture.
# Everything (except photos) are stored in the database.
# Statelessness means they can bounce people around servers and it's easier to make their APIs.
# Scaled at first by replication, but that only helps with reads.
# Create a search farm by replicating the portion of the database they want to search.
# Use horizontal scaling so they just need to add more machines.
# Handle pictures emailed from users by parsing each email is it's delivered in PHP. Email is parsed for any photos.
# Earlier they suffered from Master-Slave lag. Too much load and they had a single point of failure.
# They needed the ability to make live maintenance, repair data, and so forth, without taking the site down.
# Lots of excellent material on capacity planning. Take a look in the Information Sources for more details.
# Went to a federated approach so they can scale far into the future:
- Shards: My data gets stored on my shard, but the record of performing action on your comment, is on your shard. When making a comment on someone else's’ blog
- Global Ring: Its like DNS, you need to know where to go and who controls where you go. Every page view, calculate where your data is, at that moment of time.
- PHP logic to connect to the shards and keep the data consistent (10 lines of code with comments!)
# Shards:
- Slice of the main database
- Active Master-Master Ring Replication: a few drawbacks in MySQL 4.1, as honoring commits in Master-Master. AutoIncrement IDs are automated to keep it Active Active.
- Shard assignments are from a random number for new accounts
- Migration is done from time to time, so you can remove certain power users. Needs to be balanced if you have a lot of photos… 192,000 photos, 700,000 tags, will take about 3-4 minutes. Migration is done manually.
# Clicking a Favorite:
- Pulls the Photo owners Account from Cache, to get the shard location (say on shard-5)
- Pulls my Information from cache, to get my shard location (say on shard-13)
- Starts a “distributed transaction” - to answer the question: Who favorited the photo? What are my favorites?
# Can ask question from any shard, and recover data. Its absolutely redundant.
# To get rid of replication lag…
- every page load, the user is assigned to a bucket
- if host is down, go to next host in the list; if all hosts are down, display an error page. They don’t use persistent connections, they build connections and tear it down. Every page load thus, tests the connection.
# Every users reads and writes are kept in one shard. Notion of replication lag is gone.
# Each server in shard is 50% loaded. Shut down 1/2 the servers in each shard. So 1 server in the shard can take the full load if a server of that shard is down or in maintenance mode. To upgrade you just have to shut down half the shard, upgrade that half, and then repeat the process.
# Periods of time when traffic spikes, they break the 50% rule though. They do something like 6,000-7,000 queries per second. Now, its designed for at most 4,000 queries per second to keep it at 50% load.
# Average queries per page, are 27-35 SQL statements. Favorites counts are real time. API access to the database is all real time. Achieved the real time requirements without any disadvantages.
# Over 36,000 queries per second - running within capacity threshold. Burst of traffic, double 36K/qps.
# Each Shard holds 400K+ users data.
- A lot of data is stored twice. For example, a comment is part of the relation between the commentor and the commentee. Where is the comment stored? How about both places? Transactions are used to prevent out of sync data: open transaction 1, write commands, open transaction 2, write commands, commit 1st transaction if all is well, commit 2nd transaction if 1st committed. but there still a chance for failure when a box goes down during the 1st commit.
# Search:
- Two search back-ends: shards 35k qps on a few shards and Yahoo!’s (proprietary) web search
- Owner’s single tag search or a batch tag change (say, via Organizr) goes to the Shards due to real-time requirements, everything else goes to Yahoo!’s engine (probably about 90% behind the real-time goodness)
- Think of it such that you’ve got Lucene-like search
# Hardware:
- EMT64 w/RHEL4, 16GB RAM
- 6-disk 15K RPM RAID-10.
- Data size is at 12 TB of user metadata (these are not photos, this is just innodb ibdata files - the photos are a lot larger).
- 2U boxes. Each shard has~120GB of data.
# Backup procedure:
- ibbackup on a cron job, that runs across various shards at different times. Hotbackup to a spare.
- Snapshots are taken every night across the entire cluster of databases.
- Writing or deleting several huge backup files at once to a replication filestore can wreck performance on that filestore for the next few hours as it replicates the backup files. Doing this to an in-production photo storage filer is a bad idea.
- However much it costs to keep multiple days of backups of all of your data, it's worth it. Keeping staggered backups is good for when you discover something gone wrong a few days later. something like 1, 2, 10 and 30 day backups.
# Photos are stored on the filer. Upon upload, it processes the photos, gives you different sizes, then its complete. Metadata and points to the filers, are stored in the database.
# Aggregating the data: Very fast, because its a process per shard. Stick it into a table, or recover data from another copy from other users shards.
# max_connections = 400 connections per shard, or 800 connections per server & shard. Plenty of capacity and connections. Thread cache is set to 45, because you don’t have more than 45 users having simultaneous activity.
# Tags:
- Tags do not fit well with traditional normalized RDBMs schema design. Denormalization or heavy caching is the only way to generate a tag cloud in milliseconds for hundreds of millions of tags.
- Some of their data views are calculated offline by dedicated processing clusters which save the results into MySQL because some relationships are so complicated to calculate it would absorb all the database CPU cycles.
# Future Direction:
- Make it faster with real-time BCP, so all data centers can receive writes to the data layer (db, memcache, etc) all at the same time. Everything is active nothing will ever be idle.

Lessons Learned

# Think of your application as more than just a web application. You'll have REST APIs, SOAP APIs, RSS feeds, Atom feeds, etc.

# Go stateless. Statelessness makes for a simpler more robust system that can handle upgrades without flinching.

# Re-architecting your database sucks.

# Capacity plan. Bring capacity planning into the product discussion EARLY. Get buy-in from the $$$ people (and engineering management) that it’s something to watch.

# Start slow. Don’t buy too much equipment just because you’re scared/happy that your site will explode.

# Measure reality. Capacity planning math should be based on real things, not abstract ones.

# Build in logging and metrics. Usage stats are just as important as server stats. Build in custom metrics to measure real-world usage to server-based stats.

# Cache. Caching and RAM is the answer to everything.

# Abstract. Create clear levels of abstraction between database work, business logic, page logic, page mark-up and the presentation layer. This supports quick turn around iterative development.

# Layer. Layering allows developers to create page level logic which designers can use to build the user experience. Designers can ask for page logic as needed. It's a negotiation between the two parties.

# Release frequently. Even every 30 minutes.

# Forget about small efficiencies, about 97% of the time. Premature optimization is the root of all evil.

# Test in production. Build into the architecture mechanisms (config flags, load balancing, etc.) with which you can deploy new hardware easily into (and out of) production.

# Forget benchmarks. Benchmarks are fine for getting a general idea of capabilities, but not for planning. Artificial tests give artificial results, and the time is better used with testing for real.

# Find ceilings.
- What is the maximum something that every server can do ?
- How close are you to that maximum, and how is it trending ?
- MySQL (disk IO ?)
- SQUID (disk IO ? or CPU ?)
- memcached (CPU ? or network ?)

# Be sensitive to the usage patterns for your type of application.
- Do you have event related growth? For example: disaster, news event.
- Flickr gets 20-40% more uploads on first work day of the year than any previous peak the previous year.
- 40-50% more uploads on Sundays than the rest of the week, on average

# Be sensitive to the demands of exponential growth. More users means more content, more content means more connections, more connections mean more usage.

# Plan for peaks. Be able to handle peak loads up and down the stack.

Digg Architecture

Update 2:: How Digg Works and How Digg Really Works (wear ear plugs). Brought to you straight from Digg's blog. A very succinct explanation of the major elements of the Digg architecture while tracing a request through the system. I've updated this profile with the new information.
Update: Digg now receives 230 million plus page views per month and 26 million unique visitors - traffic that necessitated major internal upgrades.

Traffic generated by Digg's over 22 million famously info-hungry users and 230 million page views can crash an unsuspecting website head-on into its CPU, memory, and bandwidth limits. How does Digg handle billions of requests a month?

Site: http://digg.com

Information Sources

# How Digg Works by Digg
# How Digg.com uses the LAMP stack to scale upward
# Digg PHP's Scalability and Performance

Platform

# MySQL
# Linux
# PHP
# Lucene
# Python
# APC PHP Accelerator
# MCache
# Gearman - job scheduling system
# MogileFS - open source distributed filesystem
# Apache
# Memcached

The Stats

# Started in late 2004 with a single Linux server running Apache 1.3, PHP 4, and MySQL. 4.0 using the default MyISAM storage engine
# Over 22 million users.
# 230 million plus page views per month
# 26 million unique visitors per month
# Several billion page views per month
# None of the scaling challenges faced had anything to do with PHP. The biggest issues faced were database related.
# Dozens of web servers.
# Dozens of DB servers.
# Six specialized graph database servers to run the Recommendation Engine.
# Six to ten machines that serve files from MogileFS.

What's Inside

# Specialized load balancer appliances monitor the application servers, handle failover, constantly adjust the cluster according to health, balance incoming requests and caching JavaScript, CSS and images. If you don't have the fancy load balancers take a look at Linux Virtual Server and Squid as a replacement.
# Requests are passed to the Application Server cluster. Application servers consist of: Apache+PHP, Memcached, Gearman and other daemons. They are responsible for making coordinating access to different services (DB, MogileFS, etc) and creating the response sent to the browser.
# Uses a MySQL master-slave setup.
- Four master databases are partitioned by functionality: promotion, profiles, comments, main. Many slave databases hang off each master.
- Writes go to the masters and reads go to the slaves.
- Transaction-heavy servers use the InnoDB storage engine.
- OLAP-heavy servers use the MyISAM storage engine.
- They did not notice a performance degradation moving from MySQL 4.1 to version 5.
- The schema is denormalized more than "your average database design."
- Sharding is used to break the database into several smaller ones.
# Digg's usage pattern makes it easier for them to scale. Most people just view the front page and leave. Thus 98% of Digg's database accesses are reads. With this balance of operations they don't have to worry about the complex work of architecting for writes, which makes it a lot easier for them to scale.
# They had problems with their storage system telling them writes were on disk when they really weren't. Controllers do this to improve the appearance of their performance. But what it does is leave a giant data integrity whole in failure scenarios. This is really a pretty common problem and can be hard to fix, depending on your hardware setup.
# To lighten their database load they used the APC PHP accelerator MCache.
# Memcached is used for caching and memcached servers seemed to be spread across their database and application servers. A specialized daemon monitors connections and kills connections that have been open too long.
# You can configure PHP not parse and compile on each load using a combination of Apache 2’s worker threads, FastCGI, and a PHP accelerator. On a page's first load the PHP code is compiles so any subsequent page loads are very fast.
# MogileFS, a distributed file system, serves story icons, user icons, and stores copies of each story’s source. A distributed file system spreads and replicates files across a lot of disks which supports fast and scalable file access.
# A specialized Recommendation Engine service was built to act as their distributed graph database. Relational databases are not well structured for generating recommendations so a separate service was created. LinkedIn did something similar for their graph.

Lessons Learned

# The number of machines isn't as important what the pieces are and how they fit together.
# Don't treat the database as a hammer. Recommendations didn't fit will with the relational model so they made a specialized service.
# Tune MySQL through your database engine selection. Use InnoDB when you need transactions and MyISAM when you don't. For example, transactional tables on the master can use MyISAM for read-only slaves.
# At some point in their growth curve they were unable to grow by adding RAM so had to grow through architecture.
# People often complain Digg is slow. This is perhaps due to their large javascript libraries rather than their backend architecture.
# One way they scale is by being careful of which application they deploy on their system. They are careful not to release applications which use too much CPU. Clearly Digg has a pretty standard LAMP architecture, but I thought this was an interesting point. Engineers often have a bunch of cool features they want to release, but those features can kill an infrastructure if that infrastructure doesn't grow along with the features. So push back until your system can handle the new features. This goes to capacity planning, something the Flickr emphasizes in their scaling process.
# You have to wonder if by limiting new features to match their infrastructure might Digg lose ground to other faster moving social bookmarking services? Perhaps if the infrastructure was more easily scaled they could add features faster which would help them compete better? On the other hand, just adding features because you can doesn't make a lot of sense either.
# The data layer is where most scaling and performance problems are to be found and these are language specific. You'll hit them using Java, PHP, Ruby, or insert your favorite language here.

Google Architecture

Update: Greg Linden points to a new Google article MapReduce: simplified data processing on large clusters. Some interesting stats: 100k MapReduce jobs are executed each day; more than 20 petabytes of data are processed per day; more than 10k MapReduce programs have been implemented; machines are dual processor with gigabit ethernet and 4-8 GB of memory.

Google is the King of scalability. Everyone knows Google for their large, sophisticated, and fast searching, but they don't just shine in search. Their platform approach to building scalable applications allows them to roll out internet scale applications at an alarmingly high competition crushing rate. Their goal is always to build a higher performing higher scaling infrastructure to support their products. How do they do that?

Information Sources

# Video: Building Large Systems at Google
# Google Lab: The Google File System
# Google Lab: MapReduce: Simplified Data Processing on Large Clusters
# Google Lab: BigTable.
# Video: BigTable: A Distributed Structured Storage System.
# Google Lab: The Chubby Lock Service for Loosely-Coupled Distributed Systems.
# How Google Works by David Carr in Baseline Magazine.
# Google Lab: Interpreting the Data: Parallel Analysis with Sawzall.
# Dare Obasonjo's Notes on the scalability conference.

Platform

# Linux
# A large diversity of languages: Python, Java, C++

What's Inside?

The Stats

# Estimated 450,000 low-cost commodity servers in 2006
# In 2005 Google indexed 8 billion web pages. By now, who knows?
# Currently there over 200 GFS clusters at Google. A cluster can have 1000 or even 5000 machines. Pools of tens of thousands of machines retrieve data from GFS clusters that run as large as 5 petabytes of storage. Aggregate read/write throughput can be as high as 40 gigabytes/second across the cluster.
# Currently there are 6000 MapReduce applications at Google and hundreds of new applications are being written each month.
# BigTable scales to store billions of URLs, hundreds of terabytes of satellite imagery, and preferences for hundreds of millions of users.

The Stack

Google visualizes their infrastructure as a three layer stack:

# Products: search, advertising, email, maps, video, chat, blogger
# Distributed Systems Infrastructure: GFS, MapReduce, and BigTable.
# Computing Platforms: a bunch of machines in a bunch of different data centers
# Make sure easy for folks in the company to deploy at a low cost.
# Look at price performance data on a per application basis. Spend more money on hardware to not lose log data, but spend less on other types of data. Having said that, they don't lose data.

Reliable Storage Mechanism with GFS (Google File System)

# Reliable scalable storage is a core need of any application. GFS is their core storage platform.
# Google File System - large distributed log structured file system in which they throw in a lot of data.
# Why build it instead of using something off the shelf? Because they control everything and it's the platform that distinguishes them from everyone else. They required:
- high reliability across data centers
- scalability to thousands of network nodes
- huge read/write bandwidth requirements
- support for large blocks of data which are gigabytes in size.
- efficient distribution of operations across nodes to reduce bottlenecks
# System has master and chunk servers.
- Master servers keep metadata on the various data files. Data are stored in the file system in 64MB chunks. Clients talk to the master servers to perform metadata operations on files and to locate the chunk server that contains the needed they need on disk.
- Chunk servers store the actual data on disk. Each chunk is replicated across three different chunk servers to create redundancy in case of server crashes. Once directed by a master server, a client application retrieves files directly from chunk servers.
# A new application coming on line can use an existing GFS cluster or they can make your own. It would be interesting to understand the provisioning process they use across their data centers.
# Key is enough infrastructure to make sure people have choices for their application. GFS can be tuned to fit individual application needs.

Do Something With the Data Using MapReduce

# Now that you have a good storage system, how do you do anything with so much data? Let's say you have many TBs of data stored across a 1000 machines. Databases don't scale or cost effectively scale to those levels. That's where MapReduce comes in.
# MapReduce is a programming model and an associated implementation for processing and generating large data sets. Users specify a map function that processes a key/value pair to generate a set of intermediate key/value pairs, and a reduce function that merges all intermediate values associated with the same intermediate key. Many real world tasks are expressible in this model. Programs written in this functional style are automatically parallelized and executed on a large cluster of commodity machines. The run-time system takes care of the details of partitioning the input data, scheduling the program's execution across a set of machines, handling machine failures, and managing the required inter-machine communication. This allows programmers without any experience with parallel and distributed systems to easily utilize the resources of a large distributed system.
# Why use MapReduce?
- Nice way to partition tasks across lots of machines.
- Handle machine failure.
- Works across different application types, like search and ads. Almost every application has map reduce type operations. You can precompute useful data, find word counts, sort TBs of data, etc.
- Computation can automatically move closer to the IO source.
# The MapReduce system has three different types of servers.
- The Master server assigns user tasks to map and reduce servers. It also tracks the state of the tasks.
- The Map servers accept user input and performs map operations on them. The results are written to intermediate files
- The Reduce servers accepts intermediate files produced by map servers and performs reduce operation on them.
# For example, you want to count the number of words in all web pages. You would feed all the pages stored on GFS into MapReduce. This would all be happening on 1000s of machines simultaneously and all the coordination, job scheduling, failure handling, and data transport would be done automatically.
- The steps look like: GFS -> Map -> Shuffle -> Reduction -> Store Results back into GFS.
- In MapReduce a map maps one view of data to another, producing a key value pair, which in our example is word and count.
- Shuffling aggregates key types.
- The reductions sums up all the key value pairs and produces the final answer.
# The Google indexing pipeline has about 20 different map reductions. A pipeline looks at data with a whole bunch of records and aggregating keys. A second map-reduce comes a long, takes that result and does something else. And so on.
# Programs can be very small. As little as 20 to 50 lines of code.
# One problem is stragglers. A straggler is a computation that is going slower than others which holds up everyone. Stragglers may happen because of slow IO (say a bad controller) or from a temporary CPU spike. The solution is to run multiple of the same computations and when one is done kill all the rest.
# Data transferred between map and reduce servers is compressed. The idea is that because servers aren't CPU bound it makes sense to spend on data compression and decompression in order to save on bandwidth and I/O.

Storing Structured Data in BigTable

# BigTable is a large scale, fault tolerant, self managing system that includes terabytes of memory and petabytes of storage. It can handle millions of reads/writes per second.
# BigTable is a distributed hash mechanism built on top of GFS. It is not a relational database. It doesn't support joins or SQL type queries.
# It provides lookup mechanism to access structured data by key. GFS stores opaque data and many applications needs has data with structure.
# Commercial databases simply don't scale to this level and they don't work across 1000s machines.
# By controlling their own low level storage system Google gets more control and leverage to improve their system. For example, if they want features that make cross data center operations easier, they can build it in.
# Machines can be added and deleted while the system is running and the whole system just works.
# Each data item is stored in a cell which can be accessed using a row key, column key, or timestamp.
# Each row is stored in one or more tablets. A tablet is a sequence of 64KB blocks in a data format called SSTable.
# BigTable has three different types of servers:
- The Master servers assign tablets to tablet servers. They track where tablets are located and redistributes tasks as needed.
- The Tablet servers process read/write requests for tablets. They split tablets when they exceed size limits (usually 100MB - 200MB). When a tablet server fails, then a 100 tablet servers each pickup 1 new tablet and the system recovers.
- The Lock servers form a distributed lock service. Operations like opening a tablet for writing, Master aribtration, and access control checking require mutual exclusion.
# A locality group can be used to physically store related bits of data together for better locality of reference.
# Tablets are cached in RAM as much as possible.

Hardware

# When you have a lot of machines how do you build them to be cost efficient and use power efficiently?
# Use ultra cheap commodity hardware and built software on top to handle their death.
# A 1,000-fold computer power increase can be had for a 33 times lower cost if you you use a failure-prone infrastructure rather than an infrastructure built on highly reliable components. You must build reliability on top of unreliability for this strategy to work.
# Linux, in-house rack design, PC class mother boards, low end storage.
# Price per wattage on performance basis isn't getting better. Have huge power and cooling issues.
# Use a mix of collocation and their own data centers.

Misc

# Push changes out quickly rather than wait for QA.
# Libraries are the predominant way of building programs.
# Some are applications are provided as services, like crawling.
# An infrastructure handles versioning of applications so they can be release without a fear of breaking things.

Future Directions for Google

# Support geo-distributed clusters.
# Create a single global namespace for all data. Currently data is segregated by cluster.
# More and better automated migration of data and computation.
# Solve consistency issues that happen when you couple wide area replication with network partitioning (e.g. keeping services up even if a cluster goes offline for maintenance or due to some sort of outage).

Lessons Learned

# Infrastructure can be a competitive advantage. It certainly is for Google. They can roll out new internet services faster, cheaper, and at scale at few others can compete with. Many companies take a completely different approach. Many companies treat infrastructure as an expense. Each group will use completely different technologies and their will be little planning and commonality of how to build systems. Google thinks of themselves as a systems engineering company, which is a very refreshing way to look at building software.

# Spanning multiple data centers is still an unsolved problem. Most websites are in one and at most two data centers. How to fully distribute a website across a set of data centers is, shall we say, tricky.

# Take a look at Hadoop (product) if you don't have the time to rebuild all this infrastructure from scratch yourself. Hadoop is an open source implementation of many of the same ideas presented here.

# An under appreciated advantage of a platform approach is junior developers can quickly and confidently create robust applications on top of the platform. If every project needs to create the same distributed infrastructure wheel you'll run into difficulty because the people who know how to do this are relatively rare.

# Synergy isn't always crap. By making all parts of a system work together an improvement in one helps them all. Improve the file system and everyone benefits immediately and transparently. If every project uses a different file system then there's no continual incremental improvement across the entire stack.

# Build self-managing systems that work without having to take the system down. This allows you to more easily rebalance resources across servers, add more capacity dynamically, bring machines off line, and gracefully handle upgrades.

# Create a Darwinian infrastructure. Perform time consuming operation in parallel and take the winner.

# Don't ignore the Academy. Academia has a lot of good ideas that don't get translated into production environments. Most of what Google has done has prior art, just not prior large scale deployment.

# Consider compression. Compression is a good option when you have a lot of CPU to throw around and limited IO.

eBay Architecture

Update 2: EBay's Randy Shoup spills the secrets of how to service hundreds of millions of users and over two billion page views a day in Scalability Best Practices: Lessons from eBay on InfoQ. The practices: Partition by Function, Split Horizontally, Avoid Distributed Transactions, Decouple Functions Asynchronously, Move Processing To Asynchronous Flows, Virtualize At All Levels, Cache Appropriately.
Update: eBay Serves 5 Billion API Calls Each Month. Aren't we seeing more and more traffic driven by mashups composed on top of open APIs? APIs are no longer a bolt on, they are your application. Architecturally that argues for implementing your own application around the same APIs developers and users employ.

Who hasn't wondered how eBay does their business? As one of the largest most loaded websites in the world, it can't be easy. And the subtitle of the presentation hints at how creating such a monster system requires true engineering: Striking a balance between site stability, feature velocity, performance, and cost.

You may not be able to emulate how eBay scales their system, but the issues and possible solutions are worth learning from.

Site: http://ebay.com

Information Sources

# The eBay Architecture - Striking a balance between site stability, feature velocity, performance, and cost.
# Podcast: eBay’s Transactions on a Massive Scale
# Dan Pritchett on Architecture at eBay interview by InfoQ

Platform

# Java
# Oracle
# WebSphere, servlets
# Horizontal Scaling
# Sharding
# Mix of Windows and Unix

What's Inside?

This information was adapted from Johannes Ernst's Blog

The Stats

# On an average day, it runs through 26 billion SQL queries and keeps tabs on 100 million items available for purchase.
# 212 million registered users, 1 billion photos
# 1 billion page views a day, 105 million listings, 2 petabytes of data, 3 billion API calls a month
# Something like a factor of 35 in page views, e-mails sent, bandwidth from June 1999 to Q3/2006.
# 99.94% availability, measured as "all parts of site functional to everybody" vs. at least one part of a site not functional to some users somewhere
# The database is virtualized and spans 600 production instances residing in more than 100 server clusters.
# 15,000 application servers, all J2EE. About 100 groups of functionality aka "apps". Notion of a "pool": "all the machines that deal with selling"...

The Architecture

# Everything is planned with the question "what if load increases by 10x". Scaling only horizontal, not vertical: many parallel boxes.
# Architectures is strictly divided into layers: data tier, application tier, search, operations,
# Leverages MSXML framework for presentation layer (even in Java)
# Oracle databases, WebSphere Java (still 1.3.1)
# Split databases by primary access path, modulo on a key.
# Every database has at least 3 on-line databases. Distributed over 8 data centers
# Some database copies run 15 min behind, 4 hours behind
# Databases are segmented by function: user, item account, feedback, transaction, over 70 in all.
# No stored procedures are used. There are some very simple triggers.
# Move cpu-intensive work moved out of the database layer to applications applications layer: referential integrity, joins, sorting done in the application layer! Reasoning: app servers are cheap, databases are the bottleneck.
# No client-side transactions. no distributed transactions
# J2EE: use servlets, JDBC, connection pools (with rewrite). Not much else.
# No state information in application tier. Transient state maintained in cookie or scratch database.
# App servers do not talk to each other -- strict layering of architecture
# Search, in 2002: 9 hours to update the index running on largest Sun box available -- not keeping up.
# Average item on site changes its search data 5 times before it is sold (e.g. price), so real-time search results are extremely important.
# "Voyager": real-time feeder infrastructure built by eBay.. Uses reliable multicast from primary database to search nodes, in-memory search index, horizontal segmentation, N slices, load-balances over M instances, cache queries.

Lessons Learned

# Scale Out, Not Up
– Horizontal scaling at every tier.
– Functional decomposition.

# Prefer Asynchronous Integration
– Minimize availability coupling.
– Improve scaling options.

# Virtualize Components
– Reduce physical dependencies.
– Improve deployment flexibility.

# Design for Failure
– Automated failure detection and notification.
– “Limp mode” operation of business features.

# Move work out of the database into the applications because the database is the bottleneck. Ebay does this in the extreme. We see it in other architecture using caching and the file system, but eBay even does a lot of traditional database operations in applications (like joins).

# Use what you like and toss what you don't need. Ebay didn't feel compelled to use full blown J2EE stack. They liked Java and Servlets so that's all they used. You don't have to buy into any framework completely. Just use what works for you.

# Don't be afraid to build solutions that meet and evolve with your needs. Every off the shelf solution will fail you at some point. You have to go the rest of the way on your own.

# Operational controls become a larger and larger part of scalability as you grow. How do you upgrade, configure, and monitor thousands of machines will running a live system?

# Architectures evolve. You need to be able to change, refine, and develop your new system while keeping your existing site running. That's the primary challenge of any growing website.

# It's a mistake to worry too much about scalability from the start. Don't suffer from paralysis by analysis and worrying about traffic that may never come.

# It's also a mistake not to worry about scalability at all. You need to develop an organization capable of dealing with architecture evolution. Understand you are never done. Your system will always evolve and change. Build those expectations and capabilities into your business from the start. Don't let people and organizations be why your site fails. Many people will think the system should be perfect from the start. It doesn't work that way. A good system is developed overtime in response to real issues and concerns. Expect change and adapt to change.

大型网站架构系列之三,多对多关系的优化设计

上篇大型网站架构系列之二,底层架构概论中以用户数据表为例介绍了基本的数据分割方案以及基本的配置方案。但是在2.0时代,这种简单的列表索引已经远远实现起来是问题的,多对多关系将是最常见的关系。现在我们针对web2.0数据中广泛存在的多对多关系进行阐述和具体行为判断,比如一个很简单的例子,在2.0时代,好友功能是最常被用到的,每个用户会有很多的好友,同时也会是很多人的好友,那么这个数据量将会是用户数的平方的级别。同样,对于文章标签,每个文章可以有多个标签,而每个标签又可以有多个文章,这又是一个几何乘积,数据量又会是个天文数字。

传统的处理方案有两种,一种是通过SEARCH的方法来实现,一种是通过另建一个索引表,存贮对应的ID以进行存贮。对于第一种方案,因为要涉及大量的LIKE查询,性能不敢恭维,第二种的情况下,数据库的行的数量也是惊人海量级别的,并且要跨表跨区查询,还要维护数据的唯一性,数据处理过程相当的复杂性能也就不言而喻了。

文入正题,下面对数据多对多关系举出来具体的解决方案,我们这里以标签和文章之间的多对多关系为例来讲解,大家可以举一反三的思考群组和用户之间,相册和被圈用户之间等等复杂的多对多关系。

首先滤清一下流程,我们以传统方案的第二种为例,在传统的数据库设计中我们是如下走的:当一篇博文发布的时候并插入标签的时候一般是三步走(也可以理解为四步,以为还要判断标签是否存在的问题),第一步插入文章数据库并获取文章的ID,第二步插入标签数据库同时查询标签是否存在,如果存在就取出标签的ID,否则的话插入新标签并取出ID,第三部,将文章的ID和标签的ID插入索引表来建立关联。如果这个时候在索引表上建立了索引的话就是灾难性的,特别是在数据量大的情况下,尽管它可以有效的提高查询速度,但是发布的速度可能就会让人无法忍受了。

我们处理的方法也是三部曲,对多对多关系进行进一步的处理。
用标签的时候,我们用的最多的就是查询标签下的文章和显示文章的标签,所以我们实现这例就成了。
第一步,抛弃索引表。
对文章做冗余字段,加一个TAG列,我们可以讲TAG的标签如下写[TagID,TagName]| [TagID,TagName]| [TagID,TagName] 同样 对于TAG表,我们做如下冗余加个Article字段,如下内容[ArticleID,Title]| [ArticleID, Title]| [ArticleID, Title],在需要增加的时候我们只要APPEND一下就可以了,至于ARTICLE的结构和TAG的结构可以参考我上一篇文章的介绍。其实根据需要还可以存贮更多。
有人会问,为什么要存贮TagName和ArticleTitle呢,其实是为了避免跨表查询和INNERJOIN查询来做的,In查询和跨表查询会造成全表遍历,所以我们在执行的时候In查询是必须要找到一个有效的替代方法的。

第二部:异步加载。
在设计模式下我们常思考的是单件模式,我们采用另类的单件模式来处理,也就是把文章和标签之间的索引作为专门的进程来做,异步的实现。
为了避免文章在发布的时候以为要检查TAG表而造成的线程拥堵,我们需要采取延迟加载的方案来做。服务器应该维护一个进程专业的对标签和文章地段的查询和索引,我们在发布文章的时候应该把标签同步这一块托管给另外的一个程序进行处理,并进行索引。
第三部:标签缓存索引:
对于频繁的判断标签去或者热门的标签我们还可以组织一套有效的索引,比如对于标签“疯狂代码”和”傲博知识库”,我们用树来把它表示出来。对于疯狂代码我们索引一个疯,其实用程序表达就是疯狂代码[0],同样傲博知识库就是傲博知识库[0]。而在数组”疯”中存贮以疯开头的标签组,以”傲”的数组中存贮以”傲”开头的标签。如果量更大的话还可以再做二级索引。

这涉及另外一个话题了就是分词,上面是一个简单的分词方案,大家在进行GOOGLE搜索的时候应该很输入它的Suggest方法吧,就是这个道理。最终讲标签有效的索引,并提取热门的作为一个全局静态变量,我们就可以绕过数据查询这一关,对第二部的单件模式又是一个进化。

以上是对多对多关系的一个简单的架构说明,肯定有人会问,如果这样做的话工作量不是太大了吗,分词处理什么的,对每个多对多关系进行处理。
OK,咱们可以进一步的把它来抽象化,我们用TableA 表示Article表,用TagbleT表示Tag表,我们可以讲字段抽象化出来,也就是一个ID,一个Tag的String 同理对于标签表也是如此。朋友们应该可以理解我的意思了。

对,就是做个代码生成器把对应的多对多关系给生成出来,这个很好写的,几个Append就可以搞定。如果想更方便的处理,那么把这个东西做成单件的模式抽象化出来,然后再违反一下原则,做成基类,其他关系继承这个基类。。。。。剩下的应该很简单了,具体实现大家思考吧。

请参照第二篇的文章进行进一步优化设计来实现更高的负载性能

下章接着讲述数据分割和散列方面的内容

大型网站架构系列之二,底层架构概论

上篇大型网站架构系列之一中介绍的基于AJAX的攻击很多人提出疑问,比如不能跨域,减轻负担之类。Ajax是通过简单的GET和POST进行数据传递的,采用HTTPDEBUGGER,抓取数据,然后采用如下方案,顺便写个示例的攻击代码.比传统的webform,我们更容易构造一些,其实对于 webform和ajax的处理和发包过程是一样的,ajax数据量相对小,速度也快一些。
结合SharpPcap和HttpWebRequest我们构造一个合理的正常的IP数据包过去,代码很长,我们用伪代码简单的表达一下。
request.CreateUrl(Ajax处理页面);
request.Method=”GetORPost”;
request.refere=”网页来源”;
SharpPcap.SetLinkConnection(伪造IP地址);
String content = request.GetResponseStream() 如果作为一个多线程的应用程序对对方的WEB构成批量发包的话(假如是DEDECMS),足可以把Dedecms的数据库搞垮

文入正题:
对于上回书提到要解决问题A,我们先讲解一下电信公司ADSL的布局方案。机器上没有装VISIO,我简单的用文字描述一下流程。
Adsl用户Aè输入用户名密码è远程连接到账户数据库(在天津)è账户数据库连接计费数据库并返回状è如果成功,连接PPPOE服务器,并进一步连接计费数据库è认证服务并连接。

这里没有什么特别的地方,但是和qq通讯服务是一样的,就是采用了统一的用户验证服务器,同时对于用户验证的信息数据库是只读的,我们从其中可以想到什么吗?

以上是个简单的例子,下面开始谈具体的架构策略,首先对于上篇提到的问题A,我们首先以用户数据库为例来做解释和要求。
首先做用户量估算需求,假如我们做的是学术社区,那么这个用户量不会很大,可能我们不需要考虑这个,对于用户量的级别,我们暂时把用户量级别定为三种,百万级别(M)和千万界别(S),以及亿万级别(Q),并考虑用户登录验证以及查询常用的操作,对M和S进行扩充以及了解。

众所周知,在这个情况下,对于用户数据的负载其实并非可行而不可行的问题,而是如何最大化的保证查询和更新以及各个服务器之间的数据同步。这里我们不再讲解如何优化如何索引,只介绍架构初期的方案,下面介绍的方案如果涉及全表查询,可以采用分区视图的方案,大家可以具体搜索相关资料。

对于M级别来说,现有的DBMS经过合理的布局完全可以满足需求。我们需要解决的问题的关键其实是处理IO方面的问题,处理方案相对简单一些,对数据库的FILE文件分磁盘存贮(不是分区,是不同的硬盘),根据负载量大小,我们可以适当的控制硬盘的数量和文件分区的数量。

对于S级别,上个处理方案已经不能完全满足需求了,这个时候我们需要对注册和入库的流程进行简单的修改了,解决方案是数据散列和分区视图的概念,具体概念大家去google一下,我不详细说明了。
我们常用的方案有三种。第一种是等容扩充法,在用户注册控制的基础上,保证每个库的用户容量不超过500万,超过之后入第二个库,以此类推,这个方案可以保证系统有效的扩充性,但不能保证数据被有效的索引。第二种就是共区索引方案,其实和第一种方案有异曲同工的之说但是讲第一种方案进行了合理的优化,按照用户名进行分库存贮。比如我们可以建立26的数据库,按照用户名的索引来控制用户数据入哪个库。假如用户名是CrazyCoder,那么就讲该用户名的数据存放在用户表C中,在数据存贮的时候可以很方便的根据用户名进行相应的数据查询,方案二可以有效的解决数据索引问题。方案三是一个更具模型化的方案,结合方案一和方案二,进行用户ID的编码,不是INDENTIFY Cloumn,我们用一种序列化的方案将用户名以编码的形式存贮,比如用户名是CrazyCoder,我们的编码方案就是通过算法进行数字化,将 CrazyCoder按照C,R,A,….存贮为数字索引,然后进行分区存贮,数字类型的数据在数据库中可以更有效的被查询和被更新和共享,结合方案一和方案二这个就是方案三。


对于Q级别。数据量已经是足够海量了,这个时候无论用哪种方案都是一个让人头大的数据,不能简单的用查询的方案来处理了,可以参考S级别的进行处理。但这个时候我们采用的方案是根据用户活跃度的权值结合数据量进行临时数据表的存放。如果一个非意外的数据情况下,每天登录的用户量不会上千万。这个时候我们需要做的是一个简单的数据代理程序。一个临时的用户验证数据库,每天执行一次批处理,将活跃度高的用户账户提取到临时数据库中,查询的时候先查询临时库,如果没有在进行全库查询。这个根据系统的负载情况来估计阈值,不同的系统估算方案也不尽相同。


上面对于,M,S,Q三种界别进行了简单的概述,下面介绍一个在其之上更高级的一个查询方案,数据缓存服务器,我们也可以把它理解为缓冲服务器,数据做为只读来使用。

具体实现方案如下:以为涉及了海量,DBMS常规的缓存方案已经不符合我们的要求了,那么我们需要一个有效的缓存方案,这个时候处理的流程其实就是讲最常用最直接的数据直接存放在缓存服务器中,而这个缓存服务器定时从主服务器获取并更新信息。这个是一个简单的查询,我们还可以更深入的讲缓存服务器做二次缓存,也就是一次性处理输入并存放到LIST数据中,作为全局变量放到内存中进行查询,同时用HASHTABLE或者数组进行数据组索引(可以是多级),根据查询分布到各个变量中。直接从内存中读取数据。

以笔者的经验来说的话,对于ITEM数据不超过10K的来说,每个列表最佳的存放范围是0到6万之间。

这里简单的介绍了一下DBMS基本架构,里面具体细节处理的还有很多,这里只介绍个大概的纲要。有问题请给我发邮件(Heroqst # Gmail.com),请讲#替换为@


这里只是简单的介绍了一下DBMS的基本布局,下章讲具体对我们常见的多对多关系数据库进行具体配置说明。

首先介绍一下问题的大概,比如对于文章和标签,每个文章可以有多个标签,而每个标签下又会有多个文章,那么数据量将是文章数乘以标签数,这个时候如何进行处理并有效的索引,将是下章多对多关系的优化设计要介绍的内容。

大型网站架构系列之一,前言,不得不考虑的问题

前言:这两天机器坏了,正在送修中,写个系列的大型网站架构的文章,希望对有志在互联网做出一番事业的站长朋友们一些帮助。

注意:这里的大型网站架构只包括高互动性高交互性的数据型大型网站,基于大家众所周知的原因,我们就不谈新闻类和一些依靠HTML静态化就可以实现的架构了,我们以高负载高数据交换高数据流动性的网站为例,比如海内,开心网等类似的web2.0系列架构。我们这里不讨论是PHP还是JSP或者. NET环境,我们从架构的方面去看问题,实现语言方面并不是问题,语言的优势在于实现而不是好坏,不论你选择任何语言,架构都是必须要面对的。

文入正题:
首先讨论一下大型网站需要注意和考虑的问题
A. 海量数据的处理。
众所周知,对于一些相对小的站点来说,数据量并不是很大,select和update就可以解决我们面对的问题,本身负载量不是很大,最多再加几个索引就可以搞定。对于大型网站,每天的数据量可能就上百万,如果一个设计不好的多对多关系,在前期是没有任何问题的,但是随着用户的增长,数据量会是几何级的增长的。在这个时候我们对于一个表的select和update的时候(还不说多表联合查询)的成本的非常高的。
B. 数据并发的处理
在一些时候,2.0的CTO都有个尚方宝剑,就是缓存。对于缓存,在高并发高处理的时候也是个大问题。在整个应用程序下,缓存是全局共享的,然而在我们进行修改的时候就,如果两个或者多个请求同时对缓存有更新的要求的情况下,应用程序会直接的死掉。这个时候,就需要一个好的数据并发处理策略以及缓存策略。
另外,就是数据库的死锁问题,也许平时我们感觉不到,死锁在高并发的情况下的出现的概率是非常高的,磁盘缓存就是一个大问题。
C. 文件存贮的问题
对于一些支持文件上传的2.0的站点,在庆幸硬盘容量越来越大的时候我们更多的应该考虑的是文件应该如何被存储并且被有效的索引。常见的方案是对文件按照日期和类型进行存贮。但是当文件量是海量的数据的情况下,如果一块硬盘存贮了500个G的琐碎文件,那么维护的时候和使用的时候磁盘的Io就是一个巨大的问题,哪怕你的带宽足够,但是你的磁盘也未必响应过来。如果这个时候还涉及上传,磁盘很容易就over了。
也许用raid和专用存贮服务器能解决眼下的问题,但是还有个问题就是各地的访问问题,也许我们的服务器在北京,可能在云南或者新疆的访问速度如何解决?如果做分布式,那么我们的文件索引以及架构该如何规划。
所以我们不得不承认,文件存贮是个很不容易的问题
D. 数据关系的处理
我们可以很容易的规划出一个符合第三范式的数据库,里面布满了多对多关系,还能用GUID来替换INDENTIFY COLUMN 但是,多对多关系充斥的2.0时代,第三范式是第一个应该被抛弃的。必须有效的把多表联合查询降到最低。
E. 数据索引的问题
众所周知,索引是提高数据库效率查询的最方面最廉价最容易实现的方案。但是,在高UPDATE的情况下,update和delete付出的成本会高的无法想想,笔者遇到过一个情况,在更新一个聚焦索引的时候需要10分钟来完成,那么对于站点来说,这些基本上是不可忍受的。
索引和更新是一对天生的冤家,问题A,D,E这些是我们在做架构的时候不得不考虑的问题,并且也可能是花费时间最多的问题,
F. 分布式处理
对于2.0网站由于其高互动性,CDN实现的效果基本上为0,内容是实时更新的,我们常规的处理。为了保证各地的访问速度,我们就需要面对一个绝大的问题,就是如何有效的实现数据同步和更新,实现各地服务器的实时通讯有是一个不得不需要考虑的问题。
G. Ajax的利弊分析
成也AJAX,败也AJAX,AJAX成为了主流趋势,突然发现基于XMLHTTP的post和get是如此的容易。客户端get或者post到服务器数据,服务器接到数据请求之后返回来,这是一个很正常的AJAX请求。但是在AJAX处理的时候,如果我们使用一个抓包工具的话,对数据返回和处理是一目了然。对于一些计算量大的AJAX请求的话,我们可以构造一个发包机,很容易就可以把一个webserver干掉。
H. 数据安全性的分析
对于HTTP协议来说,数据包都是明文传输的,也许我们可以说我们可以用加密啊,但是对于G问题来说的话,加密的过程就可能是明文了(比如我们知道的 QQ,可以很容易的判断他的加密,并有效的写一个跟他一样的加密和解密方法出来的)。当你站点流量不是很大的时候没有人会在乎你,但是当你流量上来之后,那么所谓的外挂,所谓的群发就会接踵而来(从qq一开始的群发可见端倪)。也许我们可以很的意的说,我们可以采用更高级别的判断甚至HTTPS来实现,注意,当你做这些处理的时候付出的将是海量的database,io以及CPU的成本。对于一些群发,基本上是不可能的。笔者已经可以实现对于百度空间和 qq空间的群发了。大家愿意试试,实际上并不是很难。
I. 数据同步和集群的处理的问题
当我们的一台databaseserver不堪重负的时候,这个时候我们就需要做基于数据库的负载和集群了。而这个时候可能是最让人困扰的的问题了,数据基于网络传输根据数据库的设计的不同,数据延迟是很可怕的问题,也是不可避免的问题,这样的话,我们就需要通过另外的手段来保证在这延迟的几秒或者更长的几分钟时间内,实现有效的交互。比如数据散列,分割,内容处理等等问题
K.数据共享的渠道以及OPENAPI趋势
Openapi已经成为一个不可避免的趋势,从google,facebook,myspace到海内校内,都在考虑这个问题,它可以更有效的留住用户并激发用户的更多的兴趣以及让更多的人帮助你做最有效的开发。这个时候一个有效的数据共享平台,数据开放平台就成为必不可少的途径了,而在开放的接口的情况保证数据的安全性和性能,又是一个我们必须要认真思考的问题了。

当然还有更多需要考虑的问题,我这里就写一个最需要考虑的问题,欢迎补充。

下一篇文章底层架构概论中将针对问题A,提出具体的解决方案和思路