Download IoTDB

1. 安装


该部分主要介绍如何对IoTDB系统进行安装和启动。

1.1 下载

下载iotdb-v0.7.tar.gz(更新时间: 2018-6-5)或者iotdb-v0.7.zip(注:二者仅是压缩方式不同),该压缩包包含了IoTDB系统运行所需的所有必要组件。

1.2 解压

可以使用以下命令对iotdb进行解压

tar -zxf iotdb-v0.7.tar.gz

uzip iotdb-v0.7.zip

1.3 配置说明

所有的配置文件均存放在conf文件夹下

tsfile-format.properties

该文件存储了和tsfile项目有关的配置选项

# 每次将内存中的数据写入到磁盘时的大小,默认128MB
# Memory size threshold for flushing to disk or HDFS, default value is 128MB
group_size_in_byte=134217728

# 内存中每个列打一次包的大小,默认1MB
# The memory size for each series writer to pack page, default value is 1MB
page_size_in_byte=1048576

# 一个页中最多包含的数据点数量,默认 1024*1024
# The maximum number of data points in a page, defalut 1024*1024
max_number_of_points_in_page=1048576

# 数据类型设置
# Data type configuration

# 时间戳数据类型,可选INT32, INT64
# Data type for input timestamp, TsFile supports INT32 or INT64
time_series_data_type=INT64

# 针对字符串类型的数据,单个字符串最大长度
# Max length limitation of input string
max_string_length=128

# 浮点数精度
# Floating-point precision
float_precision=2

# 编码设置
# Encoder configuration

# 时间列编码方式,默认二阶差分(TS_2DIFF),还可以选择PLAIN, RLE(游程编码,run-length encoding)
time_series_encoder=TS_2DIFF

# 值列编码方式,默认PLAIN,对于int, long, float, double类型的数据,还可以选RLE(游程编码,run-length encoding)和TS_2DIFF(二阶差分)
# 对于int, long类型的数据, 还可以选RLE(游程编码,run-length encoding)和TS_2DIFF(二阶差分).
# 对于float, double类型的数据, 还可以选RLE(游程编码,run-length encoding),TS_2DIFF(二阶差分)和GORILLA.
# 对于text类型的数据, TsFile 只支持PLAIN.
value_encoder=PLAIN

# 压缩设置
# Compression configuration

# 数据压缩方法,可选UNCOMPRESSED,SNAPPY两种,默认UNCOMPRESSED,即不压缩
compressor=UNCOMPRESSED

iotdb-engine.properties

该文件主要存储了和IoTDB相关的配置选项

# JDBC服务配置
# JDBC Server configuration

# JDBC 服务监听端口
# port which JDBC server listens to
rpc_port=6667

# 写前日志配置
# Write ahead log configuration

# 是否开启写前日志
# is write ahead log enable
enable_wal=true

# 当文件中和内存中的日志总数量达到指定大小后,对所有日志进行压缩并去掉无用的记录日志
# 该值过大会导致短暂的写入暂停,过小会增加IO和CPU消耗
wal_cleanup_threshold=500000

# 写前日志达到一定数量之后,刷新到磁盘
# 有可能丢失至多flush_wal_threshold个操作
flush_wal_threshold=10000

# 写前日志定期刷新到磁盘的周期,单位:毫秒
# 有可能丢失至多flush_wal_period_in_ms毫秒的操作
flush_wal_period_in_ms=10

# 数据库特性的配置
# database features configuration

# 数据存储目录
data_dir=data

# overflow数据进行合并的时候最多可以起多少个线程来merge
# 值越大,对IO和CPU消耗越多
# 值越小,当overflow数据过多时,磁盘占用量越大,读取会变慢
merge_concurrent_threads=10

# 最大同时打开的文件夹数量
# 值变大,占用内存变多,IO随机读写变小,文件分块(即group)更加整齐
# 值越小,占用内存越少,IO随机读写变多,文件块大小不足group的概率变大
max_opened_folder=100

# 批量读取数据的时候,每一次读取数据的数量
# 某次会话中,用户可以在使用时自己设定,此时仅在该次会话中生效
fetch_size=10000

# Close和Merge操作有关的配置

# close操作触发周期,单位:秒
period_time_for_close_in_second=3600

# merge操作触发周期,单位:秒
period_time_for_merge_in_second=7200

# 选择是否启动后台统计功能
enable_stat_monitor=true

