Skip to content

转:Cassandra – 一个分散的非结构化存储系统

本文翻译自Facebook员工在LADIS大会上发布的论文.Cassandra – A Decentralized Structured Storage System
这篇论文中,两位作者详细介绍了Cassandra的系统架构,它的设计初衷,设计应用时使用到的相关技术,以及设计/实现/使用过 程中得到的经验教训.

Cassandra – 一个分散的非结构化存储系统
By Avinash Lakshman Facebook ,Prashant Malik Facebook; Translated By Jametong

概要

Cassandra是一个分布式的存储系统,可用来管理分布在大量廉价服务器上的巨量结构化数据,并同时提供没有单点故障的高 可用服务.Cassandra的设计目的是运行在由几百个节点(可能分布在多个不同的数据中心)组成的基础设施(infrastructure) 上.当节点达到这个规模时,大大小小的组件出现故障就可能经常发生了.Cassandra在管理持久状态时面临这些故障,这 种情况也驱动软件系统的可靠性(reliability)与可伸缩性(scalability)会依赖于Cassandra的服务. 虽然大部分情况,Cassandra看上去像一个数据库系统, 也与数据库系统共享大量的设计与实现手段,但是Cassandra并 不支持完整的关系数据模型;相反,它提供了一个简单数据模型的客户端,支持对数据布局与数据格式的动态控制.我们设计 Cassandra的初衷是,可以运行在廉价硬件上,并能在不牺牲读效率的情况下实现高的写吞吐量.

1. 导论

Facebook维护着世界上最大的社交网络平台,利用分布在世界各地的大量数据中心的成千上万台服务器,为上亿的用户提供服 务.Facebook平台有严格的业务要求,包含性能、可靠性、效率以及高度的可伸缩性以支持平台的持续增长.在一个包含 成千上万的组件的基础设施上处理故障是我们的标准运作模式;在任何时候,随时都可能出现相当数量的服务器或网络组件故障.这样,软 件系统在构建时就需要将故障当作一种常态而不是异常来处理.为了满足上面描述的这些可靠性与可伸缩性,Facebook开发了 Cassandra系统.
为了实现可伸缩性与可靠性,Cassandra组合了多项众所周知的技术.我们设计Cassandra的最初目的是解决收件箱搜索的 存储需要.在Facebook,这意味着这个系统需要能够处理非常大的写吞吐量,每天几十亿的写请求,随着用户数的规模而 增长.由于我们是通过在地理上分布的数据中心对用户进行服务的,因此支持跨越多个数据中心的数据复制对于降低搜索延时就非常关键了. 当我们在2008年6月发布收件箱搜索项目时,我们有1亿的用户,现在我们差不多有2.5亿的用户,Cassandra一直保持了其 对业务的承诺.目前,Facebook内部已经有多个服务部署了Cassandra作为其后端存储系统.
本文的结构如下.第2节讨论相关研究,其中的部分研究对我们的设计有很大影响.第3节介绍详细的数据模型.第4节简要介绍客户端 API.第5节介绍系统设计以及Cassandra中应用到的分布式算法.第6节介绍我们如何使用Cassandra部署 Facebook平台的一个应用.

2. 相关研究

对于为了性能、可用性与数据持久性对数据进行分布,文件系统与数据库社区已经进行了广泛的研究.与仅支持扁平命名空间 (namespace)的点对点(P2P)存储系统相比,分布式文件系统通常支持层次化(hierarchical)的命名空间.与 Ficus[14]与Coda[16]类似的系统都是通过牺牲一致性来复制文件以实现高可用(high availability).通常使用特别的冲突解决(conflict resolution)程序来管理更新冲突(update conflict). Farsite[2]是一个没有使用任何中心服务器的分布式文件系统. Farsite使用复制来实现高可用性与可伸缩性.Google文件系统(GFS)[9]是另一个分布式文件系统,用来存储 Google内部应用的各种状态数据.GFS设计比较简单,用一台主服务器存储所有的元数据(metadata),数据拆分成块 (chunk)存储在多个块服务器(chunk server)上.不过,目前Google已经使用Chubby[3]抽 象层为GFS的主服务器做了容错处理(fault tolerant).Bayou[18]是一个分布式的关系数据库系统,它支持断开操作(个 人理解为网络断开以后的操作)并提供最终的数据一致性(eventual data consistency).在这些系统中,Bayou、Coda 与Ficus允许断开操作,并且在遇到类似与网络断开与停机时能够做到自动复原.这些系统在冲突解决程序上存在差异.例如,Coda 与Ficus执行系统级别的冲突解决,而Bayou允许应用级别的冲突解决.但所有这些都保证最终一致性(eventual consistency).与这些系统类似,即使在网络段开的时候,Dynamo[6]也允许进行读写操作,并使用不同的冲突解决机 制(部分客户端驱动)来解决更新冲突.传统的基于复制的关系数据库系统重点在保证复制数据的强一致性(strong consistency).虽然强一致性为应用写程序提供了一个方便的编程模型,但是,这些系统在伸缩性与可用性方面却受到了限制.因 为这些系统提供强一致性的保证,所以在网络分开时,它们就无法进行处理.
Dynamo[6]是一个Amazon开发的存储系统,Amazon用它来存储检索用户的购物车.Dynamo利用基于Gossip 的会员算法来维护每个节点上所有其他节点的信息.可以认为Dynamo是一个只支持一跳路由请求(one-hop request routing)的结构化覆盖层(structured overlay).Dynamo使用一个向量时钟(vector lock)概要来发现更新冲突,但偏爱客户端的冲突解决机制.为了管理向量时间戳(vector timestamp),Dynamo 中的写操作同时也需要执行一次读操作.在一个需要处理非常大的写吞吐量的系统中,这可能会成为瓶颈. Bigtable[4]既提供了结构化也支持数据的分布式,不过它依赖于一个分布式的文件系统来保证数据的持久化.

3. 数据模型

Cassandra中的表是一个按照主键索引的分布式多维图.它的值是一个高度结构化的对象.表中的记录键是一个没有大小限制 的字符串,虽然它通常都只有16-36个字节的长度.无论需要读写多少列,单一记录键的每个副本的每次操作都是一个原子操作.多 个列可以组合在一起形成一个称为column family的列的集合,这一点与Bigtable[4]系统非常相似.Cassandra提供 两种类型的column family,简单的column family与超级的column family.可以将超级column family想象成column family里面嵌入column family.进一步,应用还可以指定超级column family或者简单column family里面的列的排序顺序.系统允许按时间或者名称对列进行排序.按照时间对列进行排序可 以被类似于收件箱搜索这样的应用使用,因为它们的结果始终需要按照时间顺序进行展示.column family中的每个列都需要通过规范column family : column来进行访问,每个超级column family中的列都通过规范column family : super column : column来进行访问.小节6.1给出了一个 展示超级column family抽象能力的非常好的例子.通常,应用都会使用一个独占的Cassandra集群,并将它们当作服 务的一部分进行管理.虽然,Cassandra系统支持多表的概念,在部署时每个概要中都只能有一个表.

