最近在 Google 上看到一篇在 Hive 中利用正则表达式来自定义反序列化处理文本文件。百度后发现这块知识目前还没有人系统的总结一下。
所以我就不才把之前记录的资料跟大家分享一下:
SerDe 是Serializer 和 Deserializer 的简称。它是 Hive用来处理记录并且将它们映射到 Hive 表中的字段数据类型。为了更好的阐述使用 SerDe 的场景,我们需要了解一下 Hive 是如何读数据的(类似于 HDFS 中数据的读写操作):
1. 从 HDFS 读取数据
2. 通过 InputFormat 来处理数据,根据定义的数据类型来将文件分割成键值对记录。在 Hive 中,我们可以通过 Create Table。。。Stored As 来指定使用哪种 InputFormat 来读取数据。
3. SerDe 中 JAVA 的 Deserializer 会被调用来格式化数据并且映射到表中对应的字段和数据类型。
对于数据读取,我们希望使用 JSON SerDe 来从 HDFS 中读取文本文件格式数据,并且根据正确的 schema 将 JSON每一行的属性和值与 Hive 表中的行进行转换。
如果写入数据:
1. 写入的数据(例如 Insert 语句)会通过 SerDe 定义的 Serlializer 类进行转换成 OutputFormat 类能够读取的格式。
2. 数据会被OutputFormat 继承类进行处理,创建 RecordWrite 对象。类似于 InputFormat 的实现。OutputFormat 的实现方法跟表写入数据的方式相同。
3. 将数据写入到表中(数据将保存在 HDFS)
在实际写入数据的时候,我们可以使用 JSON SerDe来 Hive 表中一个 行列转数据转换成 JSON 文本,保存到 HDFS 中。
Hive 近期发布的 org.apache.hadoop.hive.serde2 库,之前的的 org.apache.hadoop.hive.serde2 库已经摒弃不建议使用了。接下来我们将详细介绍一下 Hive 中常用的 SerDe :
SerDe 类型
|
具体应用
|
LazySimpleSerDe: 内置SerDe(org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe) ,用来处理文本文件格式:TEXTFILE
|
jdbc:hive2://> CREATE TABLE test_serde_lz
. . . . . . .> STORED AS TEXTFILE AS
. . . . . . .> SELECT name from employee;
No rows affected (32.665 seconds)
|
ColumnarSerDe: 用来处理 RCFile 的内置 SerDe
|
jdbc:hive2://> CREATE TABLE test_serde_cs
. . . . . . .> ROW FORMAT SERDE
. . . . . . .> 'org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe'
. . . . . . .> STORED ASRCFile AS
. . . . . . .> SELECT name from employee
No rows affected (27.187 seconds)
|
RegexSerDe: 用来处理文本文件的内置 JAVA 正则表达式 SerDe
|
--Parse , seperate fields
jdbc:hive2://> CREATE TABLE test_serde_rex(
. . . . . . .> name string,
. . . . . . .> sex string,
. . . . . . .> age string
. . . . . . .> )
. . . . . . .> ROW FORMAT SERDE
. . . . . . .> 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
. . . . . . .> WITH SERDEPROPERTIES(
. . . . . . .> 'input.regex' = '([^,]*),([^,]*),([^,]*)',
. . . . . . .> 'output.format.string' = '%1$s %2$s %3$s'
. . . . . . .> )
. . . . . . .> STORED AS TEXTFILE;
No rows affected (0.266 seconds)
|
HBaseSerDe: 内置的 SerDe,可以让 Hive 跟 HBase 进行集成。我们可以利用 HBaseSerDe 来将 Hive 表存储到 HBase 中。
注意:前提是 HBase 已经安装
|
jdbc:hive2://> CREATE TABLE test_serde_hb(
. . . . . . .> id string,
. . . . . . .> name string,
. . . . . . .> sex string,
. . . . . . .> age string
. . . . . . .> )
. . . . . . .> ROW FORMAT SERDE
. . . . . . .> 'org.apache.hadoop.hive.hbase.HBaseSerDe'
. . . . . . .> STORED BY
. . . . . . .> 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
. . . . . . .> WITH SERDEPROPERTIES (
. . . . . . .> "hbase.columns.mapping"=
. . . . . . .> ":key,info:name,info:sex,info:age"
. . . . . . .> )
. . . . . . .> TBLPROPERTIES("hbase.table.name" = "test_serde");
No rows affected (0.387 seconds)
|
AvroSerDe: 用来在 Hive 表中读写 Avro 数据格式的内置 SerDe(参考:)
Avro 是一个 RPC 和序列化框架,从 Hive 0.14.0 版本才本地支持 Avro :CREATE TABLE ... STORED AS AVRO
|
jdbc:hive2://> CREATE TABLE test_serde_avro(
. . . . . . .> name string,
. . . . . . .> sex string,
. . . . . . .> age string
. . . . . . .> )
. . . . . . .> ROW FORMAT SERDE
. . . . . . .> 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
. . . . . . .> STORED AS INPUTFORMAT
. . . . . . .> 'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
. . . . . . .> OUTPUTFORMAT
. . . . . . .> 'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
. . . . . . .>;
No rows affected (0.31 seconds)
需要注意的是,上述方法是 Hive 0.14.0 版本以前的定义方法,如左边所示,我们可以轻松的使用 Stored as Avro 来指定存储为 Avro 格式。
详细内容请参考:
|
ParquetHiveSerDe: 用来在 Hive 中读写 Parquet 数据格式的内置 SerDe。从 Hive 0.13.0 版本开始本地支持。
|
jdbc:hive2://> CREATE TABLE test_serde_parquet
. . . . . . .> STORED AS PARQUET AS
. . . . . . .> SELECT name from employee;
No rows affected (34.079 seconds)
|
OpenCSVSerDe: 用来读写 CSV 数据的 SerDe. 从 Hive 0.14.0 版本才发布的。
我们可以通过从 Github 中下载源码进行安装( )
|
jdbc:hive2://> CREATE TABLE test_serde_csv(
. . . . . . .> name string,
. . . . . . .> sex string,
. . . . . . .> age string
. . . . . . .>)
. . . . . . .> ROW FORMAT SERDE
. . . . . . .> 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
. . . . . . .> STORED AS TEXTFILE;
|
JSONSerDe: 这是一个第三方的 SerDe,用来利用 Hive 读取 JSON 数据记录。
你可以通知下载源码进行安装()
|
jdbc:hive2://> CREATE TABLE test_serde_js(
. . . . . . .> name string,
. . . . . . .> sex string,
. . . . . . .> age string
. . . . . . .> )
. . . . . . .> ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
. . . . . . .> STORED AS TEXTFILE;
No rows affected (0.245 seconds)
|
最后,为了应对目前存在的各式各样的数据格式以及数据存储系统。Hive 允许用户可以自定义 SerDe 来处理自己的文件格式。更多关于 自定义SerDe 请参考:
.
当然,为了呼应本次主题,特地跑到 Jira 上搜了一些各个 SerDe 的使用情况,随着大家对这些SerDe的深入研究,需求也越来越多,功能也逐渐被完善着:
LazySimpleSerDe :%20~%20%22LazySimpleSerDe%22
ColumnarSerDe : %20~%20%22ColumnarSerDe%22
RegexSerDe :%20~%20%22RegexSerDe%22
HBaseSerDe :%20~%20%22HBaseSerDe%22
AvroSerDe : %20~%20%22AvroSerDe%22
ParquetHiveSerDe:%20~%20%22ParquetHiveSerde%22
OpenCSVSerDe :%20~%20%22OpenCSVSerDe%22
JSONSerDe : %20~%20%22JSONSerDe%22