# 百分比值,这个值乘以IoTDB运行时分配到的最大堆内存值后得到一个阈值。
# 当IoTDB使用内存超过该阈值的时候,将触发把当前内存中的数据写入到磁盘上,并释放相应内存的操作。
# 默认为IoTDB运行时能使用最大堆内存的80%。如果该值配置超过1,那么该配置项将不生效。如果该值小于等于0,那么使用默认值。
mem_threshold_warning=0.8

# 百分比值,这个值乘以IoTDB运行时分配到的最大堆内存后得到一个阈值。
# 当IoTDB使用内存超过该阈值的时候,将触发把当前内存中的数据写入到磁盘上,并释放相应内存的操作。
# 同时,写入操作将被阻塞。默认为IoTDB运行时能使用最大堆内存的90%。如果该值配置超过1,那么该配置项将不生效。如果该值小于等于0,那么使用默认值。
mem_threshold_dangerous=0.9

# IoTDB系统每隔一段时间检查当前内存使用情况,如果超过了根据mem_threshold_warning或者mem_threshold_dangerous计算出来的阈值,将触发相应的操作。单位是为毫秒,默认值是1000毫秒。
mem_monitor_interval=1000

# 当内存中保存的TsFile文件元数据大小超过该阈值之后,会将元数据保存在TsFile文件尾部,然后关闭该文件,并释放元数据占用的内存空间。单位为byte,默认值为200M。
bufferwrite_meta_size_threshold=209715200

# 当磁盘上的一个TsFile文件大小超过该阈值时,会关闭该TsFile文件。并打开一个新的TsFile文件接受数据写入。单位为byte,默认值为2G。
bufferwrite_file_size_threshold=2147483648

# 当内存中保存的Overflow文件元数据大小超过该阈值之后,会将元数据保存在TsFile文件尾部,然后关闭该文件,并释放元数据占用的内存空间。单位为byte,默认值为200M。
overflow_meta_size_threshold=209715200

# 当磁盘上的一个Overflow文件大小超过该阈值时,会关闭该Overflow文件。并打开一个新的Overflow文件接受数据写入。单位为byte,默认值为2G。
overflow_file_size_threshold=2147483648

# 当IoTDB将内存中的数据写入磁盘时,最多启动多少个线程来执行该操作。如果该值小于等于0,那么采用机器所安装的CPU核的数量。默认值为0。
concurrent_flush_thread=0

iotdb-env.sh(如果在Windows下运行,可以配置iotdb-env.bat)

该文件存储了IoTDB启动环境参数的配置

# 是否以本地模式启动JMX服务
# 配置为yes表示仅允许本地访问JMX
# 配置为no表示允许远程访问
LOCAL_JMX=yes

# JMX服务端口
JMX_PORT="31999"

# IoTDB启动时分配的最大堆内存大小
MAX_HEAP_SIZE="2G"

# IoTDB启动时分配的最大堆内存大小
HEAP_NEWSIZE="2G"

1.4 运行

1.4.1 系统启动

在系统部署完毕后,可以通过下面命令对服务器端进行启动

bin/start-server.sh

1.4.2 启动客户端

在服务器启动完毕后,可以通过如下命令进行启动

bin/start-client.sh -h 127.0.0.1 -p 6667 -u root

please input your password:
 _____       _________  ______   ______
|_   _|     |  _   _  ||_   _ `.|_   _ \
  | |   .--.|_/ | | \_|  | | `. \ | |_) |
  | | / .'`\ \  | |      | |  | | |  __'.
 _| |_| \__. | _| |_    _| |_.' /_| |__) |
|_____|'.__.' |_____|  |______.'|_______/  version 0.7.0


IoTDB> login successfully
IoTDB>

1.4.3 关闭客户端

在客户端中输入quit可以直接对客户端进行退出

IoTDB> quit
quit normally

1.4.4 关闭IoTDB系统

通过如下命令可以关闭服务器端

bin/stop-server.sh

2.JDBC接口及使用说明


IoTDB的JDBC包可以在这里下载(iotdb-jdbc.jar)。

2.1 安装JDBC的jar包

首先下载iotdb-jdbc.jar,然后执行以下命令可以将JDBC包安装到本地Maven仓库:

mvn install:install-file -DgroupId=cn.edu.tsinghua -DartifactId=iotdb-jdbc -Dversion=0.7.0 -Dpackaging=jar -Dfile={FilePath}