4. API

Cassandra的API由下面三种方法组成.

  • insert(table, key, rowMutation)
  • get(table, key, columnName)
  • delete(table, key, columnName) 列名可以是column family里面的一个特定列,或column family,或超级column family,或超级列里面的一个列

5. 系统架构
一个需要在生产环境运转的存储系统的架构是很复杂的.除了真实的数据持久化组件外,这个系统还需要包含以下特性;可伸缩性与强大负载 均衡解决方案、会员与故障检测、故障恢复、副本同步、超负荷处理、状态转移、并发与任务调度、请求编组、请求路由、系统监控与报警以 及配置管理.详细描述这里的每一个解决方案超出了本论文的范围,我们将集中介绍Cassandra使用的核心的分布式系统技术:分 区、复制、会员、故障处理以及伸缩性.处理读写请求需要所有这些模块的协同处理.通常,一个键的请求可能被路由到Cassandra 集群的任何一个节点去处理.这个节点会确定这个特定的键的副本.对于写操作来讲,系统会将请求路由到副本上,并且等待仲裁 数量的副本以确认写操作完成.对于读操作来讲,基于客户端要求的一致性保证,系统要么将请求路由到最近的副本,要么将请求路由到所有 的副本并等待达到仲裁数量的响应.

Continue reading ›

美文欣赏:父母的记忆

The Memory of Parents

All you remember about your child being an infant is the incredible awe you felt about the precious miracle you created. You remember having plenty of time to bestow all your wisdom and knowledge. You thought your child would take all of your advice and make fewer mistakes, and be much smarter than you were. You wished for your child to hurry and grow up.

All you remember about your child being two is never using the restroom alone or getting to watch a movie without talking animals. You recall afternoons talking on the phone while crouching in the bedroom closet, and being convinced your child would be the first Ivy League1 college student to graduate wearing pullovers2 at the ceremony. You remember worrying about the bag of M&M’s melting in your pocket and ruining your good dress. You wished for your child to be more independent.

All you remember about your child being five is the first day of school and finally having the house to yourself. You remember joining the PTA3 and being elected president when you left a meeting to use the restroom. You remember being asked “Is Santa real?” and saying “yes” because he had to be for a little bit longer. You remember shaking the sofa cushions for loose change4, so the toothfairy5 could come and take away your child’s first lost tooth. You wished for your child to have all permanent teeth.

All you remember about your child being seven is the carpool6 schedule. You learned to apply makeup in two minutes and brush your teeth in the rearview mirror1 because the only time you had to yourself was when you were stopped at red lights. You considered painting your car yellow and posting a “taxi” sign on the lawn next to the garage door. You remember people staring at you, the few times you were out of the car, because you kept flexing2 your foot and making acceleration3 noises. You wished for the day your child would learn how to drive.

All you remember about your child being ten is managing the school fundraisers. You sold wrapping paper for paint, T shirts for new furniture, and magazine subscriptions4 for shade trees in the school playground. You remember storing a hundred cases of candy bars in the garage to sell so the school band could get new uniforms, and how they melted together on an unseasonably5 warm spring afternoon. You wished your child would grow out of playing an instrument.

All you remember about your child being twelve is sitting in the stands6 during baseball practice and hoping your child’s team would strike out7 fast because you had more important things to do at home. The coach didn’t understand how busy you were. You wished the baseball season would be over soon.

All you remember about your child being fourteen is being asked not to stop the car in front of the school in the morning. You had to drive two blocks further and unlock the doors without coming to a complete stop. You remember not getting to kiss your child goodbye or talking to him in front of his friends. You wished your child would be more mature.

All you remember about your child being sixteen is loud music and undecipherable8 lyrics9 screamed to a rhythmic beat. You wished for your child to grow up and leave home with the stereo.

All you remember about your child being eighteen is the day they were born and having all the time in the world.

And, as you walk through your quiet house, you wonder where they went and you wish your child hadn’t grown up so fast.

【中文译文】:

当你的孩子是个婴儿时,你所记得的,是你对自己创造出的堪称完美奇迹的作品,感到不可思议的敬畏。你记得你有大量的时间去传授你所有的智慧和知识。你认为你的孩子将会接受你所有的忠告而少犯错误,将会比孩提时代的你聪明许多。你多希望你的孩子快快长大。

孩子两岁时,你所记得的,是从不能独自使用卫生间,从不看一部与动物无关的电影。你记得那些蜷缩在卧室储衣间跟朋友通电话的下午,深信你的孩子将是第一个身着套头衫出席毕业典礼的常春藤名牌大学毕业生。你记得你担心那袋M&M巧克力糖会在你的衣兜里融化,毁了你体面的衣服。你多希望你的孩子更独立些。

孩子5岁时,你所记得的,是他上学第一天你终于独自拥有整个房子了。你记得参加家长—教师联系会,在你离开会议室去洗手间时,你当选为会长。你记得孩子问你“圣诞老人是真的吗?”你回答“是的”,因为他还需要你的肯定回答,尽管不久他就能自己判断了。你记得在沙发垫子下一通翻腾要找出些零钱,这样牙齿仙女就会来把你孩子掉的第一颗牙带走。你多希望孩子的牙都换成了恒牙。

孩子7岁时,你所记得的,是合伙用车的时间安排。你学会了在两分钟内化完妆,照着汽车后视镜刷牙,因为你能给你自己找出的时间就只有汽车停在红灯前的那小段。你想过把你的车子漆成黄色,并在车库门旁的草坪上立一个“出租车”的标志牌。你记得有几次你下车后,人们盯着你,因为你不断用脚踩油门加速,制造噪音。你多希望孩子有一天能学会开车。

孩子10岁时,你所记得的,是怎么组织学校的募捐者。你们为重新粉刷学校兜售包装纸,为购置新家具兜售体恤衫,为在学校操场上种植遮阳树劝人订阅各种杂志。你记得你在车库里存放了上百盒糖果等待出售,得到钱后学校的乐队就可以购置新制服,可是那些糖果竟在一个暖和得过头的春天的下午全都融化在一起了。你多希望孩子长大,不再演奏什么乐器了。

孩子12岁时,你所记得的,是孩子在体育场打棒球练习赛时,你坐在看台上希望你孩子所在的队很快三击不中出局,因为家里还有更重要的事等你去做。教练不明白你为什么那么忙。你多希望棒球赛季能尽快结束。

孩子14岁时,你所记得的,是他不让你早晨把汽车停在校门口。你不得不开过两个街区,车还没停稳就赶紧打开车门。你记得没能在他的朋友面前跟他吻别或说话。你多希望孩子能更成熟些。

孩子16岁时,你所记得的,是吵闹的音乐和以富有节奏的拍子尖声唱出的难以听懂的歌词。你多希望孩子快点长大成人,带着音响离开家吧。

孩子18岁时,你所记得的,是他们出生的那一天,拥有世间所有的时光。

