前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LockFactory索引文件锁源码解析

LockFactory索引文件锁源码解析

原创
作者头像
LuceneReader
修改2020-01-20 15:35:19
1K0
修改2020-01-20 15:35:19
举报

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

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

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源码解析

代码语言:javascript
复制
  @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的源码实现。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. NativeFSLockFactory源码解析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档