ES出现异常:

failed to notify ClusterStateListener
java.lang.IllegalStateException: environment is not locked

定位代码:

 

下载ES 5.5源码,在main/java/org/elasticsearch/env/NodeEnvironment.java 里可以看到:

private void assertEnvIsLocked() {
        if (!closed.get() && locks != null) {
            for (Lock lock : locks) {
                try {
                    lock.ensureValid();
                } catch (IOException e) {
                    logger.warn("lock assertion failed", e);
                    throw new IllegalStateException("environment is not locked", e);
                }
            }
        }
    }
assertEnvIsLocked调用地方,可以看到在检测ES node数据路径、index路径使用:
/**
     * Returns an array of all of the nodes data locations.
     * @throws IllegalStateException if the node is not configured to store local locations
     */
    public Path[] nodeDataPaths() {
        assertEnvIsLocked();
        Path[] paths = new Path[nodePaths.length];
        for(int i=0;i<paths.length;i++) {
            paths[i] = nodePaths[i].path;
        }
        return paths;
    }

    /**
     * Returns an array of all of the {@link NodePath}s.
     */
    public NodePath[] nodePaths() {
        assertEnvIsLocked();
        if (nodePaths == null || locks == null) {
            throw new IllegalStateException("node is not configured to store local location");
        }
        return nodePaths;
    }

    public int getNodeLockId() {
        assertEnvIsLocked();
        if (nodePaths == null || locks == null) {
            throw new IllegalStateException("node is not configured to store local location");
        }
        return nodeLockId;
    }

    /**
     * Returns all index paths.
     */
    public Path[] indexPaths(Index index) {
        assertEnvIsLocked();
        Path[] indexPaths = new Path[nodePaths.length];
        for (int i = 0; i < nodePaths.length; i++) {
            indexPaths[i] = nodePaths[i].resolve(index);
        }
        return indexPaths;
    }

 

而locks变量的赋值在:
public NodeEnvironment(Settings settings, Environment environment) throws IOException {

        if (!DiscoveryNode.nodeRequiresLocalStorage(settings)) {
            nodePaths = null;
            sharedDataPath = null;
            locks = null;
            nodeLockId = -1;
            nodeMetaData = new NodeMetaData(generateNodeId(settings));
            logger = Loggers.getLogger(getClass(), Node.addNodeNameIfNeeded(settings, this.nodeMetaData.nodeId()));
            return;
        }
        final NodePath[] nodePaths = new NodePath[environment.dataWithClusterFiles().length];
        final Lock[] locks = new Lock[nodePaths.length];
        boolean success = false;
        。。。

查了下Lock这个类:

import org.apache.lucene.store.Lock

 

作用:

  • org.apache.lucene.store.Lock
  • An interprocess mutex lock.
    Typical use might look like:
LockObtainFailedException

1. lucene并发规则

a,任意数量的只读属性IndexReader类都可以同时打开一个索引。

b,对于一个索引来说,一次只能打开一个IndexWriter对象。lucene采用锁来提供保障。

c,IndexReader可以在indexwriter正在修改索引时打开。该对象只有在IndexWriter提交修改或自己重新打开后才能获知索引的修改情况。

d,任意多个线程可以共享同一个indexreader或indexwriter。

2. lucene锁机制

为了实现单一的writer,lucene采用了基于文件的锁,如果锁文件(默认writer.lock)存在于你的索引所在目录内,说明此时正在打开一个writer。此时若企图对同一个索引文件创建其他的writer的话,将产生一个LockObtainFailedException异常。

而由assertEnvIsLocked看,抛出的异常应该是锁出现了问题,文件损坏或者目录损坏、或者文件系统损坏导致。
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java