当你在静静的房子里走来走去时,你纳闷他们去哪里了——你多希望孩子别这么快就长大了。

来自:每日英语 http://blog.beanwoo.com/english/30/2010/01/04/1151

人生,没那么容易

关于爱情:不 要认为后面还有更好的,因为现在拥有的就是最好的。不要认为还年轻可以晚些结婚,爱情是不等年龄的。不要因为距离太远而放弃,爱情可以和你一起坐火车的。 不要因为对方不富裕而放弃,只要不是无能的人,勤劳可以让你们富裕的。不要因为父母反对而放弃,你会发现因为这个原因而反放弃的爱情,将是你一生的悔恨。 其实对于爱情,越单纯越幸福。一生只谈一次恋爱是最好的,经历的太多了,会麻木;分离多了,会习惯;换恋人多了,会比较;到最后,你不会再相信爱情;你会 自暴自弃;你会行尸走肉;你会与你不爱的人结婚,就这样过一辈子。

关于爱情:也 许爱情是一部忧伤的童话,惟其遥远才真实。放弃一个爱你的人并不痛苦,放弃一个你爱的人那才痛苦。若是有缘,时间空间都不是距离,若是无缘总是相聚也无法 合意。凡事不必太在意,更不需去强求,就让一切随缘。逃避不一定躲得过;面对不一定最难过;孤独不一定不快乐;得到不一定长久;失去不一定不再拥有。爱是 一种享受,即使痛苦也会觉得幸福;爱是一种体会,即使心碎也会觉得甜蜜;爱是一种经历,即使破碎也会觉得美丽;不要因为寂寞而错爱,不要因为错爱而寂寞一 生。

关于伴侣:伴 侣不是结婚时发誓非你不娶或非你不嫁的那个人,而是发现你身上有许多缺点仍然选择你的那个人;伴侣不是生活中你爱吃黄瓜ta也爱吃黄瓜的那个人,而是你吃 蛋清ta吃蛋黄的那个人;伴侣不是天黑了和你一起手挽手走进饭店的那个人,而是守在门口巴望你回来共进晚餐的那个人;伴侣不是和你大谈爱情,把“我爱你” 挂在嘴边的那个人,而是和你平淡的唠叨柴米油盐、锅碗瓢盆的那个人。在幸福的婚姻中,伴侣已不是一个具体的人,而是你和ta在几十年的岁月中沉淀下来的: 一份默契、一份温情、一份平淡、一份理解、一份宽容。爱ta就要让ra开心,这就是伴侣……

关于承诺:在 古希腊传说中,情侣都将戒指套在对方的中指上,因为他们相信那儿有一根血管直通心脏。所以戒指的意思就是用心承诺!但是人世间有多少爱能生死白头,又有多 少的情可以天长地久?所以你选择共度一生得未必是你最爱的,你最爱的未必能和你共度一生。多少的有情人走不进彼此的今生,只能苦苦地相约于来世;而多少的 男男女女走过爱情走进婚姻却不会再珍惜彼此的付出。所以记得珍惜你爱的人,把每一个平淡的今天当成是彼此相依的最后一刻,好好握紧爱人的手,即使ta容颜 已老,即使ta满面沧桑,那也是你记忆中永恒的温馨。别忘了守住对ta的承诺,别忘了牵住ta的手,一生一世一辈子……

关于人生:人 生如梦,岁月无情。蓦然回首,才发现人活着是一种心情。穷也好,富也好,得也好,失也好。一切都是过眼云烟。想想,不管昨天、今天、明天,能豁然开朗就是 美好的一天。不管亲情、友情、爱情,能永远珍惜就是好心情。记得有一个经典短信这样写着:曾经拥有的不要忘记;已经得到的更加珍惜;属于自己的不要放弃; 已经失去的留作回忆;想要得到的一定要努力;累了把心靠岸;选择了就不要后悔;苦了才懂得满足;痛了才享受生活;伤了才明白坚强;总有起风的清晨;总有绚 烂的黄昏;总有流星的夜晚。人生就像一张有去无回的单程车票,没有彩排,每一场都是现场直播。把握好每次演出便是对人生最好的珍惜。把握现在,畅享人生!

关于友情:有 一天,友情和爱情碰见。爱情问友情:世上有我了,为什么还要有你的存在?友情笑着说:爱情会让人们流泪,而友情的存在就是帮人们擦干眼泪!朋友就是:偶尔 会为你担心、向你关心、替你懆心、想你开心、逗你开心、请你放心。朋友之间,懂得关怀才是难得。伤心时不妨和我说;痛苦时别忘了跟我讲;有病时别忘了通知 我;困难时记得要请教我;失望时要想起还有我;开心时更不要忘记我。朋友的定义,就在于此。我们是朋友,这就够了。

关于微笑:被 人误解的时候能微微的一笑,这是一种素养;受委屈的时候能坦然的一笑,这是一种大度;吃亏的时候能开心的一笑,这是一种豁达;处窘境的时候能自嘲的一笑, 这是一种智慧;无奈的时候能达观的一笑,这是一种境界;危难的时候能泰然一笑,这是一种大气;被轻蔑的时候能平静的一笑,这是一种自信;失恋的时候能轻轻 的一笑,这是一种洒脱。不管是有什么事情,为了什么原因,我们每天都要开心一笑~~

关于生活:日出东海落西山,愁也一天,喜也一天;遇事不钻牛角尖,人也舒坦,心也舒坦;每天领取谋生钱,多也喜欢,少也喜欢;少荤多素日三餐,粗也香甜,细也香甜;新旧衣服不挑捡,好也御寒,赖也御寒;常与知己聊聊天,古也谈谈,今也谈谈;全家老少互慰勉,贫也相安,富也相安。

关于幸福:相传幸福是个美丽的玻璃球,跌碎散落在世间的每个角落。有的人捡到多些,有的人捡到少些,却没有人能拥有全部。爱你所爱选你所选,珍惜现在所拥有的一切。人活着就是一种心情,把握今天,设置明天,储存永远。只要用心感受,幸福就会永远存在。

人总是对自己拥有的东西不珍惜,直到不再拥有时才会加倍怀念,而在得知自己快失去自己所拥有的东西而又无能为力时,就寻死觅活地不肯放手,歇斯底里往往发生在这个时候,而对于生命的执著确实是到死才放手!

人生,没有那么简单……幸福伴随悲伤,快乐总和痛苦相伴,这就是人生。今天总要过去,明天充满未知,自己活得快乐没有遗憾就好。 ——草本

做一个温暖的孩子

【一】

做一个温暖的孩子。
做一个爱笑的孩子。
懂得如何快乐,并感染身边的人快乐。
用心去生活,并记得自己的使命和诺言。
偶尔任性,却不犀利。
偶尔敏感,却不神经质。
乐意和大家分享所有开心的事情,坦然面对所有的悲伤,笑看彩虹,我坚强!
高兴,就笑,让大家都知道。
悲伤,就微笑,没什么大不了,疼爱你的人不会舍得你流泪,痛到深处会有共鸣。
不轻易流泪。
不轻易伤悲。
偶尔,可以适当发泄。
只需要一个鼓励的微笑,就可以说服自己继续坚强。

