专栏首页solr lucene源码解析LockFactory索引文件锁源码解析
原创

LockFactory索引文件锁源码解析

LockFactory在lucene中用来对索引目录进行加锁,使得同一时间只能有一个IndexWriter对象对索引目录进行操作。

lucene中LockFactory实现类的继承关系如下

LockFactory类继承关系

LockFactory实现类功能描述

LockFactory实现类

功能描述

SimpleFSLockFactory

使用File.createNewFile api, 在JVM异常退出时,会在索引目录遗留write.lock文件,在下次使用时,需要手动清除该文件,比较适合NFS文件系统

NativeFSLockFactory

使用java.nio.*进行加锁,FSDirectory默认的锁实现,不适合NFS使用,在JVM异常退出时,由OS负责移除write.lock,OS并不会真正删除该文件,释放该文件上的引用,使得下次可以重新获取锁

NoLockFactory

完全关闭锁机制

1. NativeFSLockFactory源码解析

  @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 symlink
    // 如果索引目录不存在,创建索引目录
    Files.createDirectories(lockDir);
    // 获取lock文件的Path
    Path lockFile = lockDir.resolve(lockName);

    IOException creationException = null;
    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.
      creationException = ignore;
    }
    
    // fails if the lock file does not exist
    final Path realPath;
    try {
      // 如果索引锁文件无法获取到,则会抛出异常
      realPath = lockFile.toRealPath();
    } catch (IOException e) {
      // if we couldn't resolve the lock file, it might be because we couldn't create it.
      // so append any exception from createFile as a suppressed exception, in case its useful
      if (creationException != null) {
        e.addSuppressed(creationException);
      }
      throw e;
    }
    
    // used as a best-effort check, to see if the underlying file has changed
    // 获取索引锁文件的创建时间
    final FileTime creationTime = Files.readAttributes(realPath, BasicFileAttributes.class).creationTime();
    // 如果索引锁文件已经存在LOCK_HELD中,抛出异常,否则添加该对象到LOCK_HELD中
    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 out
          IOUtils.closeWhileHandlingException(channel); // TODO: addSuppressed
          clearLockHeld(realPath);  // clear LOCK_HELD last 
        }
      }
    } else {
      throw new LockObtainFailedException("Lock held by this virtual machine: " + realPath);
    }
  }

lucene的索引锁实现原理比较简单,代码比较简单,这里只是简单的介绍源码实现,感兴趣的读者,可以看lucene的源码实现。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • lucene添加文档源码解析(第二篇)

    在lucene中添加文档是通过IndexWriter.addDocument方法,我们先给出添加文档的示例代码

    LuceneReader
  • TimeLimitingCollector源码解析

    在solr的查询请求中添加timeAllowed参数,可以限定solr查询的请求时间,在solr内部,是通过TimeLimitingCollector类...

    LuceneReader
  • lucene添加文档源码解析(第一篇)

    在lucene中可以对一篇文档进行添加、修改、删除操作,在这篇文章中我们详细介绍lucene添加文档的流程,对添加文档的源码进行解析。

    LuceneReader
  • Mybatis之ParameterHandler

        可以看到,使用了TypeHandler的setParameter方法来设置参数,ParameterHandler的实现相对简单。

    克虏伯
  • Mybatis 判断等于时候无效问题解决

    <if test=" name!=null && name =='1' "><if/>

    斯文的程序
  • SharedPreferences解析

    说明:SharedPreferences与Editor只是两个接口,SharedPreferencesImpl和EditorImp分别实现了对应的接口。另外,C...

    用户1205080
  • APK安装流程详解11——普通应用安装简介

    众所周知,Android应用最终是打包成.apk格式(其实就是一个压缩包),然后安装至手机并运行的。其中APK是Android Package的缩写。

    隔壁老李头
  • 【手记】解决VS2010宏功能报错

    抱歉问题解决前没留截图,总之就是使用宏相关的功能都打不开,会弹窗报错,英文,大意是【一个或多个组件不存在,请尝试重装】。

    AhDung
  • “新基建”横空出世,9本书助你把握7+2大领域风口

    导读:新基建横空出世,中央近期频频点名,政策也陆续加码。新基建是什么?新基建为什么火了?新基建是如何成为关键词的?科技新基建包含哪些内容呢?新基建会给IT行业带...

    华章科技
  • 软件给win10快速断网

    在使用电脑中一些特殊的情况下,需要我们断开网络,一般情况下就是把无线网断开或者网线拔掉就可以了,但是有时候主机的位置很小拔网线不是很方便这时候就需要用windo...

    用户1188347

扫码关注云+社区

领取腾讯云代金券