1. 程式人生 > 其它 >Hive使用Snappy壓縮,Parquet格式儲存檔案

Hive使用Snappy壓縮,Parquet格式儲存檔案

技術標籤:Hive

一、資料內容

95002,劉晨,女,19,IS
95017,王風娟,女,18,IS
95018,王一,女,19,IS
95013,馮偉,男,21,CS
95014,王小麗,女,19,CS
95019,邢小麗,女,19,IS
95020,趙錢,男,21,IS

二、檢視 HDFS 是否支援 Snappy 格式

shell 命令列執行:

hadoop checknative

返回:

21/01/26 20:32:52 WARN bzip2.Bzip2Factory: Failed to load/initialize native-bzip2 library system-native, will use pure-Java version
21/01/26 20:32:52 INFO zlib.ZlibFactory: Successfully loaded &
initialized native-zlib library Native library checking: hadoop: true /opt/module/hadoop-2.7.2/lib/native/libhadoop.so zlib: true /lib64/libz.so.1 snappy: true /opt/module/hadoop-2.7.2/lib/native/libsnappy.so.1 lz4: true revision:99 bzip2: false

若是 snappy 後面是 true ,則支援 snappy 壓縮。

三、方式一:使用 load 方式載入

1、建表

create table student
	(id Int,
	name String,
	sex String,
	age Int,
	country String) 
partitioned by(date_str String)
stored as parquet
tblproperties("parquet.compress"="SNAPPY");

2、查看錶結構,是否與第一步中建的一樣

desc formatted student;

3、直接載入資料

load data local inpath '/root/student.snappy.parquet'
into table student partition(date_str='2021');

四、方式二:將檔案先 put 到指定目錄,最後 load

–hive使用snappy壓縮,parquet格式儲存檔案(先將檔案存放到HDFS的’/stu’目錄下,然後再使用下面的建表語句,可以直接掃描到)
–但是分割槽表,掃描不到(錯誤意識)

1、先將檔案 putHDFS 指定的目錄下(若是分割槽表,要 put 到指定分割槽)

hadoop fs -out  /root/student.snappy.parquet  /stu/date_str=2020

2、建表

create external table student_snappy
	(id Int,
	name String,
	sex String,
	age Int,
	country String)
partitioned by(date_str String)
stored as parquet
location '/stu'
tblproperties("parquet.compress"="SNAPPY");

3、查看錶結構,是否與第二步中建的一樣

desc formatted student;

4、直接載入資料

load data inpath '/stu/date_str=2020' into table student_snappy partition(date_str='2020');

五、注意事項:

1、Hive 表的欄位型別與 Parquet 檔案中欄位的型別必須一致。否則會導致空表(但不會報錯,讓你不會察覺)
2、使用第二種方法的時候。若不是分割槽表,不用 load 載入也可以查到資料。但若是分割槽表,則必須使用 load 載入,否則會導致空表(但不會報錯,讓你不會察覺)
3、使用第二種方法建分割槽表的時候。建表語句 location 不帶分割槽目錄。

六、附:使用 Sparktxt 檔案轉為 Snappy 壓縮(Spark預設壓縮格式),Parquet 格式的檔案

import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, SaveMode, SparkSession}

/**
  * 將txt轉為parquet
  */
object Txt2Parquet {
  def main(args: Array[String]): Unit = {

    //待轉換的檔案路徑
    val path = "E:\\data\\student.txt"

    val spark: SparkSession = SparkSession.builder()
      .appName("Txt2Parquet")
      .master("local[*]").getOrCreate()

    //RDD ===> DataFrame
    val sc: SparkContext = spark.sparkContext
    //設定日誌級別
    sc.setLogLevel("WARN")

    //讀取txt檔案
    val stuRDD: RDD[String] = sc.textFile(path)

    //RDD ===> DataFrame 需要隱式轉換
    import spark.implicits._
    val stuDF: DataFrame = stuRDD.map(_.split(",", -1))
      .map(line => Student(line(0).toInt, line(1), line(2), line(3).toInt, line(4))).toDF()
    
    //寫為Snappy壓縮的Parquet檔案。設定檔案數為1
    stuDF.repartition(1).write.mode(SaveMode.Overwrite).parquet("E:\\data\\student")

    //設定壓縮格式為gzip
//    stuDF.repartition(1).write.mode(SaveMode.Overwrite)
//      .option("compression","gzip").parquet("E:\\data\\student_gzip")

    //關閉資源
    spark.stop()

  }
  case class Student(id: Int, name: String, sex: String, age: Int, country: String)
}