【二】

心存感激。
爸爸妈妈,是这个世界上最爱我和我最爱的。
每一次回家,忍不住睁大眼睛张望这个熟悉的被称作故乡的地方。
下雪了,天晴了,这个世界始终都是那样美好。
记得在心里默念那句话——
美好是因为相信。
真爱只有用真爱才换的回来。
所以,我相信。

【三】

勇敢面对现实。
没有十全十美的人,认定了那一个,再难也要坚持下去。
我要对你好,用尽全力,就算会受伤,也不后悔。
欣赏你,因为你是我的骄傲。
逗你笑,因为想看到你开心时的样子。
对你好,因为你是我唯一的选择。
善于遗忘。
善于把我们的不愉快格式化。
我喜欢的爱情不是王子与公主的童话,而是为对方着想到忘了自己的心疼。
“如果胖的我跟瘦的我同时出现,你会选哪一个啊?”
“当然是胖的那一个啊。”
“少骗人了,哪有人会选胖的啊。”
“……因为,胖胖的你没有人疼。”

【四】

对自己好一点。
对别人好一点。
善待自己,善待坚强乐观的自己。
不再为不在乎我的人掉眼泪。
选择相信对方,不管你是好是坏。
做一个聪明的孩子,只在调皮时装傻。
认真地生活。
少一点幻想。
不再期待幸福的降临,它就在身边。
我想要,活得比夏天还要温暖。

【五】

永远不放弃希望。
希望可以被宠溺,被心疼。
希望有被保护的感觉。
希望可以保护好我想保护的人。
希望有一天背上行囊,和你一起流浪。
希望拥有白头偕老的爱情。
希望还可以笑着告诉别人要快乐,一心一意地给他们带去温暖。
希望还可以见到很多个过度曝光的夏天和白雪纷飞的冬夜。
希望所有的人都幸福,安康。

转:一种语言/编码检测的复合方法

转自: http://blog.i5un.com/item/21

翻译自Mozilla的网站。
这篇论文讨论了组合三种不同的检测方法来实现自动字符集检测。
A composite approach to language/encoding detection)
Shanjian Li (shanjian@netscape.com)
Katsuhiko Momoi (momoi@netscape.com)
Netscape Communications Corp.

[ 注:这篇论文最初发表在19届国际Unicode会议(19th International Unicode Conference)(San Jose)。那以后,我们的实现经受住了时间和实际应用的检验,并且,我们还作了许多改进。一个主要的变化是我们现在使用正序列来检测单字节字符集,参见 4.7和4.7.1节。这篇论文写于通用字符集检测代码集成到Moailla主代码前(参见第8节)。自此以后,字符集检测代码被合并到了代码树中。如想 查看最新的实现,请在Mozilla的代码树中查看相应代码。作者 - 2002年11月25日。]

1.概要:

这篇论文提供三种自动检测的方法来判定无明显字符集声明的文档的编码。我们将分别讨论每种方法的优点和缺点,并且提供了一种复合后的,更有效的方法 来检测编码,这样,三种检测方法就可以互为补充。我们认为自动检测在使浏览器用户避免经常使用编码菜单手动选择编码上很有用,同时在编码菜单很少出现的情 况下,提供了更合理的处理方式。我们假设,文档转化到Unicode对用户是透明的。无论字符编码采用的是某种Unicode编码还是本地编码,用户仅需 知道字符最终显示是正确的就行。好的自动编码检测能有效的帮助用户处理大部分的编码事项,而无需用户手动参与。
2.背景:

自从进入计算机时代以来,人们创造了许多使用计算机数据表示的编码方案来表达不同的文字/字符集。随着全球化和Internet的发展,跨语言和区 域的信息交换越来越重要。但是现存的多种编码方案对此是一个屏障。Unicode提供了通用的编码解决方案,但是,迄今为止,各种各样的因素使它并没有代 替现存的区域编码方案。除了W3C和IETF建议使用UTF-8作为缺省编码,比如XML,XHTML,RDF。因此,现今的国际化软件不仅要处理 Unicode编码,还要处理其它多种不同的编码方式。

我们当前的工作是在开发Internet浏览器的环境中开展的。为了处理如今Web上使用不同编码的各种语言,我们做了许多努力。为了获取正确的显 示结果,浏览器需要利用HTTP服务器返回的编码信息,网页或者是最终用户通过选择编码菜单而得到的编码方式。此外,大部分用户没有能力手动的通过编码菜 单来进行操作。如果没有编码信息的话,网页有时就会显示为“垃圾”字符,用户就无法得到他们想要的信息。这最终会导致用户认为他们的浏览器有故障或有 Bug。

由于越来越多的Internet标准协议指定Unicode作为缺省的编码方式,网页将会不容置疑的转向使用Unicode来编码。好的通用自动检 测方法可以对这种转向提供重要的贡献,因为它们工作很自然,无需用户使用编码菜单。在这种情况下,渐进的转向将会以用户不易察觉的方式进行,这是由于,对 用户来说,网页总会显示正确,他们无需考虑使用编码菜单。这种平滑的转变将使编码对用户来说越来越不需要关注。自动检测在这种场景中将很关键。

Continue reading ›

转:Berkeley DB增加SQL功能

Oracle Berkeley DB将于2010年3月底发布最新版本Oracle Berkeley DB 11g release 2,具体版本号为 11.2.5.0.xx (xx代表具体的patch版本号)。

除了对原有Oracle Berkeley DB的功能进行了一定的改进和增强(比如提升了数据压缩功能、性能优化、C/C++中系统资源自动管理功能等等),本次发布的版本中最引人瞩目的变化是我们引入了一个有用的新特性——Oracle Berkeley DB SQL,简称BDBSQL。这是自Berkeley DB诞生20多年来第一次支持SQL接口。这无论是对开源社区,还是对嵌入式数据库行业来说,都将是一件喜事。在此也感谢整个Oracle Berkeley DB 研发团队的努力工作和大家的不断支持。

新的版本,新增的BDBSQL接口,值得期待。 :-)

Oracle Berkeley DB SQL接口简介

从Oracle Berkeley DB (简称BDB)诞生以来,它一直扮演着一个嵌入式、提供API调用的、高性能、非关系型的数据库引擎的角色, 被广泛应用于存储、金融、互联网、电子商务、汽车、消费电子、航空及国防等领域。简言之,它是一个1M大小的C语言类库,提供了基于键/值对(key/value pair)形式的并发和事务操作的API给C/C++/Java/C#/PHP等编程语言调用。由于BDB灵活高效的特点,它特别适合一些大数据量的、或者任务密集型的、或者硬件资源受限而性能要求高的嵌入式、跨平台等等的应用需求。

