You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ka...@apache.org on 2021/05/11 19:27:32 UTC

[iotdb] branch f_index_dev updated: add time out, show INFO log

This is an automated email from the ASF dual-hosted git repository.

kangrong pushed a commit to branch f_index_dev
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/f_index_dev by this push:
     new 13b6b88  add time out, show INFO log
13b6b88 is described below

commit 13b6b8873723001d7a21f1a7b9060a6325db0ecf
Author: kr11 <3095717866.com>
AuthorDate: Wed May 12 03:26:50 2021 +0800

    add time out, show INFO log
---
 .../java/org/apache/iotdb/db/index/IndexManager.java | 13 +++++++++++--
 .../org/apache/iotdb/db/index/IndexProcessor.java    |  2 ++
 .../apache/iotdb/db/index/algorithm/RTreeIndex.java  |  2 ++
 .../iotdb/db/index/algorithm/elb/ELBIndex.java       | 13 ++++++++++++-
 .../iotdb/db/index/algorithm/mmhh/MMHHIndex.java     | 10 ++++++++++
 .../apache/iotdb/db/index/algorithm/rtree/RTree.java |  6 +++++-
 .../iotdb/db/index/read/QueryIndexExecutor.java      |  8 +++++++-
 .../iotdb/db/index/stats/IndexStatManager.java       |  8 +++++++-
 .../iotdb/db/qp/physical/crud/QueryIndexPlan.java    |  9 +++++++++
 .../org/apache/iotdb/db/service/TSServiceImpl.java   | 16 +++++++++++++++-
 .../org/apache/iotdb/db/index/it/ELBIndexReadIT.java |  1 +
 .../apache/iotdb/db/index/it/MMHHIndexReadIT.java    |  5 +++--
 .../apache/iotdb/db/index/it/PytorchLoadTest.java    |  1 +
 server/src/test/resources/logback.xml                |  1 +
 .../org/apache/zeppelin/iotdb/IoTDBInterpreter.java  | 20 ++++++++++++++++++++
 .../apache/zeppelin/iotdb/IoTDBInterpreterTest.java  | 14 ++++++++++++++
 16 files changed, 120 insertions(+), 9 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/index/IndexManager.java b/server/src/main/java/org/apache/iotdb/db/index/IndexManager.java
