Lucene 索引滚动流程设计
TangFulin <tangfulin@gmail.com>
一. Index Writer:
1. 这里的 Writer 包括 Index Updater 和 Index Rebuilder ,但 Rebuilder 产生的索引文件不直接传送给 Searcher 使用,
而是覆盖 Updater 的索引,由 Updater 统一处理后续的流程
2. IndexUpdaterScheduler 每隔一段时间会设置 copy out timer 标识。
3. Updater 每次处理完一批 xml 文件后会查看 copy out timer 标识是否已经被设置,
如果是,则将当前的索引拷贝一份到 src-snap 目录下 yyyyMMddHHmm 格式的子目录中
4. Updater 为单线程,每次处理完一批 xml 后都会调用 optimizeAndCloseIdx ,所以可以保证 idx 数据是完整的
5. 拷贝数据完成后,在该子目录下 touch 一个 copy.done.flag 标识文件
二. Index Transfer:(rsync src-snap 中的新索引到 Index Searcher)
1. 监控 src-snap 目录下是否有新的子目录出现,且子目录下是否有 copy.done.flag 标识
2. 发现新目录后,两阶段传送数据:
2.1 首先将目录下的数据传送到 Index Searcher,如果出错则停止,成功则继续进行下一步
2.2 touch 一个 trans.done.flag 标识文件,并传送到 Index Searcher
3. 成功传送目录后删除 src-snap 下的源目录
三. Index Searcher
1. MySearcherRoller 定期检查 dest 目录下是否有新的索引目录,且该目录下有 trans.done.flag 标识文件
2. 如果发现多个索引目录,则比较目录的 lastModifyTime,选择最新的一个目录,其他目录标识为 skipped
3. 如果当前可用索引 List 无空位置,则关闭最老的一个索引(并将目录标识为 closed),腾出空间。如果关闭失败(可能有未完成的请求仍然在使用它),则跳过本次处理流程
4. 打开最新的索引,预热新打开的索引,将新打开的索引放入可用索引 List
5. 将内部 pointer 指向最新打开的索引。接下来 Searcher 调用 getLuceneSearcher 的时候,即返回最新的索引给新的请求,未完成的老的请求仍然使用旧的有效的索引
6. 当前可用索引 List 容量为 4 ,即 MySearcherRoller 同时打开了 4 份索引,如果要打开第 5 份索引,则需要关闭最老的一个。
7. 当前使用计数器的方式来检查某一个索引是否有未完成的请求。每次 Searcher 调用 getLuceneSearcher,则计数器加1,调用 returnLuceneSearcher,则计数器减1。
四. Index Cleaner
1. 监控 Searcher 的 dest 目录,查找含有 skipped 标识或者 closed 标识的目录,并删除
五. Index Monitor
1. 监控以上服务或进程是否存在,如果不存在,则报警(当前还未实现)并尽量自动重启
2. 监控 log (当前还未实现)
参考:http://www.opensubscriber.com/message/lucene-user@jakarta.apache.org/802222.html
{ 3 } Comments
Index Searcher 使用一个可用索引 List 的原因在于,如果只有一个索引,更新的时候reopen,则不可避免的要进行同步,要使用锁。synchronized is evil!
重整索引更新流程基本完成:
1。当前测试索引更新周期为 4-5 分钟
2。当前同时打开 3 份索引,索引滚动切换,切换不需要使用锁。任何时刻都有可用的索引
3。索引打开后,会先进行查询预热,然后再投入使用
4。未完成:从 updater 到 searcher 只传送增量部分(计划合并到大小库拆分工作中去)
学习学习~
{ 1 } Trackback
[...] 原文:http://tangfl.yo2.cn/2009/04/lucene_index_roller.html 评论及建议请尽量提交到原文处,谢谢! [...]
Post a Comment