但我们发现,在很多场合对于关系数据库和SQL的需求是大量存在的。在 “edge”(如消费电子)或者一些大型的企业应用(如ERP)中,一个即时高效、并发的,支持SQL的、本地化嵌入式数据库通常是首选。因此,从 Oracle Berkeley DB 11g release 2开始,我们在保留原有基于key/value操作的API的同时,新增加了BDBSQL接口,实现了对SQL的支持。

BDBSQL完全兼容SQLite(著名的嵌入式开源关系数据库)原有的编程接口。以往运行在SQLite上的程序和应用都可以无缝的、方便的迁移到 Oracle Berkeley DB这个更加强大的引擎。并且,Oracle Berkeley DB和SQLite还将进行长期的官方层面的合作,保证了Oracle Berkeley DB的SQL接口和SQLite保持一致,免除了用户的后顾之忧。此外,Berkeley DB SQL完美支持很多第三方的SQLite工具,如JDBC,ODBC,FireFox 3及其SQLite Manager 插件等。

就具体实现来说,在BDBSQL中,我们将原SQLite的底层存储引擎替换为Berkeley DB的数据库引擎。如下图所示:
Oracle Berkeley DB SQL 架构图

Oracle Berkeley DB SQL 架构图

从上面的BDBSQL实现图可以看到,Oracle Berkeley DB引入了SQLite的SQL层:包括用户接口(sqlite3(), ODBC, JDBC等)和SQL语言处理层(Tokenizer、Parser及Generator),而底层引擎(虚拟机)则使用了BDB的存储引擎。从而,将原来SQLite基于数据库级别的并发提升一个级别 – 至BDB的基于页(Page)级别的并发,并可以利用BDB的更好的内存管理、数据和事务恢复功能、更多的扩展(如Berkeley DB的db_hotbackup、db_stat、db_archive等一系列命令行工具)。

Oracle Berkeley DB 11g release 2在主流平台经过了严格的、多重的测试和认证(每个平台涵盖以十万计的测试案例),测试平台包括Solaris、*nix、Windows系列(XP, 7, Mobile)、Android 2.0(及以上)、VxWorks等等。此外,我们还提供了大量工具和资料帮助用户熟悉这套最新接口。随版本一起发布的,包括SQLite到Oracle Berkeley DB数据迁移指南、JDBC/ODBC使用指南、全文检索(Full Text Search)向导、空间数据库(R*Tree)向导、Android平台上使用向导、数据库使用手册及调优向导、数据管理员手册、测试集、代码示例等完善的资料,进一步帮助用户放心地来使用我们的产品。了解更多SQLite的语法、API、命令行等帮助,还可以参考SQLite.org上的文档。

总结一下: BDBSQL接口是一个1M大小的C语言类库,是一个高效并发的嵌入式数据库。它支持in-memory cache选项,某些场合可作为内存数据库的一个替代方案。它支持C/C++/Java/PHP等语言接口和通过JDBC/ODBC等驱动程序访问。它运行于Unix/POSIX、Windows家族、VxWorks、QNX、Android等平台。和SQLite一样,它支持SQL92标准。

Berkeley DB SQL和SQLite使用上的区别

a) 对于用户和开发人员来说,这两个产品是没有区别的。它们在SQL语法、API、命令行交互、PRAGAMAs 等方面都是一致的。我认为,用户可以体验的显著区别有可能是性能和并发了 – 由于SQLite提供的是数据库级别的锁,而Berkeley DB SQL是页(Page)级别的锁,因此后者在绝大多数测试中都会快很多 (如Insert, Update, Delete, 并发操作等)。但是,由于BDBSQL提供的细粒度锁的机制,它又会带来一些额外的开销,一些极端的测试用例下会比SQLite慢上少许(但不明显)。并且对于这些极端测试的案例,我们一直在进行性能优化。

b) 对于已有的SQLite应用程序和工具而已,由于这两者在调用接口都是一致的,因而都可以无缝支持。

c) 对于DBA人员来说,除了可以继续使用SQLite原来的管理工具,您还可以使用BDB提供的db_hotbackup、db_stat、db_archive等一系列命令行工具来备份,监控,升级等。另外,您还可以联系Oracle寻求支持。

总体而言,我们有充分理由相信Oracle Berkeley DB SQL将会比SQLite更快,更稳定。同时,我们也将会提供更好的支持服务。

BDBSQL接口和BDB key/value接口的比较

我们举个例子说明这两套API在开发上的区别。

假设有一个employee的BDB数据库(注:一个BDB的数据库,即相当于关系型数据库中的一张二维表),我们定义其主键字段为:key{empId, email},定义其value包含字段:value{empName, sex, age, startDate, status}。相应的,对应于Oracle 关系型数据库的表结构为:

TABLE: employee {
empId PRIMARY KEY,
email PRIMARY KEY,
empName,
sex,
age,
startDate,
status
}

接下来,对于数据库的操作,在BDB的语法大致为:
- 要插入一条记录,employeeDatabase.put(key{1000, john.smith@foo.com}, value{‘John Smith’, ‘male’, 30, 2005-01-01, ‘OK’});
- 随后,如果要更新上面那条记录:employeeDatabase.put(key{1000, john.smith@foo.com}, value{‘John Smith’, ‘male’, 60, 2005-01-01, ‘Retired’});
- 如果删除该条记录,则:employeeDatabase.delete(key{1000, john.smith@foo.com}); // 此处只需要提供key即可
- 查询记录:employeeDatabase.get(key{1000, john.smith@foo.com}); // 此处只需要提供key即可

在BDBSQL中,上面的增删改操作都可以通过标准的SQL语言来进行。如更新一条记录,可写成:

update employee set age=60, status=’Retired’ where empId=1000 and email=’john.smith@foo.com’;

总结

最后,需要强调的是,BDBSQL是作为对BDB已有功能的一个补充而不是替代。它只是本次BDB发布产品的一个新特性,并且将会像Hash、Queue、集群等功能一样持续下去。它的出现在一定程度上更丰富了BDB的应用场景。用户可以根据自己的需要,选择适合的BDB接口:

* 当用户需要非常高的性能,管理非关系型数据,或者以Queue、Hash等方式来组织和访问数据的时候,可以继续选择 Oracle Berkeley DB的既有key/value API。如大型企业系统中单点登录、消息队列、工作流等模块,如管理XML、声音、照片、视频等场合,如SOA中的BAM模块、业务规则引擎,如云计算或者云存储节点上,等等。
* 而在用户需要一个本地持久化的支持SQL的嵌入式数据库时,BDBSQL将成为优先的选择。比如,手机的通讯录、个人web站点、桌面端的应用(如股票软件、浏览器客户端的缓存和存储)及开发工具(如IDE)、中小企业的数据库系统、企业实时系统的一些缓存模块、小型的关系型内存数据库等等。