index f34039e..03f2e02 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/IndexManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/IndexManager.java
@@ -189,6 +189,7 @@ public class IndexManager implements IndexManagerMBean, IService {
    * @param queryProps the properties of this query.
    * @param context the query context.
    * @param alignedByTime whether aligned index result by timestamps.
+   * @param timeout index should early-stop when the execution time > timeout.
    * @return the index query result.
    */
   public QueryDataSet queryIndex(
@@ -196,9 +197,13 @@ public class IndexManager implements IndexManagerMBean, IService {
       IndexType indexType,
       Map<String, Object> queryProps,
       QueryContext context,
-      boolean alignedByTime)
+      boolean alignedByTime,
+      long timeout)
       throws QueryIndexException, StorageEngineException {
-    IndexStatManager.totalQueryCost = System.nanoTime();
+    long current = System.nanoTime();
+    IndexStatManager.totalQueryCost = current;
+    IndexStatManager.latestTimestamp = current + timeout * 1000_000;
+    logger.info("index query time out has been set to {} sec", timeout);
     if (paths.size() != 1) {
       throw new QueryIndexException("Index allows to query only one path");
     }
@@ -261,7 +266,9 @@ public class IndexManager implements IndexManagerMBean, IService {
 
   /** close the index manager. */
   private synchronized void close() {
+    logger.info("IndexManager begins closing");
     router.serialize(true);
+    logger.info("IndexManager finishes closing");
   }
 
   @Override
@@ -269,6 +276,7 @@ public class IndexManager implements IndexManagerMBean, IService {
     if (!config.isEnableIndex()) {
       return;
     }
+    logger.info("IndexManager starts...");
     IndexBuildTaskPoolManager.getInstance().start();
     try {
       JMXService.registerMBean(this, ServiceType.INDEX_SERVICE.getJmxName());
@@ -278,6 +286,7 @@ public class IndexManager implements IndexManagerMBean, IService {
     } catch (Exception e) {
       throw new StartupException(e);
     }
+    logger.info("IndexManager starts successfully");
   }
 
   public Map<PartialPath, Map<IndexType, IndexInfo>> getIndexInfos(PartialPath prefixPath) {
diff --git a/server/src/main/java/org/apache/iotdb/db/index/IndexProcessor.java b/server/src/main/java/org/apache/iotdb/db/index/IndexProcessor.java
index 7b1d965..86e0ff7 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/IndexProcessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/IndexProcessor.java
@@ -258,6 +258,7 @@ public class IndexProcessor implements Comparable<IndexProcessor> {
     if (closed) {
       return;
     }
+    logger.info("IndexProcessor {} begins closing", indexSeries);
     waitingFlushEndAndDo(
         () -> {
           lock.writeLock().lock();
@@ -284,6 +285,7 @@ public class IndexProcessor implements Comparable<IndexProcessor> {
             lock.writeLock().unlock();
           }
         });
+    logger.info("IndexProcessor {} finishes closing", indexSeries);
   }
 
   private void waitingFlushEndAndDo(IndexNaiveFunc indexNaiveAction) throws IOException {
diff --git a/server/src/main/java/org/apache/iotdb/db/index/algorithm/RTreeIndex.java b/server/src/main/java/org/apache/iotdb/db/index/algorithm/RTreeIndex.java
index 14e76c5..a9f0ac5 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/algorithm/RTreeIndex.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/algorithm/RTreeIndex.java
@@ -147,12 +147,14 @@ public abstract class RTreeIndex extends IoTDBIndex {
 
   @Override
   protected void flushIndex() {
+    logger.info("RTreeIndex {} starts serialization", indexSeries);
     try (OutputStream outputStream = new FileOutputStream(featureFile)) {
       rTree.serialize(outputStream);
       rTree.clear();
     } catch (IOException e) {
       logger.error("Error when serialize router. Given up.", e);
     }
+    logger.info("RTreeIndex {} finishes serialization", indexSeries);
   }
 
   private void initRTree() {
diff --git a/server/src/main/java/org/apache/iotdb/db/index/algorithm/elb/ELBIndex.java b/server/src/main/java/org/apache/iotdb/db/index/algorithm/elb/ELBIndex.java
index 580069b..44c8b9c 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/algorithm/elb/ELBIndex.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/algorithm/elb/ELBIndex.java
@@ -99,7 +99,7 @@ import static org.apache.iotdb.db.index.common.IndexType.ELB_INDEX;
  */
 public class ELBIndex extends IoTDBIndex {
 
-  private final Logger logger = LoggerFactory.getLogger(ELBIndex.class);
+  private static final Logger logger = LoggerFactory.getLogger(ELBIndex.class);
   private ELBType elbType;
 
   private ELBCountFeatureExtractor elbMatchPreprocessor;
@@ -176,6 +176,7 @@ public class ELBIndex extends IoTDBIndex {
 
   @Override
   protected void flushIndex() {
+    logger.info("ELBIndex {} start serialization", indexSeries);
     try (OutputStream outputStream = new FileOutputStream(featureFile)) {
       ReadWriteIOUtils.write(windowBlockFeatures.size(), outputStream);
       for (ELBWindowBlockFeature features : windowBlockFeatures) {
@@ -187,6 +188,7 @@ public class ELBIndex extends IoTDBIndex {
     } catch (IOException e) {
       logger.error("Error when serialize router. Given up.", e);
     }
+    logger.info("ELBIndex {} finish serialization", indexSeries);
   }
 
   @TestOnly
@@ -294,6 +296,7 @@ public class ELBIndex extends IoTDBIndex {
         ELBCountFeatureExtractor featureExtractor =
             new ELBCountFeatureExtractor(
                 tsDataType, struct.pattern.length, blockWidth, elbType, true);
+        boolean alreadyTimeout = false;
         while (reader.hasNextBatch()) {
           BatchData batch = reader.nextBatch();
           long featureStart = System.nanoTime();
@@ -311,6 +314,11 @@ public class ELBIndex extends IoTDBIndex {
               TVList.append(tvList, p.tvList, p.offset, p.length);
               PartialPath showPath = indexSeries.concatNode(String.valueOf(tvList.getMinTime()));
               res.add(new DistSeries(0, tvList, showPath));
+              if(IndexStatManager.alreadyTimeout()){
+                logger.warn("ELB query on {}: already timeout", indexSeries);
+                alreadyTimeout = true;
+                break;
+              }
               // add no-overlap
               final boolean noOverlap = true;
               if (noOverlap) {
@@ -322,6 +330,9 @@ public class ELBIndex extends IoTDBIndex {
           }
           featureExtractor.clearProcessedSrcData();
           featureTotal += System.nanoTime() - featureStart;
+          if(alreadyTimeout){
+            break;
+          }
         }
         reader.close();
         long loadTotal = System.nanoTime() - loadStart;
diff --git a/server/src/main/java/org/apache/iotdb/db/index/algorithm/mmhh/MMHHIndex.java b/server/src/main/java/org/apache/iotdb/db/index/algorithm/mmhh/MMHHIndex.java
index 783482e..eaeab75 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/algorithm/mmhh/MMHHIndex.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/algorithm/mmhh/MMHHIndex.java
@@ -164,8 +164,10 @@ public class MMHHIndex extends IoTDBIndex {
 
   @Override
   protected void flushIndex() {
+    logger.info("MMHHIndex {} starts serialization", indexSeries);
     serializeHashLookup();
     hashLookupTable.clear();
+    logger.info("MMHHIndex {} finishes serialization", indexSeries);
   }
 
   private void deserializeHashLookup() {
@@ -365,6 +367,10 @@ public class MMHHIndex extends IoTDBIndex {
       if (full) {
         break;
       }
+      if(IndexStatManager.alreadyTimeout()){
+        logger.warn("MMHH query on {}: already timeout", indexSeries);
+        break;
+      }
     }
     return res;
   }
@@ -398,6 +404,10 @@ public class MMHHIndex extends IoTDBIndex {
         if (full) {
           return true;
         }
+        if(IndexStatManager.alreadyTimeout()){
+          logger.warn("MMHH query on {}: already timeout, MMHHIndex:406", indexSeries);
+          return true;
+        }
         // change bit back
         queryCode = reverseBit(queryCode, doIdx);
       }
diff --git a/server/src/main/java/org/apache/iotdb/db/index/algorithm/rtree/RTree.java b/server/src/main/java/org/apache/iotdb/db/index/algorithm/rtree/RTree.java
index d05ddfb..1fc07e5 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/algorithm/rtree/RTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/algorithm/rtree/RTree.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.db.exception.index.IndexRuntimeException;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.index.common.DistSeries;
 import org.apache.iotdb.db.index.common.TriFunction;
+import org.apache.iotdb.db.index.stats.IndexStatManager;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.utils.datastructure.TVList;
 import org.apache.iotdb.tsfile.utils.Pair;
@@ -740,7 +741,10 @@ public class RTree<T> {
                 patternFeatures);
         bsfAnswer.dist =
             minTopKDistOfNode(pairs.right, pairs.left, queryTs, topKPQ, calcRealDistFunc, topK);
-
+        if(IndexStatManager.alreadyTimeout()){
+          logger.warn("RTree query already timeout, no more visiting leaf node, RTree:745");
+          break;
+        }
       } else {
         //        processInnerCount++;
         // minPqItem is internal
diff --git a/server/src/main/java/org/apache/iotdb/db/index/read/QueryIndexExecutor.java b/server/src/main/java/org/apache/iotdb/db/index/read/QueryIndexExecutor.java
index 031c3bf..d3ca4b9 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/read/QueryIndexExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/read/QueryIndexExecutor.java
@@ -38,19 +38,25 @@ public class QueryIndexExecutor {
   private final QueryContext context;
   private final List<PartialPath> paths;
   private final boolean alignedByTime;
+  private long timeout;
 
   public QueryIndexExecutor(QueryIndexPlan queryIndexPlan, QueryContext context) {
     this.indexType = queryIndexPlan.getIndexType();
     this.queryProps = IndexUtils.toUpperCaseProps(queryIndexPlan.getProps());
     this.paths = queryIndexPlan.getPaths();
     this.alignedByTime = queryIndexPlan.isAlignedByTime();
+    this.timeout = queryIndexPlan.getIndexTimeoutInMs();
     //    this.paths.forEach(PartialPath::toLowerCase);
     this.context = context;
   }
 
+  public long getIndexTimeoutInMs() {
+    return timeout;
+  }
+
   public QueryDataSet executeIndexQuery() throws StorageEngineException, QueryIndexException {
     // get all related storage group
     return IndexManager.getInstance()
-        .queryIndex(paths, indexType, queryProps, context, alignedByTime);
+        .queryIndex(paths, indexType, queryProps, context, alignedByTime, timeout);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/index/stats/IndexStatManager.java b/server/src/main/java/org/apache/iotdb/db/index/stats/IndexStatManager.java
index d24b65f..84e7f44 100644
--- a/server/src/main/java/org/apache/iotdb/db/index/stats/IndexStatManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/index/stats/IndexStatManager.java
@@ -30,7 +30,8 @@ public class IndexStatManager {
   public static long featureExtractCost = 0;
   public static long totalQueryCost = 0;
   public static long loadRawDataCost = 0;
-
+  public static long latestTimestamp = 0;
+  
   public static String provideReport() {
     // total:%.3fms-feature:%.3fms-load:%.3fms
     String ret =
@@ -44,4 +45,9 @@ public class IndexStatManager {
     loadRawDataCost = 0;
     return ret;
   }
+
+  public static boolean alreadyTimeout() {
+    long current = System.nanoTime();
+    return current > latestTimestamp;
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryIndexPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryIndexPlan.java
index 63bcae8..09032ff 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryIndexPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryIndexPlan.java
@@ -30,6 +30,7 @@ public class QueryIndexPlan extends RawDataQueryPlan {
   private IndexType indexType;
   // for now, it's always true
   private boolean alignedByTime = true;
+  private long indexTimeoutInMs;
 
   public QueryIndexPlan() {
     super();
@@ -83,4 +84,12 @@ public class QueryIndexPlan extends RawDataQueryPlan {
   public String toString() {
     return String.format("Query paths: %s, index type: %s, props: %s", paths, indexType, props);
   }
+
+  public void setIndexTimeoutInMs(long indexTimeoutInMs) {
+    this.indexTimeoutInMs = indexTimeoutInMs;
+  }
+
+  public long getIndexTimeoutInMs() {
+    return indexTimeoutInMs;
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index 7fa107d..b6f9b6c 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -630,7 +630,21 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
       queryId = generateQueryId(true, fetchSize, deduplicatedPathNum);
       // register query info to queryTimeManager
       if (!(plan instanceof ShowQueryProcesslistPlan)) {
-        queryTimeManager.registerQuery(queryId, startTime, statement, timeout);
+        if (plan instanceof QueryIndexPlan) {
+          long actualTimeout = timeout == 0 ? config.getQueryTimeThreshold() : timeout;
+          ((QueryIndexPlan) plan).setIndexTimeoutInMs(actualTimeout);
+          // it's a hyper-parameter, we can add it into .properties.
+          // although we cannot trust that index always return result before time out, but index
+          // will early-stop the query
+//          long indexQueryExtraTimeInMs = 3_000;
+          long indexQueryExtraTimeInMs = 3_000;
+          long indexFinalTimeout = actualTimeout + indexQueryExtraTimeInMs;
+          queryTimeManager.registerQuery(queryId, startTime, statement, indexFinalTimeout);
+        }
+        else{
+          queryTimeManager.registerQuery(queryId, startTime, statement, timeout);
+        }
+
       }
       if (plan instanceof QueryPlan && config.isEnablePerformanceTracing()) {
         TracingManager tracingManager = TracingManager.getInstance();
diff --git a/server/src/test/java/org/apache/iotdb/db/index/it/ELBIndexReadIT.java b/server/src/test/java/org/apache/iotdb/db/index/it/ELBIndexReadIT.java
index 1e6902d..535afd7 100644
--- a/server/src/test/java/org/apache/iotdb/db/index/it/ELBIndexReadIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/index/it/ELBIndexReadIT.java
@@ -258,6 +258,7 @@ public class ELBIndexReadIT {
               + String.format("CONCAT (%s) WITH TOLERANCE 0 ", getArrayRange(250, 300, 10))
               + String.format("CONCAT (%s) WITH TOLERANCE 0 ", getArrayRange(400, 430, 10));
       System.out.println(querySQL);
+      statement.setQueryTimeout(20);
       boolean hasIndex = statement.execute(querySQL);
       String gt =
           "Time,root.wind1.azq01.speed.17,\n"
diff --git a/server/src/test/java/org/apache/iotdb/db/index/it/MMHHIndexReadIT.java b/server/src/test/java/org/apache/iotdb/db/index/it/MMHHIndexReadIT.java
index 71d93db..38974f3 100644
--- a/server/src/test/java/org/apache/iotdb/db/index/it/MMHHIndexReadIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/index/it/MMHHIndexReadIT.java
@@ -117,10 +117,11 @@ public class MMHHIndexReadIT {
           statement.execute(insertSQL);
         }
       }
+      IndexManager.getInstance().stop();
+      IndexManager.getInstance().start();
       statement.execute("flush");
       System.out.println(IndexManager.getInstance().getRouter());
-      //      IndexManager.getInstance().stop();
-      //      IndexManager.getInstance().start();
+
 
     } catch (Exception e) {
       e.printStackTrace();
diff --git a/server/src/test/java/org/apache/iotdb/db/index/it/PytorchLoadTest.java b/server/src/test/java/org/apache/iotdb/db/index/it/PytorchLoadTest.java
index 5799bd9..33ec192 100644
--- a/server/src/test/java/org/apache/iotdb/db/index/it/PytorchLoadTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/index/it/PytorchLoadTest.java
@@ -83,5 +83,6 @@ public class PytorchLoadTest {
       }
       System.out.println();
     }
+    model.close();
   }
 }
diff --git a/server/src/test/resources/logback.xml b/server/src/test/resources/logback.xml
index 636914e..42bc79d 100644
--- a/server/src/test/resources/logback.xml
+++ b/server/src/test/resources/logback.xml
@@ -46,6 +46,7 @@
     <logger name="org.apache.iotdb.db.service.MetricsService" level="INFO"/>
     <logger name="org.apache.iotdb.db.engine.flush.FlushManager" level="INFO"/>
     <logger name="org.apache.iotdb.db.integration.IoTDBMergeIT" level="INFO"/>
+    <logger name="org.apache.iotdb.db.index" level="INFO"/>
     <logger name="org.apache.iotdb.db.service.RegisterManager" level="INFO"/>
     <logger name="org.apache.iotdb.db.service.IoTDB" level="WARN"/>
     <logger name="org.apache.iotdb.db.service.RPCService" level="INFO"/>
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/iotdb/IoTDBInterpreter.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/iotdb/IoTDBInterpreter.java
index d97dacb..f4d0102 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/iotdb/IoTDBInterpreter.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/iotdb/IoTDBInterpreter.java
@@ -83,6 +83,7 @@ public class IoTDBInterpreter extends AbstractInterpreter {
   private static final String HELP = "help";
   private static final String IMPORT_CMD = "import";
   static final String SET_TIMESTAMP_DISPLAY = "set time_display_type";
+  static final String SET_QUERY_TIMEOUT = "set query_time_timeout";
   private static final String SET_MAX_DISPLAY_NUM = "set max_display_num";
   private static final String SHOW_TIMESTAMP_DISPLAY = "show time_display_type";
   private static final String SET_TIME_ZONE = "set time_zone";
@@ -107,6 +108,8 @@ public class IoTDBInterpreter extends AbstractInterpreter {
 
   private String timeFormat;
 
+  private int queryTimeout = -1;
+
   private IoTDBConnectionException connectionException;
   private IoTDBConnection connection = null;
   private int fetchSize;
@@ -199,6 +202,10 @@ public class IoTDBInterpreter extends AbstractInterpreter {
     }
   }
 
+  public int getQueryTimeout() {
+    return queryTimeout;
+  }
+
   private InterpreterResult handleInputCmd(String cmd, IoTDBConnection connection)
       throws StatementExecutionException {
     String specialCmd = cmd.toLowerCase().trim();
@@ -216,6 +223,16 @@ public class IoTDBInterpreter extends AbstractInterpreter {
       this.timeFormat = setTimeFormat(values[1]);
       return new InterpreterResult(Code.SUCCESS, "Time display type has set to " + timeDisplayType);
     }
+    else if (specialCmd.startsWith(SET_QUERY_TIMEOUT)) {
+      String[] values = cmd.split(EQUAL_SIGN);
+      if (values.length != 2) {
+        throw new StatementExecutionException(
+            String.format(
+                "Query timeout format error, please input like %s=10", SET_QUERY_TIMEOUT));
+      }
+      this.queryTimeout = Integer.parseInt(values[1].trim());
+      return new InterpreterResult(Code.SUCCESS, "Query timeout has set to " + queryTimeout + " seconds");
+    }
     return executeQuery(connection, cmd);
   }
 
@@ -223,6 +240,9 @@ public class IoTDBInterpreter extends AbstractInterpreter {
     StringBuilder stringBuilder = new StringBuilder();
     try (Statement statement = connection.createStatement()) {
       statement.setFetchSize(fetchSize);
+      if(this.queryTimeout > 0){
+        statement.setQueryTimeout(this.queryTimeout);
+      }
       boolean hasResultSet = statement.execute(cmd.trim());
       InterpreterResult interpreterResult;
       if (hasResultSet) {
diff --git a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/iotdb/IoTDBInterpreterTest.java b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/iotdb/IoTDBInterpreterTest.java
index 81f58a6..d5dbbd8 100644
--- a/zeppelin-interpreter/src/test/java/org/apache/zeppelin/iotdb/IoTDBInterpreterTest.java
+++ b/zeppelin-interpreter/src/test/java/org/apache/zeppelin/iotdb/IoTDBInterpreterTest.java
@@ -46,6 +46,7 @@ import static org.apache.zeppelin.iotdb.IoTDBInterpreter.IOTDB_PORT;
 import static org.apache.zeppelin.iotdb.IoTDBInterpreter.IOTDB_TIME_DISPLAY_TYPE;
 import static org.apache.zeppelin.iotdb.IoTDBInterpreter.IOTDB_USERNAME;
 import static org.apache.zeppelin.iotdb.IoTDBInterpreter.IOTDB_ZONE_ID;
+import static org.apache.zeppelin.iotdb.IoTDBInterpreter.SET_QUERY_TIMEOUT;
 import static org.apache.zeppelin.iotdb.IoTDBInterpreter.SET_TIMESTAMP_DISPLAY;
 
 public class IoTDBInterpreterTest {
@@ -134,6 +135,19 @@ public class IoTDBInterpreterTest {
   }
 
   @Test
+  public void testSetQueryTimeout() {
+    // default
+    Assert.assertEquals(-1, interpreter.getQueryTimeout());
+    InterpreterResult actual =
+        interpreter.internalInterpret(SET_QUERY_TIMEOUT + "=" + 2, null);
+    Assert.assertNotNull(actual);
+    Assert.assertEquals(Code.SUCCESS, actual.code());
+    Assert.assertEquals(
+        "Query timeout has set to 2 seconds", actual.message().get(0).getData());
+    Assert.assertEquals(2, interpreter.getQueryTimeout());
+  }
+
+  @Test
   public void testSetTimeDisplay() {
     String longGT =
         "Time\troot.test.wf01.wt01.status\n"