注:其中{FilePath}为jar包所在的本地路径

2.2 在maven项目中加入jdbc依赖

在pom.xml文件中加入下面的依赖

<dependencies>
    <dependency>
      <groupId>cn.edu.tsinghua</groupId>
      <artifactId>iotdb-jdbc</artifactId>
      <version>0.7.0</version>
    </dependency>
</dependencies>

2.3 jdbc基本用法

2.3.1 查询某个设备下的某个传感器信息

假设存在设备wt01,它有一个传感器temperature,查询temperature的jdbc使用方法如下,其中对于查询得到的ResultSet,“Time”为保留字段,用于记录传感器采集到值的时间戳

public static void main(String[] args) throws SQLException {
    Connection connection = null;
    Statement statement = null;
    try {
        Class.forName("cn.edu.tsinghua.iotdb.jdbc.TsfileDriver");
        connection = DriverManager.getConnection("jdbc:tsfile://localhost:6667/", "root", "root");
        statement = connection.createStatement();
        boolean hasResultSet = statement.execute("select temperature from root.sgcc.wf03.wt01");
        if (hasResultSet) {
            ResultSet res = statement.getResultSet();
            while (res.next()) {
                System.out.println(res.getString("Time") + " | " + res.getString("root.sgcc.wf03.wt01.temperature"));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(statement != null){
            statement.close();
        }
        if(connection != null){
            connection.close();
        }
    }
}

2.3.2 执行非Query操作

假设想要更新设备wt01中传感器temperature的值,把时间戳在[1476434398000, 1476434399020]内的值全部设置为0,可以通过如下SQL语句实现:

public static void main(String[] args) throws SQLException {
    Connection connection = null;
    Statement statement = null;
    try {
        Class.forName("cn.edu.tsinghua.iotdb.jdbc.TsfileDriver");
        connection = DriverManager.getConnection("jdbc:tsfile://localhost:6667/", "root", "root");
        statement = connection.createStatement();
        statement.execute("update root.sgcc.wf03.wt01 set temperature = 0 where time >= 1500865386242 and time <= 1500865395916");
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(statement != null){
            statement.close();
        }
        if(connection != null){
            connection.close();
        }
    }
}

2.3.3 获取数据库metadata

如果想看数据中的各个字段的详细信息,类似JDBC标准的"show metadata",可以通过如下操作

public static void main(String[] args) throws SQLException {
    Connection connection = null;
    try {
        Class.forName("cn.edu.tsinghua.iotdb.jdbc.TsfileDriver");
        connection = DriverManager.getConnection("jdbc:tsfile://127.0.0.1:6667/", "root", "root");
        DatabaseMetaData databaseMetaData = connection.getMetaData();
        System.out.println("show metadata");  // Note that === Timeseries Tree ==== not JSON
        String metadata = databaseMetaData.toString();
        System.out.println(metadata);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(connection != null){
            connection.close();
        }
    }
}

注:metadata信息虽然是以字符串的形式返回的,但是本身的格式是JSON格式,可以把它转化成为一个JSON对象

2.3.4 获取表结构信息

如果想要获取所有的列名,或者单个列的数据类型,可以通过以下方式得到。

public static void main(String[] args) throws SQLException {
    Connection connection = null;
    try {
        Class.forName("cn.edu.tsinghua.iotdb.jdbc.TsfileDriver");
        connection = DriverManager.getConnection("jdbc:tsfile://127.0.0.1:6667/", "root", "root");  // TODO
        DatabaseMetaData databaseMetaData = connection.getMetaData();

        // get all columns
        ResultSet resultSet = databaseMetaData.getColumns(null, null, "root.*", null);
        while(resultSet.next()){
            System.out.println(String.format("column %s", resultSet.getString(0)));
        }

        // get data type for one column
        resultSet = databaseMetaData.getColumns(null, null, "root.a.b.c", null);
        while(resultSet.next()){
            System.out.println(String.format("column %s, type %s", resultSet.getString(0), resultSet.getString(1)));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(connection != null){
            connection.close();
        }
    }
}

2.4. jdbc支持的API

2.4.1 Connection

Connection {
    // 创建当前连接的statement用以执行SQL语句
    public Statement createStatement()

    // 获取数据库的元数据信息
    public DatabaseMetaData getMetaData()

  // 关闭jdbc客户端与数据库之间的连接
  public void close()
}

2.4.2 Statement

Statement {
    // 将要批量执行的SQL语句暂存
    public void addBatch(String sql)

    // 清除保存的要批量执行的语句
    public void clearBatch()

    // 结束本次操作
    public void close()

    // 执行输入的SQL语句,如果是查询操作,返回true,否则返回false
    public boolean execute(String sql)

    // 批量执行SQL语句,将每一条语句执行的结果保存在数组中
    public int[] executeBatch()

    // 执行查询操作
    public ResultSet executeQuery(String sql)

    // 执行更新操作
    public int executeUpdate(String sql)

    // 获取当前客户端和数据库的连接
    public Connection getConnection()

    // 获取每次客户端向数据库请求数据的最大条数
    public int getFetchSize()

    // 获取结果集中保存的最大结果数量
    public int getMaxRows()

    // 获得当前SQL语句执行后的结果集
    public ResultSet getResultSet()

    // 判断当前操作是否结束
    public boolean isClosed()

    // 设置每次客户端向数据库请求数据的最大条数
    public void setFetchSize(int fetchSize)

    // 设置结果集中保存的最大结果数量
    public void setMaxRows(int num)

    // 设置查询超时时间
    public void setQueryTimeout(int seconds)
}

2.4.3 ResultSetMetaData

ResultSetMetaData {
    // 获取列数
    public int getColumnCount()

    // 根据列数得到列名,并将列名转化为要打印的名字
    public String getColumnLabel(int column)

    // 根据列数返回列名
    public String getColumnName(int column)
}

2.4.4 ResultSet

ResultSet {
    // 结束当前操作
    public void close()

    // 根据列名称columnName返回它在第几列
    public int findColumn(String columnName)

    // 将字段第columnIndex列的数据转化为BigDecimal并返回
    public BigDecimal getBigDecimal(int columnIndex)

    // 将字段名称为columnName的数据转化为BigDecimal并返回
    public BigDecimal getBigDecimal(String columnName)

    // 将字段第columnIndex列的数据转化为BigDecimal,设精度为scale并返回
    public BigDecimal getBigDecimal(int columnIndex, int scale)

    // 将字段名称为columnName的数据转化为BigDecimal,设精度为scale并返回
    public BigDecimal getBigDecimal(String columnName, int scale)

    // 将字段第columnIndex列的数据转化为boolean并返回
    public boolean getBoolean(int columnIndex)

    // 将字段名称为columnName的数据转化为boolean并返回
    public boolean getBoolean(String columnName)

    // 将字段第columnIndex列的数据转化为Date并返回
    public Date getDate(int columnIndex)

    // 将字段名称为columnName的数据转化为Date并返回
    public Date getDate(String columnName)

    // 将字段第columnIndex列的数据转化为double并返回
    public double getDouble(int columnIndex)

    // 将字段名称为columnName的数据转化为double并返回
    public double getDouble(String columnName)

    // 将字段第columnIndex列的数据转化为float并返回
    public float getFloat(int columnIndex)

    // 将字段名称为columnName的数据转化为float并返回
    public float getFloat(String columnName)

    // 将字段第columnIndex列的数据转化为int并返回
    public int getInt(int columnIndex)

    // 将字段名称为columnName的数据转化为int并返回
    public int getInt(String columnName)

    // 将字段第columnIndex列的数据转化为long并返回
    public long getLong(int columnIndex)

    // 将字段名称为columnName的数据转化为long并返回
    public long getLong(String columnName)

    // 获取结果集的metadata信息
    public ResultSetMetaData getMetaData()

    // 将字段第columnIndex列的数据转化为Object并返回
    public Object getObject(int columnIndex)

    // 将字段名称为columnName的数据转化为Object并返回
    public Object getObject(String columnName)

    // 将字段第columnIndex列的数据转化为short并返回
    public short getShort(int columnIndex)

    // 将字段名称为columnName的数据转化为short并返回
    public short getShort(String columnName)

    // 获得当前的Statement
    public Statement getStatement()

    // 将字段第columnIndex列的数据转化为String并返回
    public String getString(int columnIndex)

    // 将字段名称为columnName的数据转化为String并返回
    public String getString(String columnName)

    // 将字段第columnIndex列的数据转化为Time并返回
    public Time getTime(int columnIndex)

    // 将字段名称为columnName的数据转化为Time并返回
    public Time getTime(String columnName)

    // 将字段第columnIndex列的数据转化为Timestamp并返回
    public Timestamp getTimestamp(int columnIndex)

    // 将字段名称为columnName的数据转化为Timestamp并返回
    public Timestamp getTimestamp(String columnName)

    // 判断当前SQL操作是否结束
    public boolean isClosed()

    // 指向下一行数据并返回true
    // 如果所有的数据已经遍历完或者超过了该ResultSet所包含最大行数(由maxRows控制),返回false
    public boolean next()
}

2.4.5 DatabaseMetaData

DatabaseMetaData {
    // 获取表结构信息(注:在iotdb-jdbc中该函数与标准JDBC所定义的用法不同,现阶段只能支持通过该函数获取所有的列名,或者单列的数据类型,参见2.3.4小节)
    // 当columnPattern为"root.*"的时候,可以获得所有的列名
    // 当columnPattern为某一列(如"root.a.b.c")的时候,可以获得该列的数据类型
    public ResultSet getColumns(String catalog, String schemaPattern, String columnPattern, String deltaObjectPattern)

    // 获得当前客户端与数据库的连接
    public Connection getConnection()

    // 获取数据库metadata信息,包含所有列的名称以及它的数据类型,编码方式等
    public String toString()
}

2.4.6 PrepareStatement

PrepareStatement {
    // 将要批量执行的SQL语句暂存
    public void addBatch(String sql)

    // 清除保存的要批量执行的语句
    public void clearBatch()

    // 结束本次操作
    public void close()

    // 清除语句中设置的参数
    public void clearParameters()

    // 执行已经预先设置的PrepareStatement中的SQL语句,如果有结果集,返回true,否则返回false
    public boolean execute()

    // 执行输入的SQL语句,如果有结果集,返回true,否则返回false
    public boolean execute(String sql)

    // 批量执行SQL语句
    //返回值:每一条语句执行的结果(数组下标从0开始),如果出错返回值为-1,如果正常执行返回值为1
    //备注:当批执行的某条sql语句失败时,不会报错,剩下的语句任会继续执行
    public int[] executeBatch()

    // 执行已经预先设置的PrepareStatement中的查询语句,返回值为查询语句的结果,详细用法见7.2.3.7ResultSet类
    public ResultSet executeQuery()

    // 执行查询操作,返回值为查询语句的结果,详细用法见7.2.3.7ResultSet类
    public ResultSet executeQuery(String sql)

    // 执行已经预先设置的PrepareStatement中的更新语句,返回值是0表示成功,其他情况会抛出异常
    public int executeUpdate()

    // 执行更新操作,返回值是0表示成功,其他情况会抛出异常
    public int executeUpdate(String sql)

    // 获取当前客户端和数据库的连接
    public Connection getConnection()

    // 获取每次客户端向数据库请求数据的最大条数
    public int getFetchSize()

    // 获取结果集中保存的最大结果数量
    public int getMaxRows()

    // 获得当前SQL语句执行后的结果集
    public ResultSet getResultSet()

    // 判断当前操作是否结束
    public boolean isClosed()

    // 将位于parameterIndex位置的问号替换为布尔类型的变量x
    public void setBoolean(int parameterIndex, boolean x)

    // 将位于parameterIndex位置的问号替换为高精度浮点类型的变量x
    public void setDouble(int parameterIndex, double x)

    // 设置每次客户端向数据库请求数据的最大条数
    //fetchSize小于0抛异常,等于0用默认值10000,大于0就用设置的值
    public void setFetchSize(int fetchSize)

    // 将位于parameterIndex位置的问号替换为浮点类型的变量x
    public void setFloat(int parameterIndex, float x)

    // 将位于parameterIndex位置的问号替换为整数类型的变量x
    public void setInt(int parameterIndex, int x)

    // 将位于parameterIndex位置的问号替换为长整数类型的变量x
    public void setLong(int parameterIndex, long x)

    // 设置结果集中保存的最大结果数量
    //参数num小于0抛异常,等于0表示INT的最大值,其他情况没有限制
    public void setMaxRows(int num)

    // 将位于parameterIndex位置的问号替换为对象类型的变量x
    public void setObject(int parameterIndex, Object x)

    // 将位于parameterIndex位置的问号替换为字符串类型的变量x
    public void setString(int parameterIndex, String x)

    // 将位于parameterIndex位置的问号替换为时间戳类型的变量x
    public void setTimestamp(int parameterIndex, Timestamp x)
}