zoukankan      html  css  js  c++  java
  • ES failed to notify ClusterStateListener java.lang.IllegalStateException: environment is not locked

    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:

       new Lock.With(directory.makeLock("my.lock")) {
           public Object doBody() {
             ... code to execute while locked ...
           }
         }.run();

      一些加锁、解锁例子 https://www.programcreek.com/java-api-examples/index.php?api=org.apache.lucene.store.Lock
      lucene锁的作用,写保护:在Lucene中,打开一个IndexWrite之后,就会自动在索引目录中生成write.lock文件,这个文件中并不会有内容,不管是在索引打开期间还是在索引关闭之后,其大小都为0KB,并且在IndexWriter关闭之后,并不会删除该文件。如果同时打开多个IndexWriter的话,后打开的IndexWriter就会抛出LockObtainFailedException异常。这是个很重要的保护机制,因为若针对同一索引打开两个writer的话,会导致索引损坏。所以Lucene中的锁主要针对并发写的情况,在写的过程中并不会影响到并发读操作。

      1. lucene并发规则

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

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

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

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

      2. lucene锁机制

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


      而由assertEnvIsLocked看,抛出的异常应该是锁出现了问题,文件损坏或者目录损坏、或者文件系统损坏导致。
  • 相关阅读:
    【STM32H7教程】第22章 STM32H7的SysTick实现多组软件定时器
    【STM32H7教程】第21章 STM32H7的NVIC中断分组和配置(重要)
    【STM32H7教程】第20章 STM32H7的GPIO应用之无源蜂鸣器
    【STM32H7教程】第19章 STM32H7的GPIO应用之按键FIFO
    【STM32H7教程】第18章 STM32H7的GPIO应用之跑马灯
    【STM32H7教程】第17章 STM32H7之GPIO的HAL库API
    【STM32H7教程】第16章 STM32H7必备的HAL库API(重要)
    【STM32H7教程】第15章 STM32H7的GPIO基础知识(重要)
    git源码安装
    mysql创建用户与授权
  • 原文地址:https://www.cnblogs.com/bonelee/p/7909194.html
Copyright © 2011-2022 走看看