This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch ty-doc in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git
commit 93b8bce5e58615e737a014d83ae93e8b6abc1169 Author: JackieTien97 <[email protected]> AuthorDate: Thu Feb 6 11:08:03 2020 +0800 Hive-connector design document --- .../SystemDesign/7-Connector/2-Hive-TsFile.md | 82 ++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/docs/Documentation-CHN/SystemDesign/7-Connector/2-Hive-TsFile.md b/docs/Documentation-CHN/SystemDesign/7-Connector/2-Hive-TsFile.md index 821235b..6851706 100644 --- a/docs/Documentation-CHN/SystemDesign/7-Connector/2-Hive-TsFile.md +++ b/docs/Documentation-CHN/SystemDesign/7-Connector/2-Hive-TsFile.md @@ -25,9 +25,91 @@ TsFile的Hive连接器实现了对Hive读取外部Tsfile类型的文件格式的 使用户能够通过Hive操作Tsfile。 有了这个连接器,用户可以 + * 将单个Tsfile文件加载进Hive,不论文件是存储在本地文件系统或者是HDFS中 * 将某个特定目录下的所有文件加载进Hive,不论文件是存储在本地文件系统或者是HDFS中 * 使用HQL查询tsfile * 到现在为止, 写操作在hive-connector中还没有被支持. 所以, HQL中的insert操作是不被允许的 ### 设计原理 + +Hive连接器需要能够解析tsfile的文件格式,转化为Hive能够识别的按行返回的格式。也需要能够根据用户定义的Table的形式,格式化输出。所以,Hive连接器的功能实现主要分成四个部分 + +* 将整个tsfile文件分片 +* 从分片中读取数据,转化为Hive能够识别的数据类型 +* 解析用户自定义的Table +* 将数据反序列化为Hive的输出格式 + +### 具体实现类 + +上述的主要四个功能模块都有其对应的实现类,下面就分别介绍一下这四个实现类。 + +#### org.apache.iotdb.hive.TSFHiveInputFormat + +该类主要负责对输入的tsfile文件的格式化操作,它继承了`FileInputFormat<NullWritable, MapWritable>`类,一些通用的格式化操作在`FileInputFormat`中已经有实现,这个类覆写了它的`getSplits(JobConf, int)`方法,自定义了对于tsfile文件的分片方式;以及`getRecordReader(InputSpli, JobConf, Reporter)`方法,用于生成具体从一个分片中读取数据的 +`TSFHiveRecordReader`。 + +#### org.apache.iotdb.hive.TSFHiveRecordReader + +该类主要负责从一个分片中读取tsfile的数据。 + +它实现了`IReaderSet`接口,这个接口里是一些设置类内部属性的方法,主要是为了抽出`TSRecordReader`和`TSHiveRecordReader`中重复的代码部分。 + +``` +public interface IReaderSet { + + void setReader(TsFileSequenceReader reader); + + void setMeasurementIds(List<String> measurementIds); + + void setReadDeviceId(boolean isReadDeviceId); + + void setReadTime(boolean isReadTime); +} +``` + +下面先介绍一下这个类的一些重要字段 + +* private List<QueryDataSet> dataSetList = new ArrayList<>(); + + 这个分片所生成的所有的QueryDataSet + +* private List<String> deviceIdList = new ArrayList<>(); + + 设备名列表,这个顺序与dataSetList的顺序一致,即deviceIdList[i]是dataSetList[i]的设备名. + +* private int currentIndex = 0; + + 当前正在被处理的QueryDataSet的下标 + +这个类在构造函数里,调用了`TSFRecordReader`的`initialize(TSFInputSplit, Configuration, IReaderSet, List<QueryDataSet>, List<String>)`方法去初始化上面提到的一些类字段。它覆写了`RecordReader`的`next()`方法,用以返回从tsfile里读出的数据。 + +##### next(NullWritable, MapWritable) + +我们注意到它从tsfile读取出来数据之后,是以`MapWritable`的形式返回的,这里的`MapWritable`其实就是一个`Map`,只不过它的key与value都做了序列化与反序列化的特殊适配,它的读取流程如下 + +1. 首先判断`dataSetList`当前位置的`QueryDataSet`还有没有值,如果没有值,则将`currentIndex`递增1,直到找到第一个有值的`QueryDataSet` +2. 然后调用`QueryDataSet`的`next()`方法获得`RowRecord` +3. 最后调用 `TSFRecordReader`的`getCurrentValue()`方法,将`RowRecord`中的值set进`MapWritable`里 + + +#### org.apache.iotdb.hive.TsFileSerDe + +这个类继承了`AbstractSerDe`,也是我们实现Hive从自定义输入格式中读取数据所必须的。 + +它覆写了`AbstractSerDe`的`initialize()`方法,在这个方法里,从用户的建表sql里,解析出相应的设备名,传感器名以及传感器对应的类型。还要构建出`ObjectInspector`对象,这个对象主要负责数据类型的转化,由于Tsfile只支持原始数据类型,所以当出现其他数据类型时,需要抛出异常,具体的构建过程在`createObjectInspectorWorker()`方法中可以看到 + +这个类的最主要职责就是序列化和反序列化不同文件格式的数据,由于我们的hive连接器暂时只支持读取操作,并不支持insert操作,所以只有反序列化的过程,所以仅覆写了`deserialize(Writable)`方法,该方法里调用了`TsFileDeserializer`的`deserialize()`方法。 + + +#### org.apache.iotdb.hive.TsFileDeserializer + +这个类就是将数据反序列化为Hive的输出格式,仅有一个`deserialize()`方法。 + +##### public Object deserialize(List<String>, List<TypeInfo>, Writable, String) + +这个方法的`Writable`参数就是`TSFHiveRecordReader`的`next()`生成的`MapWritable`。 + +首先判断`Writable`参数是不是`MapWritable`类型,如果不是,则抛出异常。 + +接着依次从`MapWritable`中取出该设备的传感器的值,如果遇到类型不匹配则抛异常,最后返回生成的结果集。
