serde
serde是序列化(serializer)和反序列化(deserializer)的简称
Hive uses SerDe (and FileFormat) to read and write table rows.
HDFS files --> InputFileFormat --> <key, value> --> Deserializer --> Row object
Row object --> Serializer --> <key, value> --> OutputFileFormat --> HDFS files
看到上面hive存储/读取的流程可以看出来,存储数据前要先序列化,读取数据最后一步要反序列化。
基础的原理懂了之后,就可以结合实际讲解问题了。
这里有表a存储了一些企业信息数据,我想要查询a表的数据插入b表中,大致实现如下:
insert overwrite table b
select * from a --b,a两个表字段顺序一致
但是a表中的部分字段中存储的中文数据中包含换行(红色框里的内容是一个字段中的内容):
这个时候,如果b表用textfile方式存储,这一条数据会作为两条数据存储,因为textfile在存储数据的时候,会逐个字符判断是不是分隔符和行结束符。
这时候就可以祭出rcfile了:
RCFile的特性
存储方式:数据按行分块,每块案列存储。【先水平划分,再垂直划分】
压缩快 快速列存取。
读记录尽量涉及到的block最少。
读取需要的列中需要读取每个row group的头部定义。
读取全量数据的操作性能可能比sequencefile没有明显的优势:
首先,RCFile保证同一行的数据位于同一节点,因此元组重偶构的开销很低;
其次,像列存储一样,RCFile能够利用维度的数据压缩,并且能跳过不必要的列读取;
RCFile的一个行组包括三个部分:
第一部分是行组头部的【同步标识】,主要用于分隔hdfs块中的两个连续行组
第二部分是行组的【元数据头部】,用于存储组单元的信息,包括行组中的记录数、每个列的字节数、列中每个域的字节数
第三部分是【表格数据段】,即实际的列存储数据。在该部分中,同一列的所有域顺序存储。
数据追加:RCFile不支持任意方式的数据写操作,仅提供一种追加接口,这是因为底层的HDFS当前仅仅支持数据追加写文件尾部。
行组大小:行组变大有助于提高数据压缩的效率,但是可能会损害数据的读取性能,因为这样增加了Lazy解压性能的消耗。而且行组变大会占用更多的内存,这会影响并发执行的其他MR作业。
从上面可以看出,rcfile格式存储的数据,在解析的时候,会先读取行组的元数据信息,也就是说,原来在一列的数据还是会在一列里。
stored as
TextFile,SequenceFile,RCFile是hive常见的三种存储格式。其中,TextFile是hive默认的存储格式,SequenceFile和RCFile是二进制存储格式。
stored as 包含三部分:serde ,inputformat,outputformat
在不指定存储格式的时候,hive会自动选用默认格式。
我们一般喜欢查看hive已有的建表语句的时候选用命令:show create table xx
但是存储一般会只展示 inputformat 和outputformat,如果我们只复制出来这两行,用rcfile格式的话,插入数据就会报错:
Caused by: java.lang.UnsupportedOperationException: Currently the writer can only accept BytesRefArrayWritable
at org.apache.hadoop.hive.ql.io.RCFile$Writer.append(RCFile.java:1110)
at org.apache.hadoop.hive.ql.io.RCFileOutputFormat$2.write(RCFileOutputFormat.java:141)
at org.apache.hadoop.hive.ql.exec.FileSinkOperator.process(FileSinkOperator.java:753)
at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:837)
at org.apache.hadoop.hive.ql.exec.LimitOperator.process(LimitOperator.java:54)
at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:837)
at org.apache.hadoop.hive.ql.exec.SelectOperator.process(SelectOperator.java:88)
at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:235)
... 7 more
这是因为SequenceFile和RCFile是二进制存储格式,一般默认serde方式是org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe,而二进制存储的方式需要采用org.apache.hadoop.hive.serde2.columnar.LazyBinaryColumnarSerDe