lucene中write.lock索引锁机制的原理

write.lock加锁的实现原理:

实现源码(lucene 6.0):

@Override
protected Lock obtainFSLock(FSDirectory dir, String lockName) throws IOException {Path lockDir = dir.getDirectory();// Ensure that lockDir exists and is a directory.// note: this will fail if lockDir is a symlinkFiles.createDirectories(lockDir);Path lockFile = lockDir.resolve(lockName);try {Files.createFile(lockFile);} catch (IOException ignore) {// we must create the file to have a truly canonical path.// if it's already created, we don't care. if it cant be created, it will fail below.}// fails if the lock file does not existfinal Path realPath = lockFile.toRealPath();// used as a best-effort check, to see if the underlying file has changedfinal FileTime creationTime = Files.readAttributes(realPath, BasicFileAttributes.class).creationTime();if (LOCK_HELD.add(realPath.toString())) {FileChannel channel = null;FileLock lock = null;try {channel = FileChannel.open(realPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE);lock = channel.tryLock();if (lock != null) {return new NativeFSLock(lock, channel, realPath, creationTime);} else {throw new LockObtainFailedException("Lock held by another program: " + realPath);}} finally {if (lock == null) { // not successful - clear up and move outIOUtils.closeWhileHandlingException(channel); // TODO: addSuppressedclearLockHeld(realPath);  // clear LOCK_HELD last }}} else {throw new LockObtainFailedException("Lock held by this virtual machine: " + realPath);}
}

首先会递归的创建多层目录,然后创建write.lock文件,如果已经存在抛出java.nio.file.FileAlreadyExistsException异常,捕获该异常之后不做任何处理,因为一旦索引创建之后,write.lock文件会一直存在,即使IndexWriter已经关闭,所以不能以该文件是否存在判断是否有多个IndexWriter被打开了,那么是根据什么来判断的呢?

接着会获取该文件创建时候的时间戳,并且将该文件的真实路径加入LOCK_HED, LOCK_HELD的声明如下,是一个同步的HashSet集合,在第一次打开IndexWriter的时候LOCK_HELD.add(realPath.toString())成功,然后调用FIleChannel的API去h获取锁,注意这里面重点就是channel.trylock()获取到的是FIleLock,这是系统级别的锁,即使其它进程想打开IndexWriter的时候,它虽然能够LOCK_HELD.add(realPath.toString())成功,但是在channel.tryLock()步会加锁失败,得到null,这时候程序依然会抛LockObtainFailedException异常;对于多JVM去同时写同一份索引的情况同样如此,如果在同一个进程内,后面希望打开另外的IndexWriter的时候必然LOCK_HELD.add(realPath.toString())失败,抛LockObtainFailedException异常所以如果程序或JVM崩溃,LOCK_HELD在内存中必然也失效,系统级别的锁(使用tryLock获取的文件锁)也会释放,相当于是自动解锁了,不影响下次的重新加锁操作。

补充:FileChannel中的lock()与tryLock()方法都是尝试去获取在某一文件上的独有锁(以下简称独有锁),可以实现进程间操作的互斥。区别在于lock()会阻塞(blocking)方法的执行,tryLock()则不会。

如果进程在执行lock()或tryLock()后获取到独有锁(return a FileLock object),那么进程会一直持有该锁到被释放(文件流被关闭 或 调用release() )。

如果进程P(A)持有独有锁:

1、进程P(B)执行lock()获取独有锁,则lock()所在方法会一直阻塞,直到独有锁被进程P(A)释放。

2、进程P(B)执行tryLock()获取独有锁,则tryLock()会抛出异常java.io.IOException: fcntl failed: EAGAIN (Try again)异常

 

释放锁源码:

@Override
public void close() throws IOException {if (config.getCommitOnClose()) {shutdown();} else {rollback();}

在shutdown中,Lucene会先判断一系列预先设置的参数,然后进行刷新操作,将所有在内存中缓存的更新刷新到Directory中,然后静静等待合并结束,合并之后会进行内部的提交操作

转载:

lucene源码解析:http://codepub.cn/2016/11/23/Lucene-index-file-lock-principle/

FIleChannel介绍:https://blog.csdn.net/leunging/article/details/73911927

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

正则表达式大全

[正则表达式]文本框输入内容控制 整数或者小数:^[0-9]\.{0,1}[0-9]{0,2}$ 只能输入数字:"^[0-9]*$"。 只能输入n位的数字:"^\d{n}$"。 只能输入至少n位的数字:"^\d{n,}$"。 只能输入m~n位的数字&am…

天气数据获取接口和网址汇总

免费API:https://www.sojson.com/blog/305.html 爬取网址:http://www.weather.com.cn/ https://www.tianqi.com/chinacity.html

鸡汤

史蒂芬柯维的7个习惯就是自己的原则和价值观: 积极主动以终为始要事第一双赢思维知彼解己综合综效不断更新 稻盛和的原则和价值观比如六项精进: 付出不亚于任何人的努力要谦虚,不要骄傲要每天反省或者就要感谢积善行,思利他不要…

【转载保存】索引文件锁LockFactory

索引文件锁LockFactory LockFactory在Lucene中用来对索引文件所在的目录进行加锁,使得同一时间总是只有一个IndexWriter对象可以更改索引文件,即保证单进程内(single in-process)多个不同IndexWriter对象互斥更改(多线程持有相同引用的IndexW…

lucene大牛博客汇总保存

https://www.amazingkoala.com.cn/Lucene/Index/http://codepub.cn/tags/Lucene/

no segments* file found in SimpleFSDirectory问题总结

lucene6.0版本 场景一:第一次启动程序索引库为空抛出异常 最近在写lucene发现利用lucene6.0版本时候如果索引库为空构建indexWriter,代码如下: IndexWrterConfig config new IndexWriterConfig(analyzer); IndexWriter indexWriter new …

lucene Term查询

查询demo Path path Paths.get(util.Directory.GetAppPath("indexDir"));IndexReader reader DirectoryReader.open(FSDirectory.open(path));//获取IndexSearcher对象IndexSearcher indexSearcher new IndexSearcher(reader);Query query new TermQuery(new Ter…

IndexOptions类说明

IndexOptions是在lucene-core-x.jar包下面,其作用是在新建索引时候选择索引属性。 IndexOptions是一个枚举类: 枚举变量说明: NONE不被索引DOCS_AND_FREQS文档和词频建立索引DOCS_AND_FREQS仅对文档和词频建立索引DOCS_AND_FREQS_AND_POSIT…

【转载保存】lucene正则查询使用注意

今天要分享的是关于lucene中另外一种丰富的查询方式----正则查询,lucene内置了许多的查询API,以及更强大的自定义查询方式的QueryParse,大部分情况下我们使用内置的查询API,基本上就可以满足我们的需求了,但是如果你想…

lucene 各个版本介绍

官方说明文档:https://lucene.apache.org/core/8_3_0/changes/Changes.html#v8.3.0.other 开源中国翻译:https://www.oschina.net/p/lucene

【转载保存】搜索引擎调研文档

搜索引擎选型调研文档 Elasticsearch简介* Elasticsearch是一个实时的分布式搜索和分析引擎。它可以帮助你用前所未有的速度去处理大规模数据。 它可以用于全文搜索,结构化搜索以及分析,当然你也可以将这三者进行组合。 Elasticsearch是一个建立在全…

webmagic抓取实例

git地址:https://github.com/code4craft/webmagic/tree/master/webmagic-samples/src/main/java/us/codecraft/webmagic/samples

lucene详细说明文档

以下部门功能在lucene5以上版本可能有的API所有改变 目录1.简介 2.了解索引操作 2.1倒排索引 2.2字段类型 2.3细分 2.4文件编号 2.5搜索索引 3.创建索引 4.基本索引操作 4.1核心索引类 4.2将数据添加到索引 5.文件和领域 5.1文件 5.2领域 5.3在Lucene中增强文档 1.简介 该索引是…

SimpleDateFormat(线程不安全)与DateTimeFormatter(线程安全)

https://www.liaoxuefeng.com/wiki/1252599548343744/1303985694703650

【转载保存】java8新特性学习

编者注:Java 8已经公布有一段时间了,种种迹象表明Java 8是一个有重大改变的发行版。 在Java Code Geeks上已经有大量的关于Java 8 的教程了,像玩转Java 8——lambda与并发,Java 8 Date Time API 教程: LocalDateTime和…

influxDb 异常:{“error“:“retention policy not found: default“}

第一次用influxDb,通过java客户端插入数据的时候总是报这个异常,后来发现命令行中插入数据是好的,但是客户端就是不行,后来检查代码发现是自己的配置中保留策略名写错了 。 修改代码:将RETENTION_POLICY_DEFAULT值设置…

【转载保存】什么是线程阻塞?为什么会出现线程阻塞?

为什么会出现线程阻塞? 1.睡眠状态:当一个线程执行代码的时候调用了sleep方法后,线程处于睡眠状态,需要设置一个睡眠时间,此时有其他线程需要执行时就会造成线程阻塞,而且sleep方法被调用之后,…

【转载保存】ThreadPoolExecutor类使用详解

线程启动原理线程中断机制多线程实现方式FutureTask实现原理线程池之ThreadPoolExecutor概述线程池之ThreadPoolExecutor使用线程池之ThreadPoolExecutor状态控制线程池之ThreadPoolExecutor执行原理线程池之ScheduledThreadPoolExecutor概述线程池的优雅关闭实践 转载&#x…

maven (http://repo1.maven.org/maven2/): Failed to transfer file 和PKIX path building failed: sun.secu

<?xml version"1.0" encoding"UTF-8"?> <settings xmlns"http://maven.apache.org/SETTINGS/1.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/SETTINGS/1.0.…