IT技术博客大学习 共学习 共进步

挑战邮箱搜索(续一)

福林雨-博客 2010-09-28 09:20:54 浏览 2,741 次

接上 挑战邮箱搜索

搜索速度的问题还没找到好的办法,其他的问题又来了。

首先是排序的问题。Lucene 默认的排序考虑了很多因素,套用到邮箱搜索的结果里,很多时候反而显得结果很混乱,不同文件夹,不同时间,不同主题,不同发件人的邮件混在一起,更严重的是,已读邮件和未读邮件混在一起了:已读和未读邮件的 css 样式是不一样的,混在一起的结果就是,界面看起来非常混乱。一方面协调前台的工程师修改界面的 css ,另一方面也在想办法整理搜索返回的结果列表。在与产品老大的一次讨论中,产品老大提出了一个想法:能不能将 Lucene 的打分从连续的实数改成阶梯状的区间范围?如果能,在同一区间内的邮件,便可以按照收信的时间,或者发件人,或者主题等明显有序的字段进行排序了。经过深入的研究 Lucene 的打分过程,最终实现了这样的目标:首先实现了一个自己的 Similarity 子类,将那些影响排序的因子值都设置为 1.0f ,这样,最终的分数就只是命中词的得分的简单相加,命中词的个数成了得分的唯一影响因子;然后又实现了一个 FieldComparator,提供针对文档 score 的 precisionCompare:如果 |score1-score2|/(score1+score2)<1%,则返回 0,即认为两个文档得分相同,以使用下一个字段进行排序。经过这样的处理以后,默认的排序结果终于看起来不那么混乱了。

还有邮件解析问题。就像我在我的微博http://t.sina.com.cn/tangfl)上抱怨的那样:“强烈鄙视当初设计邮件格式的人,把一个简单的东西搞的无比的复杂,到处出错。来自新浪微博”   “谁能告诉我为什么有那么多封邮件的编码被设置成 GB2132 ?没办法,只能用更猥琐的办法来兼容如此猥琐的垃圾邮件。来自新浪微博”    以及一堆的小问题:outlook 转发时带的 winmail.dat ,To 字段为空,mime part 之间缺少空行,不指定任何编码(甚至有指定错误的编码的,不知是故意的还是无意的),text 段里带 html 标签,base64 编码错误,等等等等。更别说部门内部因为历史原因,当前存在三个解信库:后台 C 库,前台 php 库,以及搜索使用的 java mail 库,三个库对不符合规范的错误邮件的容忍程度不一样,导致各种解信错误层出不穷。最初设计邮件系统的人一定不是做技术的吧,可是最初实现 mta,mua 的那些人,为什么不直接把不符合 rfc 的邮件拒之门外呢?

最痛苦的问题,莫过于更新了。为了支持复杂的查询,我们把一些非邮件本身的数据,如邮件在哪个文件夹,邮件的已读未读状态等,都建到了索引里。而这些数据的更新,都会导致索引的更新。Lucene 的索引,严格来说是不存在所谓的“更新”操作的,更新是用删除加添加两个动作的组合来实现的。而且,Lucene 更新文档的时候,不能只更新指定的一个或多个字段,而是一定要整个文档更新。更而且,在更新这个文档的时候,文档所在的整个 Lucene 的索引段的数据,都需要更新。更新的代价如此的高昂,而真正使用的概率又如此的小。权衡之下,我们选择了另一条路:“用 Lucene 做搜索,最痛恨的莫过于某个文档的某几个字段频繁变动,引起频繁的重建整个文档的索引。如果这几个字段只用来限制结果范围,而不参与排序,则可以将这几个字段拿到索引外面去,正常的搜索完成以后,再从外部获取数据,过滤结果集合。邮件搜索里的文件夹,标志位等数据,完全可以这么干 来自新浪微博

网络层也出过很郁闷的问题:搜索用的是 netty 包,而与之通讯的其他进程,几乎都是用 C 写的,而且是不同的原作者,又经过不知多少的人做过不知多少次的更新。搜索的机器是 Centos,而邮箱其他地方几乎都是 Freebsd,存储上是 Solaris + zfs。于是问题就来了,时不时的 netty 里就报一个 ClosedChannelException,或者 broken pipe,或者 read/write timeout。机器之间不是直接调用,中间还隔着 F5 。查了几次,都没有得出最终的结论。在所有的调用发起方都增加了 retry ,也算是 work around 了。

(未完待续)

建议继续学习

  1. 搜狐闪电邮箱的 Nginx/Postfix 使用模式 (阅读 33,760)
  2. 怎样用好Google进行搜索 (阅读 15,662)
  3. 淘宝搜索:定向抓取网页技术漫谈 (阅读 9,362)
  4. 简析搜索引擎中网络爬虫的搜索策略 (阅读 7,281)
  5. 几种常见的基于Lucene的开源搜索解决方案对比 (阅读 5,981)
  6. 基于用户行为分析的搜索引擎自动性能评价 (阅读 5,602)
  7. 百度搜索URL参数解析 (阅读 5,581)
  8. 用Sphinx快速搭建站内搜索功能 (阅读 5,563)
  9. Xapian搜索体系结构 (阅读 5,161)
  10. 附近地点搜索初探 (阅读 5,141)