大數據開發實戰:離線大數據處理的主要技術--Hive,概念,SQL,Hive數據庫


  1、Hive出現背景

      Hive是Facebook開發並貢獻給Hadoop開源社區的。它是建立在Hadoop體系架構上的一層SQL抽象,使得數據相關人員使用他們最為熟悉的SQL語言就可以進行海量數據的處理、分析和統計工作,

    而不是必須掌握Java等編程語言和具備開發MapReduce程序的能力。Hive SQL實際上先被SQL解析器進行解析然后被Hive框架解析成一個MapReduce可執行計划,並按照該計划生成MapReduce任務后交給Hadoop集群處理。

      由於Hive SQL是翻譯為MapReduce任務后在Hadoop集群執行的,而Hadoop是一個批處理系統,所以Hive SQL是高延遲的,不但翻譯成的MapReduce任務執行延遲高,任務提交和處理過程也會消耗時間,因此即使Hive處理

    的數據集非常小(比如即MB,幾十MB),在執行時也會出現延遲現象。這樣Hive的性能就不能很好地和傳統的Oracle數據庫、MySQL數據庫進行比較。Hive不能提供數據排序和查詢緩存功能,也不提供在線事務處理、更不提供

    實時的查詢和記錄級的更新,但它能很好的處理不變的大規模數據集,當然這是 和其根植於Hadoop近似線性的可擴展性分不開的。

 

  2、Hive基本架構

      作為基於Hadoop的主要數據倉庫解決方案,Hive SQL是主要的交互接口,實際的數據保存在HDFS文件中,真正的計算和執行則由MapReduce完成。而它們之間的橋梁是Hive引擎。下面是架構圖:

    

    Hive組件包括UI組件、Driver組件(Complier,Optimizer和Executor)、Metastore組件、CLI(Command Line Interface, 命令行接口)、JDBC/ODBC、Thrift Server和Hive Web Interface(HWI)等。

    Driver組件:核心組件,整個Hive的核心,該組件包括Complier(編譯)、Optimizer(優化器)和Executor(執行器),它們的作用是對Hive SQL語句進行解析、編譯優化,生成執行計划,然后調用底層的MapReduce計算框架。

    Metastore組件:元數據服務組件,這個組件存儲Hive的元數據。Hive的元數據存儲在關系數據庫里,Hive支持的關系數據庫有Derby和MySQL。默認情況下,Hive元數據保存在內嵌的Derby數據庫中,只能允許一個會話鏈接,

            只適合簡單的測試。實際生產中不適用,為了支持多用戶會話,需要一個獨立的元數據庫(如MySQL),Hive內部對MySQL提供了很好的支持。

    CLI:命令行接口。

    Thrift Server:提供JDBC和ODBC接入的能力,用來進行可擴展且跨語言 的服務開發。Hive集成了該服務,能讓不同的編程 語言調用Hive的接口。

    Hive Web  Interface(HWI):Hive客戶端提供了一個通過網頁方式訪問Hive所提供的服務,這個接口對應Hive的HWI組件。

    Hive通過CLI、JDBC/ODBC,或者HWI接收相關的Hive SQL查詢,並通過Driver組件進行編譯、分析優化,最后變成可執行的MapReduce。Hive主要組件執行過程如下圖:

    

 

  3、Hive SQL

      Hive SQL是Hive用戶使用Hive的主要工具。Hive SQL是類似於ANSI SQL標准的SQL語言,但兩者又不完全相同。Hive SQL和MySQL的SQL方言最為接近,但兩者之前也存在顯著差異,比如Hive不支持行級數據插入、

    更新和刪除,也不支持事務等。

   3.1、Hive關鍵概念

    3.1.1、Hive數據庫

      Hive中的數據庫從本質上來說僅僅是一個目錄或命名空間,但是對於具有很多用戶和組的集群來說,這個概念非常有用。首先,這樣可以避免表命名沖突;其次,它等同於數據型數據庫在的數據庫概念呢,是一組表或表

    的邏輯組,非常容易理解。

    3.1.2、Hive表

      Hive中的表(Table)和關系數據庫中的table在概念上是類似的,每個table在Hive在都有一個對應的目錄存儲數據,如果么有指定表的數據庫,那么HIve會通過{HIVE_HOME}/conf/hive-site.xml配置文件中的hive.metastore.

    warehouse.dir屬性來使用默認值(一般是 /user/hive/warehouse, 也可以根據實際的情況來修改這個配置),所有的table數據(不包括外部表)都保存在這個目錄。

      Hive分為兩類,即內部表和外部表。所謂內部表(managed table)即Hive管理的表,Hive內部表的管理既包含邏輯以及語法上的,也包含實際物理意義上的,即創建Hive內部表時,數據將真實存在於表所在的目錄內,刪除

    內部表時,物理數據和文件也一並刪除。外部表(external table )則不然,其管理僅僅是在邏輯和語法意義上的,即新建表僅僅是指向一個外部目錄而已。同樣,刪除時也不物理刪除外部目錄,而僅僅是將引用和定義刪除。

      考慮下面的語句:

      CREATE TABLE my_managed_table(col1 STRING);

      LOAD DATA INPATH '/user/root/data.txt'  INTO table  my_managed_table

      上述語句會將hdfs:// user/root/data.txt 移動到Hive的對應目錄hdfs://user/hive/warehouse/my_managed_table,但是載入數據的速度非常快,因為Hive只是把數據移動到對應的目錄,不會對數據是否符合定義的Schema做校驗,

    這個工作通常在讀取時候進行(即為Schema On Read)。

      同時,my_managed_table使用DROP語句刪除后,其數據和表的元數據被刪除,不再存在,這就是 Hive managed的意思:

      DROP TABLE my_managed_table;

      外部表則不一樣,數據的創建和刪除完全由自己控制,Hive不管理這些數據,數據的位置在創建時指定:

      CREATE EXTERNAL TABLE external_table(dummy STRING)

        LOCATION  '/user/root/external_table';

      LOAD DATA INPATH '/user/root/data.txt' INTO TABLE exteranl_table;

      指定EXTERNAL關鍵字后,Hive不會把數據移動warehouse目錄中。事實上,Hive甚至不會校驗外部表的目錄是否存在。這使得我們可以在創建表之后再創建數據,當刪除外部表時,Hive只刪除元數據,而不會刪除外部實際

    物理文件。

      選擇內部表還是外部表?在大多數情況下,這兩者的區別不是很明顯。如果數據的所有處理都在Hive中進行,那么更傾向於選擇內部表。但是如果Hive和其它工具針對相同的數據集做處理,那么外部表更合適。一種常見的模式

    是使用外部表訪問存儲的HDFS(通常由其它工具創建)中 的初始數據,然后使用Hive轉換數據並將其結果放在內部表中,相反,外部表也可以用於將Hive的處理結果導出供其它應用使用。使用外部表另一種場景是針對一個數據集,

    關聯多個Schema。

 

    3.1.3、分區和桶

      Hive 將表划分為分區(partition),partition根據分區字段進行。分區可以讓數據的部分查詢變得更快。表或者分區可以進一步被划分為桶(bucket)。桶通常在原始數據中加入一些額外的結構,這些結構可以用於高效查詢。

    例如,基於用戶ID的分桶可以使用基於用戶的查詢非常快。

    分區:

      假設日志數據中,每條記錄都帶有時間戳。如果根據時間來分區,那么同一天的數據將被划分到同一個分區中。針對某一天或某幾天數據的查詢將會變得很高效,因為只需要掃描對應分區的文件。分區並不會導致跨度的的查詢

    變得低效。

      分區可以通過多個維度來進行。例如,通過日期划分后,還可以根據國家進一步划分。

      分區在創建表的時候使用PARTITIONED BY從句定義,該從句接收一個字段列表:

      CREATE TABLE logs (ts BIGINT, line STRING) PARTITIONED BY (dt STRING, country STRING); 

      當導入數據到分區表時,分區的值被顯式指定:

      LOAD DATA INPATH '/user/root/path'

      INTO TABLE logs 

      PATITION(dt='2001-01-01', country='GB');

      文件系統上,分區作為表目錄的下一級目錄存在,如下圖:

      

      在實際的SQL中,靈活指定分區將大大提高其效率,如下代碼將僅會掃描2001-01-01目錄下的GB目錄:

      select ts, dt, line from logs where dt = '2001-01-01'  and country='GB'

    分桶:

      在表或者分區中使用桶通常由兩個原因:

      一個是為了高效查詢。桶在表中加了特殊的結構,Hive在查詢的時候可以利用這些結構提高效率。例如,如果兩個表根據相同的字段進行分桶,則在對這兩個表進行關聯的時候,可以

    使用map-side關聯高效實現,前提是關聯的字段在分桶中出現。

      二是可以高效地進行抽樣。在分析大數據集時,經常需要對部分抽樣數據進行觀察和分析,分桶有利於高效實現抽象。

      為了讓Hive對表進行分桶,通過CLUSTERED BY 從句在創建表的時候指定:

      CREATE TABLE bucketed_users(id INT, name STRING)

      CLUSTERED BY (id) INTO 4 BUCKETS;

      指定表根據id字段進行分桶,並且分為4個桶。分桶時,Hive根據字段哈希后取余數來決定數據應該放哪個桶,因此每個桶都是整體數據的隨機抽樣。

      在map-side的關聯中,兩個表根據相同的字段進行分桶,因此處理左邊表的bucket時,可以直接從外表對應的bucket中提取數據進行關聯操作。map-side關聯的兩個表不一定需要完全相同bucket數量,只要成倍數即可。

      需要注意的是,Hive並不會對數據是否滿足表定義中的分桶進行校驗,只有在查詢時出現異常才會報錯。因此,一種更好的方式是將分桶的工作交給Hive來完成(設置hive.enforce.bucketing屬性為true即可)。

 

   3.2、Hive數據庫

       創建數據庫

        創建數據庫的完整語法如下:

        CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name

           [COMMENT database_name]

           [LOCATION hdfs_path]

           [WITH DBPROPERTIES(property_name=property_value,...)];

        例如:

        hive> create database my_hive_test if not exists

          commit 'this is my first hive database'

          with dbproperties(‘creator’ ='mike', 'date' = '2018-08-10');

 

      切換數據庫

        hive> use my_hive_test;

      查看數據庫

        hive> describe database my_hive_test;

      刪除數據庫

        hive> drop database my_hive_test;

           默認情況下,Hive不允許用戶刪除一個包含表的數據庫。用戶要么先刪除數據庫中的表,再刪除數據庫;要么在刪除命令的最后加上關鍵字CASCADE,這樣Hive會先刪除數據庫中的表,再刪除數據庫,

        命令如下(務必謹慎使用此命令):

        hive>drop database my_hive_test CASCADE;

      查看所有數據庫

        hive>show databases;

   4、Hive函數列表

      

 

      參考資料:《離線和實時大數據開發實戰》

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM