接上文,在上面一篇文章中,我们谈到了update中的Delete和Add
下面我们来谈谈第三个大问题,就是flush的逻辑
3 什么是flush
大家可能已经沉浸于AddNode逻辑而不能自拔了,清醒一点,我们再次回到MultiIndex#update看看,有这么一段代码:
if (flush) {
flush();
}
不知道是否有人想起flush怎么才能为true呢,当VolatileIndex处理的document超过100的时候,需要把内存中的index数据copy到persistentindex中,这个时候返回true,也就是当VolatileIndex处理的document数量超过100时,就需要执行flush操作,这个就是执行flush的一个前提,不过有一点需要注意的是:flush并不只是在update方法中调用,后面我们会阐述这个问题,请记住这个问题:还有什么操作需要调用flush呢?
那么flush方法中具体做了一些什么事情呢?让我们深入到方法的内部查看一下:
void flush() throws IOException {
/*注意这里的同步*/
synchronized (this) {
// commit volatile index
/*开启一个内部事务*/
executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
/*这里又执行了一遍commitVolatileIndex方法,这个方法的功能我们已经在本文的前半部分详细的分析过了,即把ramdirectory中的数据拷贝到fsdirectory中*/
commitVolatileIndex();
// commit persistent indexes
/*所有的persistentindex对象在创建完成之后,都会放到indexes这个list中,这个list*/
for (int i = indexes.size() - 1; i >= 0; i--) {
PersistentIndex index = (PersistentIndex) indexes.get(i);
// only commit indexes we own
// index merger also places PersistentIndex instances in indexes,
// but does not make them public by registering the name in indexNames
if (indexNames.contains(index.getName())) {
index.commit();
// check if index still contains documents
/*如果一个PersistentIndex中已经没有任何一个document的数据,那就代表它已经没有存在的必要了。*/
if (index.getNumDocuments() == 0) {
executeAndLog(new DeleteIndex(getTransactionId(), index.getName()));
}
}
}
executeAndLog(new Commit(getTransactionId()));
/*将有效的PersistentIndex写到一个文件中,一旦当机,那么便可以在重启的时候得知哪些目录是有效的索引目录,这样做是为了防止其读取需要被删除的目录*/
indexNames.write(indexDir);
// reset redo log
redoLog.clear();
lastFlushTime = System.currentTimeMillis();
}
// delete obsolete indexes
/* 删除那些需要被删除的索引目录,delete其实是索引目录的一个文件,这个文件中保存着需要被删除的目录,包含小目录合并成大目录之后需要被删掉。 */
attemptDelete();
}
在上面的flush中,我们已经看到,只有index.commit()有一点点的神秘感,其他的逻辑ahuaxuan已经写的非常详细了。其实commit就是把这个PersistentIndex对应的indexwriter关闭掉。
总结
:
从这篇文章(上,下篇)中,我们可以看到delete,add和flush的主要逻辑,那么再简单回顾一下:
1. Delete:需要把所有可能保存document的地方都检查一遍,有就删除。这些地方包括,
1) VolatileIndex中的pendding队列
2) VolatileIndex(ramdirectory)中的document的indexdata
3) IndexQueue
4) PersistentIndex(fsdirectory)
2. Add and Flush:
1) 创建document
2) 将document加入到VolatileIndex的pending中
3) pending 中的document大于10就多线程生产indexdata到ram中
4) ram中的document的index数据大于100份就新建一个persistentIndex,并把这些数据拷贝到PersistentIndex对应的磁盘目录中。
3 indexNames和deletables这两个变量分别对应两个文件,一个表示有效的索引目录,还有一个表示需要删除的索引目录。在整个update的过程中,PersistentIndex可能会新建,成为一个有效的目录,再后面的合并过程中又可能会被删除,所以用这两个变量来记录有效索引目录和需要被删除的索引目录。
通过这篇文章,我们可以得到了两个疑问:
1. indexqueue到底是怎么使用的?
2. indexmerger的逻辑是怎么样的?
同样,ahuaxuan将会在后面的文章中阐述这两个话题。
TO BE CONTINUE
分享到:
相关推荐
NULL 博文链接:https://ahuaxuan.iteye.com/blog/391361
深入浅出讲解jackrabbit 共分十个专题。PDF 文档
jackrabbit最全入门教程,jackrabbit最全入门教程,jackrabbit最全入门教程,jackrabbit最全入门教程
jackrabbit 1.5.6 jar
jackrabbit-standalone-1.6.5.jar是webDav的支持jar包。
Apache Jackrabbit API html ,非常详细,
jackrabbit开发用jar包,jackrabbit是基于Lucene的一种站内搜索技术,它用xml文件为他的元数据,自动穿件索引,使用xpath或者xquery的查询方法。
jackrabbit-api-1.5.0.jar
一个Eclipse项目, 内含三个Apache Jackrabbit的入门实例, 以及所有需要的包, 在Eclipse中可直接运行。
jackrabbit教程,主要是网上整合的资源。比较全面。用法等。
常见问题查询。作为JCR的一个实例,为用户提供一种网络存储、共享、应用的方式
jackrabbit-webdav-2.1.0.jar 具体用法可以网上查找
jackrabbit, 在amqplib上,简单的amqp/rabbitmq作业队列基于 node Jackrabbitnode.js 在不讨厌生命的情况下。producer.js:var jackrabbit = require('jackrabbit');var rabbit = jackrabbit(process
jackrabbit 研究初步,不想多说,肯定值。研究了好久哦。
jackrabbit-core-1.5.5.jar
jackrabbit-webdav-1.5.5.jar
里面包含两个工程,一个是官方的三个小demo,另一个是在ibm页面看到的实例,比小demo稍微高级一些,希望可以帮助大家迅速入门和理解jackrabbit。
Rabbit BL1800 Jackrabbit 说明书pdf,Rabbit BL1800 Jackrabbit 说明书
Jackrabbit Oak-下一代内容存储库 Jackrabbit Oak是一个可伸缩的高性能分层内容存储库,旨在用作现代世界级网站和其他要求苛刻的内容应用程序的基础。 Oak的努力是Apache Jackrabbit项目的一部分。 Apache ...
NULL 博文链接:https://kinglord2010.iteye.com/blog/665530