注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

网易杭研后台技术中心的博客

 
 
 
 
 

日志

 
 

ZOIE实时索引设计分析  

来自zhuobin.he   2012-09-22 21:38:04|  分类: 检索系统 |举报 |字号 订阅

  下载LOFTER 我的照片书  |

在做NDIR项目的时候,由于底层基于ZOIE实现实时索引,对ZOIE的代码做了一定的分析,现在稍微整理一下ZOIE建索引的大致流程。本文基于ZOIE-3.0.0版本进行分析。

ZOIE索引流程大致如下图:


ZOIE实时索引设计分析 - 网易杭研后台技术中心 - 网易杭研后台技术中心的博客
 

从 上图可以看出,ZOIE整个索引线程通过3个线程处理,这样做的目的是在于通过多层次的异步线程处理,从而让索引过程中比较漫长的步骤(如写文件索引等) 不会堵塞上层提交索引请求,从而保证索引的实时性。下面将对3个线程以及相互间的关系进行分析从而介绍ZOIE的索引过程:


  1. 索引请求线程

这 个线程实际上就是用户调用ZOIE建索引的线程,在进入ZOIE索引接口后,ZOIE仅仅会把索引请求内容存放到一个缓存队列,然后检查是否已经达到缓存 上限(batchSize属性)。如果没有达到上限,马上就会返回;如果达到上限就会尝试唤醒内存索引消费线程,并进入进入等待状态,直到缓存队列中的请 求被处理完成。这样做是为了一方面减少索引请求调用的等待时间,ZOIE是准实时索引而不是实时索引,没必要同步等待每个请求索引完成;另一方面也能防止 提交索引请求太快,缓存索引请求太多导致内存溢出。


  1. 内存索引消费线程

这个线程是ZOIE内部维护的线程,他负责从索引请求缓存队列中取出请求数据,并写入内存索引。

他 本质上是一个无限的循环,在每次循环中首先会等待指定时间(这个时间决定了索引的实时性)或被索引请求线程唤醒(在缓存队列满了的时候),然后从缓存队列 取出索引数据,唤醒索引请求线程(如果在等待中),这里就把索引请求线程唤醒是由于后面的处理时间相对比较长,而索引请求线程没必要同步等待。

然 后把索引数据写入内存索引,内存索引是一个比较小的增量索引,而且内存写入速度高,因此这个过程一般不会很长,一般在1秒这个数量级内。另外,虽然内存索 引比较小且写入速度高,增量写索引依然是一个代价不小的处理,因此,缓存队列存在可以让这个过程变为批量写入新索引数据,从而提高处理效率,而批量写入的 数量则决定于循环开始的等待时间以及缓存队列的上限。

如 果此时内存索引中处理过的请求数目已经达到指定上限(maxBatchSize属性),那么内存索引消费线程会尝试唤醒刷外存索引线程并进入等待状态,直 到内存索引中的数据开始被刷写。这样做是由于如果不等待,内存索引有可能会由于索引吞吐率太高导致内存索引不断上涨而内存溢出。每次同步写外存则会导致索 引失去实时性。

如此进行循环,不断异步的消费索引请求线程提交的索引请求,从而实现实时索引。


  1. 刷外存索引线程

这个线程也是ZOIE内部维护的线程,他负责把内存索引中的数据定时定量地合并到外存索引,实现索引数据的持久化,并保持内存索引占用空间在一定范围内。

他 本质上也是一个无限的循环,在每次循环中,首先会等待指定的时间(mergeDelay属性)或被内存索引消费线程唤醒(在内存索引请求数达到设定上 限),然后如果当前内存索引消费线程使用的内存索引已经达到设定大小(batchSize属性),则会把该内存索引取出标记为只读,并替换为一个空内存索 引,然后唤醒内存索引消费线程(如果在等待中)。

取出的只读内存索引会被合并到外存索引,合并完成后,只读内存索引会被清空释放。如此循环。

这 样做的原因是通过维护最大两个内存索引,其中一个只读,一个可写,从而让ZOIE在把只读内存索引中的数据合并到文件索引的时候也能通过可写的内存索引处 理新索引请求,保证索引的实时性。在替换内存索引后就唤醒内存索引消费线程也可以减少等待时间,保证索引的实时性。然而在ZOIE-3.0.0中有一个 bug导致在写外存的时候会堵塞内存索引,详见ZOIE-108,在ZOIE-3.2.0中已经修复了。


从上面的分析可以看出,ZOIE的核心实现就是通过把整个索引过程划分为3个层次,每个层次间通过异步处理,从而简化索引流程,并且通过各个异步处理的缓冲,从而降低上层索引请求处理时被堵塞的可能性。


总结ZOIE的索引策略的效果如下:
  1. 最大异步缓存建索引数量限制为batchSize,这部分请求不能被检索出来
  2. 内存索引中最多保留maxBatchSize条记录的请求,这部分请求数据可以被检索出来;当达到这个限制的时候会堵塞异步建索引请求此时会失去索引实时性
  3. 另外当内存索引中的记录数超过batchSize,ZOIE就会开始把内存索引刷到外存,被刷到外存前重启服务器,索引数据会丢失,写外存过程中不会失去索引实时性
  4. 刷外存的时候,ZOIE会把当前的内存索引设置为只读,新开一个索引用于处理新索引请求,从而保证刷外存过程中的索引实时性
  评论这张
 
阅读(1567)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017