正式版本的Oracle Berkeley DB 11g release 2将于2010年3月底发布。Oracle Berkeley DB整个产品家族继续以开源形式发布,并对开源社区提供支持。更多关于Oracle Berkeley DB 11g release 2的新功能和特性,请关注我们的官方网站(http://www.oracle.com/database/berkeley-db/index.html)或者本博客的后续文章。

请至官方网站下载最新版本的Oracle Berkeley DB数据库系列产品,包括Oracle Berkeley DB (及SQL),Oracle Berkeley DB Java版和Oracle Berkeley DB XML数据库。

转自: bdbChina

生活琐碎

回忆就像困进眼里的砂,无论多痛都要柔柔的擦。

很久没有写点什么了,自从回了新浪,自从被强制要求使用围脖。平时有点什么想说的,一句两句,直接写到围脖了。于是,自然也就没有了写长篇大论的需求和动力。

可是,围脖和文字还是不一样的。有些东西,140个字,终究是表达不了的。就像即使有了短信,有了电话,偶尔依然还是想买个信封,买张邮票一样。如果旁边有自习室,带一本书,拿几张信纸,进去消磨一个周日的下午肯定会是我的首选。

公司年会。可能是因为座位离舞台比较远,感觉上比起来,还不如周一的产品部部门年会来的精彩。国家会议中心的设施也没有比丽亭华苑酒店好多少,不论从灯光,音像,还是服务质量来说,都衬不上“国家”俩字。吃的就更不用说了。最后抽奖快完的时候,我才明白过来菜已经上完了,而我,却还只是半饱状态。

芳和肖都回去了——年后都不再回北京。前几次在大食代里的牌局,居然成了最后的团聚。天冷的日子,大家又都各自忙着,见面的日子越来越少。幸好上个周日,跟肖一起去什刹海滑冰,也算是给她送行了。

上上个周末,在路过清华的那片结了冰的湖面时,意外的发现居然有人在溜冰,而且湖边还有租溜冰鞋的。跃跃欲试的我,穿上冰鞋,居然还能站稳,熟悉了一会,居然还能滑起来。高中时学会的滑旱冰的技巧,虽然好多年没有用过,竟然还都记得。第二次,换到什刹海,冰面比清华好很多,也大很多,场地里还有不少技术不错的人,可以偷偷的学习一下。唯一不足的是,鞋子不合脚。忍着脚痛,尝试了几次后,在太阳下山前,终于学会了倒滑。

弟弟和星星都参加了今年的考研。考研前,蚊子还千里迢迢的跑来北京给星星加油。看着他们幸福的一路同行,不胜唏嘘。分分合合到最后,才知道,单身的时候,最遗憾的不是孤单,而是快乐没有人分享,悲伤没有人分担,平凡的日子没有人相伴。

帽子感冒了,而我什么忙都帮不上。

腾讯的事情到最后也没有怎么样,但那段日子的心情,是自己很难忘记的梦靥。但愿吃一堑长一智吧。

在晚会上听到两首很好听的歌:信乐团的海阔天空和 Kelly 的 because of you 。可是回来下载下来听,却没有了当初刚听到时的感动了。

立春。一切从头开始。You Are The One

2009的漂泊

2009,漂泊的一年。

其实漂泊从2008年年底就开始了。

2008年10月,离开新浪,去到腾讯,离开北京,去到深圳。

从深秋回到盛夏。

可是还没有等我回过神来,被扒的钱包,被盗用的信用卡,给我上了深刻的一课:深圳,不是北京。

陌生的城市,陌生的人,陌生的工作,陌生的心情。

最终,还是决定离开,回北京。

2009年1月25日是除夕,在此之前3天,回到了东安。

算算有多少年没有这么早回家了呢。虽然毕业才一年半,但工作已经两年多了。工作的时候,公司的规定是大年三十才开始放假的,所以每年即使请一天两天假,那也得过年前一天才能到家。公司初八开始上班,所以初六就得走。想起人生接下来的几十年都要这样度过,每每都觉得生活灰暗得压抑。

但今年毕竟有些不一样的。旧工作辞了,新单位还没有入职,所以还是可以有一点点的自由时间的,可以多待那么一天两天。更不一样的在于,那天,去看了wawa和她的小宝宝,跟hat一起。

回到北京,不知道什么时候下的雪还没有化完。住进小蔡在百子湾家园租的房子,每天坐他的小“宝马”去九龙花园手机之家上班。开始是dal,后来,转成搜索。

那段时间有过迷茫,有过挣扎,有过不甘,有过失望。可是回想起来,更多的还是快乐的。

那时候经常跟老高他们一起出去玩,整个公司的人,甚至有的还带着家属,挤在两辆车里,还有说有笑的。去的地方也不远,也没有特别的目标,都是北京的郊区,随便找个地方,大家一路走一路玩。那时候,天很高很蓝,云很清很淡。

那时候还经常跟大家一起去双井电影院看电影,那几个月上映的大片,几乎都是在电影院里看的。

那时候还经常一起吃饭。年初的时候是固定的轮流请,到后来不固定了,偶尔找个理由也去腐败一把。记忆最深刻的是池记串吧,烤串,啤酒,麻辣烫,还有很爽口的拍黄瓜。

那时候还跟同事们爬了一次香山,没有从原路下来,却从围墙下的一个漏洞里钻了出来。然后就漫无目的的走啊走啊,几次貌似迷路,又几次找到方向。最后大家都走不动了,终于看到公交车的影子。公交车站叫黑石头,所以我们组织了一个徒步远行的户外小组,名字就叫 black stone 。只是接下来的日子里,小组再也没有组织过活动。再后来,一些人相继离开,不知道是否还有人会想起那天的旅途。

北京的春天总是很短的,冬天刚刚过去,夏天就到来了。5月,搬家了,从偏远的百子湾搬到了繁华的亮马桥。附近有昆仑饭店,燕莎商城,远一点就是三里屯使馆区,更贴切的描述应该是酒吧区或者红灯区。

暑假,躁动的季节。

最开始是 so 来北京,由我作向导,实践了一次典型的北京三日游:第一天,天安门,前门,和大栅栏;第二天,清华北大,圆明园颐和园;第三天,长城。当然,第三天已经周一了,我就没有陪着,只是详细的告诉她们怎么走,她们自己去了八达岭。

星星的蚊子暑假过来。约吃饭,顺便把同为一中和北师大校友的小师妹约了一起,西单麻辣香锅,我从头到尾只吃一个菜:上汤娃娃菜,而蚊子吃虾的表情,令人印象非常深刻。算起来已经是第二次见蚊子了,第一次的时候,还是跟np一起,还是在新浪,还是住皂君庙呢。恍如隔世。

再后来,lily来了。

阳台前的白杨,亮马河畔的柳树,冰河世纪的音乐,鸟巢夜晚的灯光。原本那么真切那么深刻的记忆,忽然就散落成了碎片,一如打碎的镜子,每个碎片还都反射着刺眼的太阳光。

lily走的那天早上,她穿着我以前在腾讯的时候发的T恤,静静的坐在车厢里。记忆里的那一刻非常安静,安静的没有一丝声音,只剩下站台上的电子钟依旧一闪一灭。隔着厚厚的玻璃窗户,我们对望。想说些什么,却不知道能说什么。走过陌生的街角,我会记得你的好。

离别后的日子,感觉有些孤单,但只要一想到远方有个人,也在思念自己,便觉得满满的幸福像要溢出来似的。毒辣的太阳光忽然就变的温和了许多,烦躁的知了声也显得悦耳起来。

9月,又一次离职。又一次离开这个城市。不过这一次是出差,走之前,就知道自己不久就会回来,所以心情是不一样的。去大道,去成都,郫县,犀浦,住在西区花园,工作在12530音乐基地。

过去了以后,回忆里留下的大都是最美好的那些。当时觉得不能忍受的种种,大都忘了,剩下没忘的,也都觉得不那么难以忍受了。成都是个美丽的地方,拿着熊猫金卡,去武侯祠,杜甫草堂,撑着雨伞,看水,看水中悠悠的鱼。

十一,lily来了,又走了。那些青城山,都江堰的记忆,美丽,而又残酷。

一个人去过了熊猫基地,宽窄巷子,锦里,以及最后的峨眉山之后,离开成都,回到了北京。

北京很冷,每天进出地铁的时候都要把帽子手套都戴上,全副武装才行。

回到新浪,熟悉的人来来去去,只剩下了几个。不过还好,剩下的是,最熟悉的那几个。

原来漂泊,是我的宿命。

明天,我会在哪里;明年,我会在哪里?

转:500 Days of Summer

男生以为有一种东西叫做fate。有一种情感可以被形容为love。有一种邂逅是meant to be。
所以当Tom看到Summer的时候,他真真切切的告诉自己,这个人就是自己一生的挚爱。
他傻傻的用留恋的目光追随她的影子。他惶恐不安的揣测她的每一个phrase。他不可自拔的沦陷了。
于是关于她的一切都是美好的。
黑色的头发。说话前抿一下嘴巴。胸口心形的胎记。笑起来咯咯的声音。沉沉的睡过去的样子。
甚至连周围一切的景观都被他主观的赋予了鲜艳的色彩。
世界不复存在,只有你。

女生从来不相信关于爱情的童话。一切都只是虚幻的感情。没有什么是fate。没有什么可以被形容为true love。没有一种偶遇是meant to be。
relationship的意义只是have fun。仅此而已。
于是当他们在Ikea里面开心的玩闹的时候,她会认真的跟他说,well…I don’t wanna get into something serious…is that ok?
Tom苦涩的笑了,但还是很快的说了sure。因为他还是抱有幻想,有一天Summer心里的那堵墙终于会因为自己而坍塌。只是因为自己。
所以当Summer把他带到属于自己的空间里的时候,他天真的以为自己终于把那堵墙无声无息的敲碎了。
所以当Summer跟他说I have never told anyone else before,他几乎百分之百的肯定,自己在对方心中也是以同样的地位存在。

然而幻想终究只是幻想。

Tom: I just wanna know….what are we?
Summer: I don’t know….well I don’t care. I’m happy, aren’t you happy?
Tom: …yea..I am happy.

300天之后,不安终于变的强烈起来。

不再因为水槽的笑话而大笑。不再因为喜欢同一个歌手而欣喜。不再放肆的比赛讲粗口。
于是关于她的一切都变的令人厌恶。
黑色的头发。说话前抿一下嘴巴。胸口心形的胎记。笑起来咯咯的声音。沉沉的睡过去的样子。

终于还是分手了。原因不明。
这一段被认定是命中注定的恋情,终于痛苦的,不堪的,结束了。
然而故事并没有完。

500天,他们再次重逢。
男生终于意识到,原来真的没有什么是fate。没有什么可以被形容为true love。没有一种偶遇是meant to be。
女生却突然醒悟,其实有一种东西叫做fate。有一种情感可以被形容为love。有一种邂逅是meant to be。
多么的讽刺。同样一段恋情,却让两个人走上了截然不同的道路。
Tom在黑板上涂满了理想中建筑的设计图。
Summer却戴上了别人递过来的钻戒。

其实又何必去追究是不是有fate,true love, or meant to be呢。
或者说其实有些人都是这样天真的执着。
当自己沉浸在热恋中的时候,就会坚定的相信自己的感情很真实很坚定很持久。
但是一旦破裂了,便会灰心丧气,一瞬间觉得一切关于爱情的描述都应该去死。

“全世界能让你快乐的只有她”;

全世界能让你悲伤的也只有她啊。
其实一切的一切只是在于你自己而已。
是不是真正爱的,只是我们自己而已?

所以归根到底,对于爱情的态度只是为了自我安慰,还是一种信仰

现在我爱你所以一定是真爱一定能坚持很久一定可以击退一切困难。
现在我不爱你了所以爱情其实只是谎言不可能有什么天长地久。
而当下一个人出现的时候,很有可能又会很没出息的回到之前的mindset。

这样的cycle是不是很可笑呢。

真的不用把自己的情感分析的那么清晰透彻的。又不要你交report。

你如果觉得你爱他的多一点你就是TOM ,如果不够爱他你就是SUMMER
有的时候真的不用去想what are we。谁知道会不会一觉醒来就突然想结婚了呢。
When Summer is gone, Autumn is here.

只是记忆和光影,还有信仰,也会变迁么?

一定要经历过求而不得的感情才懂得珍惜么,

一定要时光把紧握的指尖分开才懂得心疼么,

不要终于能读懂幸福的时候,代价是曾经失去

转自:白色植物〃黑色年轮 http://blog.sina.com.cn/s/blog_4ac407c30100ge5w.html

音乐搜索系统部署说明

工作日志,转载请保留出处:唐福林 博客雨 音乐搜索系统部署说明 http://blog.fulin.org/2009/11/pcsearch_deploy.html

PC 客户端搜索系统部署说明

唐福林 <tangfulin AT gmail.com>

PC 客户端搜索系统主要由 负责建索引的 IndexServer 和负责提供搜索服务的 SearchServer 两部分组成。
IndexServer (目前是 98)负责接收资源库发过来的xml原始文件,解析原始文件,更新索引,并将更新后的索引推送到 SearchServer 上的指定目录供搜索使用。当前架构中,IndexServer 不支持分布式和负载均衡,只能部署在一台机器上。因为索引更新并不频繁,所以这里并不会带来性能瓶颈。如果是为了消除单点故障,可以在另外一台机器上起一个备份进程,当主 IndexServer 故障的时候接收资源库发过来的xml原始文件,但为了保持索引一致,建议不做实际的索引更新操作。这样 IndexServer 故障带来的唯一影响是索引更新延迟。只要做了必要的监控措施,延迟的时间是可以控制在可接受范围内的。IndexServer 主要消耗磁盘IO,也会有一些 cpu 和内存消耗。
SearchServer (目前是 221)负责对外提供搜索服务。SearchServer 当前使用 Resin 提供的 Servlet 环境,以 HTTP 协议提供 Rest 风格的服务。SearchServer 会定期查看工作目录下是否有新的索引到达,如果有,则打开新索引,关闭旧索引。已关闭的旧索引随后会被脚本删除。SearchServer 主要消耗内存和网络IO。

一。部署之前的服务器检查:

1. 确认操作系统发行版本: cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.3 (Tikanga) 或以上
2. 确认系统安装的 java 版本:java -version
java version “1.5.0_15″ 或以上
3. 确认系统安装的 rsync 版本: rsync –version
rsync version 3.0.5 protocol version 30 或以上
4. 确认磁盘空间:df -h
确保有超过 2G 的剩余空间,建议预留 5G,方便打log。如果/home下磁盘空间不够,可以使用软链接
5. 确认svn客户端版本:svn –version
确保含有 https 模块:
ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol.
- handles ‘http’ scheme
- handles ‘https’ scheme
6. 确认 ant 版本:ant -version
Apache Ant version 1.6.2 或以上
7. 确认 resin 版本:
3.1.9 或以上

二。建立目录结构

项目根目录设置为 /home/yyjd,以下的相对路径,如无特殊说明,都是相对于项目的根目录

mkdir /home/yyjd && cd /home/yyjd && mkdir code data software && cd data && mkdir -p backup dict indexes indexserver logs pids webapps/search xml

三。取得文件数据

1. 取得必要的软件
如果 “一” 中的检查不满足,或者希望安装 Hudson 或 JIRA,可以从 98 的 /home/yyjd/software 中取得软件,并进行安装。安装的时候,如果是 rpm 包,可以使用 rpm -ivh xxx.rpm 进行安装,如果是zip或tgz压缩包,解压缩即可,Hudson 是一个 war 包,可以直接运行,参考 code/PCSearcher/trunk/shell/server-start.sh 里的运行命令说明。
注意,在安装 rpm 包的时候,可能会有一些依赖问题,按照提示先安装依赖包即可;安装 rpm 包如果报冲突,在命令行上加一个 –force 参数即可。

2. 取得代码
cd /home/yyjd/code && svn checkout https://*.*.*.254/svn/PCSearch

四。相关软件设置

1. rsync 设置:在搜索机上 vi /etc/rsyncd.conf

uid = root
gid = root
max connections = 200
timeout = 600
use chroot = no
read only = no
pid file=/var/run/rsyncd.pid
hosts allow=*.*.*.98

[search]
path=/home/yyjd
comment = PCsearch project sync model

保存退出,然后运行 rsync –daemon

在 IndexServer 上测试 rsync 是否畅通:
rsync -vn 搜索机ip::search/data/indexes .
如果不通,则再测试一下使用 ssh 协议是否畅通:
首先将 IndexServer 的 /root/.ssh/id_rsa.pub (如果没有该文件,运行一下 ssh-keygen 命令)的内容添加到搜索机 /root/.ssh/authorized_keys 文件的末尾(注意不要引入多余的换行符),然后测试:
rsync -vn root@搜索机ip:/home/yyjd/data/indexes .

测试正常之后,将测试成功的地址添加到 IndexServer 的 /home/yyjd/code/PCSearcher/trunk/shell/trans-dest.conf 文件末尾

2. resin 设置:
将 data/webapps/search 目录添加到 resin app 目录列表,也可以在 resin 的 webapps 目录下建一个到 data/webapps/search 的软链接

五。编译代码

cd /home/yyjd/code/PCSearcher/trunk && svn up && ant && ant indexserver

六。启动进程
进入 /home/yyjd/code/PCSearcher/trunk/shell 目录
参考 server-start.sh
1. IndexServer:
a. 启动 resin (仅作测试,非必要)
b. 启动 IndexServer: ./indexUpdater.sh restart
c. 启动 trans 索引传输脚本:
(nohup ./trans-indexsnap.sh songs 2>&1 >> /home/yyjd/data/logs/trans-songs.log &)
(nohup ./trans-indexsnap.sh albums 2>&1 >> /home/yyjd/data/logs/trans-albums.log &)
(nohup ./trans-indexsnap.sh keywords 2>&1 >> /home/yyjd/data/logs/trans-keywords.log &)
d. 启动 clean 索引清除脚本(如果启用了 resin,就必须启动这些清除脚本):
(nohup ./clean-indexsnap.sh songs 2>&1 >> /home/yyjd/data/logs/clean-songs.log &)
(nohup ./clean-indexsnap.sh albums 2>&1 >> /home/yyjd/data/logs/clean-albums.log &)
(nohup ./clean-indexsnap.sh keywords 2>&1 >> /home/yyjd/data/logs/clean-keywords.log &)
e. 检查 /home/yyjd/data/logs 下的日志是否都正常

2. SearchServer:
a. 启动 resin
b. 启动 IndexServer: ./indexUpdater.sh restart (可以作为 IndexServer 接收xml原始文件的功能的备份,非必要)
c. 启动 clean 索引清除脚本:
(nohup ./clean-indexsnap.sh songs 2>&1 >> /home/yyjd/data/logs/clean-songs.log &)
(nohup ./clean-indexsnap.sh albums 2>&1 >> /home/yyjd/data/logs/clean-albums.log &)
(nohup ./clean-indexsnap.sh keywords 2>&1 >> /home/yyjd/data/logs/clean-keywords.log &)
d. 检查 /home/yyjd/data/logs 下的日志是否都正常

七。日常管理

1. shell 脚本介绍:code/PCSearcher/trunk/shell
build.sh : Hudson 使用的编译,重启 IndexServer 进程的脚本,不建议使用
clean-indexsnap.sh : 无用索引清除脚本,SearchServer 使用
indexUpdater.sh : 索引更新 daemon 进程,接受 {start|stop|restart} 参数调用
initKeyword.sh : 关键词索引初始化脚本,平常不用
processManager.sh : 底层的进程启动,停止管理脚本,由其他脚本调用
rebuild.sh : 模拟发送重建歌曲,专辑索引的xml原始数据的脚本,重建索引时使用
server-start.sh : 记录了新部署机器时可能会用到的启动命令,不建议直接运行
trans-dest.conf : 传输脚本的目的地址配置文件
trans-indexsnap.sh : 索引传输脚本,IndexServer 使用

2. logs 日志介绍:data/logs
classpath.log : 索引更新 daemon 进程启动的时候的 classpath,debug 使用
clean-*.log : 索引清除日志
trans-*.log : 索引传输日志
search.log : 搜索日志
indexserver.log : 索引更新日志
另外,resin 的日志也需要留意观察。

八。常见错误及修正方法

1. svn 不支持 https
2. ant 编译出错
3. indexUpdater.sh 启动 索引更新 daemon 进程 出错
4. rsync 传输出错
5. 搜索出错,出白页面或 404
6. 搜索出错,报 Exception:确认一下 data/indexes/ 下面的每个子目录下面都有索引文件