<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一文搞懂Hive的數(shù)據(jù)存儲與壓縮

          共 18732字,需瀏覽 38分鐘

           ·

          2021-09-23 15:39

          • 行存儲與列存儲

            • 行存儲的特點(diǎn)

            • 列存儲的特點(diǎn)

          • 常見的數(shù)據(jù)格式

            • TextFile

            • SequenceFile

            • RCfile

            • ORCfile

            • Parquet

          • 測試

            • 準(zhǔn)備測試數(shù)據(jù)

            • 存儲空間大小

            • 測試SQL 執(zhí)行效率

          • 總結(jié)

          • Hive 壓縮

            • Hive中間數(shù)據(jù)壓縮

            • 最終輸出結(jié)果壓縮

            • 常見的壓縮格式

            • 演示

          • 總結(jié)


          行存儲與列存儲

          • 當(dāng)今的數(shù)據(jù)處理大致可分為兩大類,聯(lián)機(jī)事務(wù)處理 OLTP(on-line transaction processing)聯(lián)機(jī)分析處理 OLAP(On-Line Analytical Processing)=,OLTP 是傳統(tǒng)關(guān)系型數(shù)據(jù)庫的主要應(yīng)用來執(zhí)行一些基本的、日常的事務(wù)處理比如數(shù)據(jù)庫記錄的增、刪、改、查等等而OLAP則是分布式數(shù)據(jù)庫的主要應(yīng)用它對實時性要求不高,但處理的數(shù)據(jù)量大通常應(yīng)用于復(fù)雜的動態(tài)報表系統(tǒng)上

          所以一般OLTP 都是使用行式存儲的,因為實時性要求高,而且有大量的更新操作,OLAP 都是使用列式存儲的,因為實時性要求不高,主要是要求性能好

          行存儲的特點(diǎn)

          • 查詢滿足條件的一整行數(shù)據(jù)的時,只需要找到其中一個值,其余的值都在相鄰地方,所以此時行存儲查詢的速度更快。
          • 傳統(tǒng)的關(guān)系型數(shù)據(jù)庫,如 Oracle、DB2、MySQL、SQL SERVER 等采用行式存儲法(Row-based),在基于行式存儲的數(shù)據(jù)庫中, 數(shù)據(jù)是按照行數(shù)據(jù)為基礎(chǔ)邏輯存儲單元進(jìn)行存儲的, 一行中的數(shù)據(jù)在存儲介質(zhì)中以連續(xù)存儲形式存在
          • TEXTFILE和SEQUENCEFILE的存儲格式都是基于行存儲的
          • 這種存儲格式比較方便進(jìn)行INSERT/UPDATE操作,不足之處就是如果查詢只涉及某幾個列,它會把整行數(shù)據(jù)都讀取出來,不能跳過不必要的列讀取。當(dāng)然數(shù)據(jù)比較少,一般沒啥問題,如果數(shù)據(jù)量比較大就比較影響性能,還有就是由于每一行中,列的數(shù)據(jù)類型不一致,導(dǎo)致不容易獲得一個極高的壓縮比,也就是空間利用率不高

          列存儲的特點(diǎn)

          • 查詢時,只有涉及到的列才會被查詢,不會把所有列都查詢出來,即可以跳過不必要的列查詢,在查詢只需要少數(shù)幾個字段的時候,能大大減少讀取的數(shù)據(jù)量;因為每一列的數(shù)據(jù)都是存儲在一起的,每個字段的數(shù)據(jù)類型一定是相同的,列式存儲可以針對性的設(shè)計更好的設(shè)計壓縮算法,高效的壓縮率,不僅節(jié)省儲存空間也節(jié)省計算內(nèi)存和CPU

          • 不足之處是INSERT/UPDATE很麻煩或者不方便,不適合掃描小量的數(shù)據(jù)

          • 列式存儲(Column-based)是相對于行式存儲來說的,新興的Hbase、HPVertica、EMCGreenplum等分布式數(shù)據(jù)庫均采用列式存儲。在基于列式存儲的數(shù)據(jù)庫中, 數(shù)據(jù)是按照列為基礎(chǔ)邏輯存儲單元進(jìn)行存儲的,一列中的數(shù)據(jù)在存儲介質(zhì)中以連續(xù)存儲形式存在

          列存儲的特點(diǎn):因為每個字段的數(shù)據(jù)聚集存儲,在查詢只需要少數(shù)幾個字段的時候,能大大減少讀取的數(shù)據(jù)量;每個字段的數(shù)據(jù)類型一定是相同的,列式存儲可以針對性的設(shè)計更好的設(shè)計壓縮算法。ORC和PARQUET是基于列式存儲的。

          舉個例子吧不然還是太抽象,假設(shè)一個表有10億行數(shù)據(jù),按照列式存儲的定義,應(yīng)該先將某個字段的10億條數(shù)據(jù)存儲完之后,再存儲其他字段。

          常見的數(shù)據(jù)格式

          Hive 支持一下幾種存儲格式,下面我們會對每種格式的特點(diǎn)進(jìn)行簡單介紹

          1. Text File
          2. SequenceFile
          3. RCFile
          4. Avro Files
          5. ORC Files
          6. Parquet
          7. Custom INPUTFORMAT and OUTPUTFORMAT(用戶自定義格式)

          Hive 默認(rèn)使用的實Text File,也就是說當(dāng)你建表的時候不指定文件的存儲格式的時候,它就使用的就是Text File,Hive 是支持指定默認(rèn)存儲格式的

          <property>
            <name>hive.default.fileformat</name>
            <value>TextFile</value>
            <description>
              Expects one of [textfile, sequencefile, rcfile, orc, parquet].
              Default file format for CREATE TABLE statement. Users can explicitly override it by CREATE TABLE ... STORED AS [FORMAT]
            </description>
          </property>

          TextFile

          存儲方式:行存儲

          默認(rèn)的存儲格式,數(shù)據(jù)不做壓縮,磁盤開銷大,數(shù)據(jù)解析開銷大。可結(jié)合Gzip、Bzip2使用(系統(tǒng)自動檢查,執(zhí)行查詢時自動解壓),但使用這種方式,壓縮后的文件不支持split,Hive不會對數(shù)據(jù)進(jìn)行切分,從而無法對數(shù)據(jù)進(jìn)行并行操作。

          并且在反序列化過程中,必須逐個字符判斷是不是分隔符和行結(jié)束符,因此反序列化開銷會比SequenceFile高幾十倍。

          SequenceFile

          SequenceFile是Hadoop API提供的一種二進(jìn)制文件支持,,存儲方式為行存儲,其具有使用方便、可分割、可壓縮的特點(diǎn)。

          壓縮數(shù)據(jù)文件可以節(jié)省磁盤空間,但Hadoop中有些原生壓縮文件的就是不支持分割,所以Hadoop 猜提供了SequenceFile 這種格式,支持分割的文件可以并行的有多個mapper程序處理大數(shù)據(jù)文件,大多數(shù)文件不支持可分割是因為這些文件只能從頭開始讀。

          SequenceFile支持三種壓縮選擇:NONE,RECORD,BLOCK。Record壓縮率低,一般建議使用BLOCK壓縮,RECORD是默認(rèn)選項,通常BLOCK會帶來較RECORD更好的壓縮性能。

          SequenceFile的優(yōu)勢是文件和hadoop api中的MapFile是相互兼容的。

          :建表使用這個格式,導(dǎo)入數(shù)據(jù)時會直接把數(shù)據(jù)文件拷貝到hdfs上不進(jìn)行處理。SequenceFile、RCFile、ORC格式的表不能直接從本地文件導(dǎo)入數(shù)據(jù),數(shù)據(jù)要先導(dǎo)入到TextFile格式的表中,然后再從TextFile表中用insert導(dǎo)入到SequenceFile、RCFile表中

          RCfile

          存儲方式:數(shù)據(jù)按行分塊,每塊按列存儲

          Record Columnar的縮寫,是Hadoop中第一個列式存儲格式。能夠很好的壓縮和快速的查詢性能,但是不支持模式演進(jìn)。是一種行列存儲相結(jié)合的存儲方式。

          首先,其將數(shù)據(jù)按行分塊,保同一行的數(shù)據(jù)位于同一個塊上,避免讀一個記錄需要讀取多個block。其次,塊數(shù)據(jù)列式存儲,有利于數(shù)據(jù)壓縮和快速的列存取,并且能跳過不必要的列讀取

          ORCfile

          存儲方式:數(shù)據(jù)按行分塊 每塊按照列存儲(不是真正意義上的列存儲,可以理解為分段列存儲,你可以對照我們講的那個例子來理解)

          ORC的全稱是(Optimized Row Columnar),ORC文件格式是一種Hadoop生態(tài)圈中的列式存儲格式,它的產(chǎn)生早在2013年初,最初產(chǎn)生自Apache Hive,用于降低Hadoop數(shù)據(jù)存儲空間和加速Hive查詢速度。和Parquet類似,它并不是一個單純的列式存儲格式,仍然是首先根據(jù)行組分割整個表,在每一個行組內(nèi)進(jìn)行按列存儲。

          ORC文件是自描述的,它的元數(shù)據(jù)使用Protocol Buffers序列化,并且文件中的數(shù)據(jù)盡可能的壓縮以降低存儲空間的消耗,目前也被Spark SQL、Presto等查詢引擎支持,但是Impala對于ORC目前沒有支持,仍然使用Parquet作為主要的列式存儲格式。2015年ORC項目被Apache項目基金會提升為Apache頂級項目。

          ORC文件特點(diǎn)是壓縮快 快速列存取,是rcfile的改良版本,相比RC能夠更好的壓縮,能夠更快的查詢,支持各種復(fù)雜的數(shù)據(jù)類型,比如datetime,decimal,以及復(fù)雜的struct是以二進(jìn)制方式存儲的,所以是不可以直接讀取,ORC文件也是自解析的,它包含許多的元數(shù)據(jù),這些元數(shù)據(jù)都是同構(gòu)ProtoBuffer進(jìn)行序列化的。

          需要注意的是 ORC在讀寫時候需要消耗額外的CPU資源來壓縮和解壓縮,當(dāng)然這部分的CPU消耗是非常少的。

          格式

          ORC文件:保存在文件系統(tǒng)上的普通二進(jìn)制文件,一個ORC文件中可以包含多個stripe,每個Orc文件由1個或多個stripe組成,每個stripe一般為HDFS的塊大小,每一個stripe包含多條記錄,這些記錄按照列進(jìn)行獨(dú)立存儲,對應(yīng)到Parquet中就是row group的概念。每個Stripe里有三部分組成,分別是Index Data,Row Data,Stripe Footer;

          stripe:一組行形成一個stripe,每次讀取文件是以行組為單位的,一般為HDFS的塊大小,保存了每一列的索引和數(shù)據(jù)

          文件級元數(shù)據(jù):包括文件的描述信息PostScript、文件meta信息(包括整個文件的統(tǒng)計信息)、所有stripe的信息和文件schema信息。

          stripe元數(shù)據(jù):保存stripe的位置、每一個列的在該stripe的統(tǒng)計信息以及所有的stream類型和位置。

          row group:索引的最小單位,一個stripe中包含多個row group,默認(rèn)為10000個值組成。每次讀取文件是以行組為單位的,一般為HDFS的塊大小,保存了每一列的索引和數(shù)據(jù)。

          在ORC文件中保存了三個層級的統(tǒng)計信息,分別為文件級別、stripe級別和row group級別的,他們都可以用來根據(jù)Search ARGuments(謂詞下推條件)判斷是否可以跳過某些數(shù)據(jù),在統(tǒng)計信息中都包含成員數(shù)和是否有null值,并且對于不同類型的數(shù)據(jù)設(shè)置一些特定的統(tǒng)計信息。

          file level:在ORC文件的末尾會記錄文件級別的統(tǒng)計信息,會記錄整個文件中columns的統(tǒng)計信息。這些信息主要用于查詢的優(yōu)化,也可以為一些簡單的聚合查詢比如max, min, sum輸出結(jié)果。

          **stripe level:**ORC文件會保存每個字段stripe級別的統(tǒng)計信息,ORC reader使用這些統(tǒng)計信息來確定對于一個查詢語句來說,需要讀入哪些stripe中的記錄。比如說某個stripe的字段max(a)=10,min(a)=3,那么當(dāng)where條件為a >10或者a <3時,那么這個stripe中的所有記錄在查詢語句執(zhí)行時不會被讀入

          row level: 為了進(jìn)一步的避免讀入不必要的數(shù)據(jù),在邏輯上將一個column的index以一個給定的值(默認(rèn)為10000,可由參數(shù)配置)分割為多個index組。以10000條記錄為一個組,對數(shù)據(jù)進(jìn)行統(tǒng)計。Hive查詢引擎會將where條件中的約束傳遞給ORC reader,這些reader根據(jù)組級別的統(tǒng)計信息,過濾掉不必要的數(shù)據(jù)。如果該值設(shè)置的太小,就會保存更多的統(tǒng)計信息,用戶需要根據(jù)自己數(shù)據(jù)的特點(diǎn)權(quán)衡一個合理的值

          數(shù)據(jù)訪問

          讀取ORC文件是從尾部開始的,第一次讀取16KB的大小,盡可能的將Postscript和Footer數(shù)據(jù)都讀入內(nèi)存。文件的最后一個字節(jié)保存著PostScript的長度,它的長度不會超過256字節(jié),PostScript中保存著整個文件的元數(shù)據(jù)信息,它包括文件的壓縮格式、文件內(nèi)部每一個壓縮塊的最大長度(每次分配內(nèi)存的大小)、Footer長度,以及一些版本信息。在Postscript和Footer之間存儲著整個文件的統(tǒng)計信息(上圖中未畫出),這部分的統(tǒng)計信息包括每一個stripe中每一列的信息,主要統(tǒng)計成員數(shù)、最大值、最小值、是否有空值等。

          接下來讀取文件的Footer信息,它包含了每一個stripe的長度和偏移量,該文件的schema信息(將schema樹按照schema中的編號保存在數(shù)組中)、整個文件的統(tǒng)計信息以及每一個row group的行數(shù)。

          處理stripe時首先從Footer中獲取每一個stripe的其實位置和長度、每一個stripe的Footer數(shù)據(jù)(元數(shù)據(jù),記錄了index和data的的長度),整個striper被分為index和data兩部分,stripe內(nèi)部是按照row group進(jìn)行分塊的(每一個row group中多少條記錄在文件的Footer中存儲),row group內(nèi)部按列存儲。每一個row group由多個stream保存數(shù)據(jù)和索引信息。每一個stream的數(shù)據(jù)會根據(jù)該列的類型使用特定的壓縮算法保存。在ORC中存在如下幾種stream類型:

          • PRESENT:每一個成員值在這個stream中保持一位(bit)用于標(biāo)示該值是否為NULL,通過它可以只記錄部位NULL的值
          • DATA:該列的中屬于當(dāng)前stripe的成員值。
          • LENGTH:每一個成員的長度,這個是針對string類型的列才有的。
          • DICTIONARY_DATA:對string類型數(shù)據(jù)編碼之后字典的內(nèi)容。
          • SECONDARY:存儲Decimal、timestamp類型的小數(shù)或者納秒數(shù)等。
          • ROW_INDEX:保存stripe中每一個row group的統(tǒng)計信息和每一個row group起始位置信息。

          在初始化階段獲取全部的元數(shù)據(jù)之后,可以通過includes數(shù)組指定需要讀取的列編號,它是一個boolean數(shù)組,如果不指定則讀取全部的列,還可以通過傳遞SearchArgument參數(shù)指定過濾條件,根據(jù)元數(shù)據(jù)首先讀取每一個stripe中的index信息,然后根據(jù)index中統(tǒng)計信息以及SearchArgument參數(shù)確定需要讀取的row group編號,再根據(jù)includes數(shù)據(jù)決定需要從這些row group中讀取的列,通過這兩層的過濾需要讀取的數(shù)據(jù)只是整個stripe多個小段的區(qū)間,然后ORC會盡可能合并多個離散的區(qū)間盡可能的減少I/O次數(shù)。然后再根據(jù)index中保存的下一個row group的位置信息調(diào)至該stripe中第一個需要讀取的row group中。

          使用ORC文件格式時,用戶可以使用HDFS的每一個block存儲ORC文件的一個stripe。對于一個ORC文件來說,stripe的大小一般需要設(shè)置得比HDFS的block小,如果不這樣的話,一個stripe就會分別在HDFS的多個block上,當(dāng)讀取這種數(shù)據(jù)時就會發(fā)生遠(yuǎn)程讀數(shù)據(jù)的行為。如果設(shè)置stripe的只保存在一個block上的話,如果當(dāng)前block上的剩余空間不足以存儲下一個strpie,ORC的writer接下來會將數(shù)據(jù)打散保存在block剩余的空間上,直到這個block存滿為止。這樣,下一個stripe又會從下一個block開始存儲。

          由于ORC中使用了更加精確的索引信息,使得在讀取數(shù)據(jù)時可以指定從任意一行開始讀取,更細(xì)粒度的統(tǒng)計信息使得讀取ORC文件跳過整個row group,ORC默認(rèn)會對任何一塊數(shù)據(jù)和索引信息使用ZLIB壓縮,因此ORC文件占用的存儲空間也更小

          Parquet

          Parquet能夠很好的壓縮,有很好的查詢性能,支持有限的模式演進(jìn)。但是寫速度通常比較慢。這中文件格式主要是用在Cloudera Impala上面的。Parquet文件是以二進(jìn)制方式存儲的,所以是不可以直接讀取的,文件中包括該文件的數(shù)據(jù)和元數(shù)據(jù),因此Parquet格式文件是自解析的。

          Parquet的設(shè)計方案,整體來看,基本照搬了Dremel中對嵌套數(shù)據(jù)結(jié)構(gòu)的打平和重構(gòu)算法,通過高效的數(shù)據(jù)打平和重建算法,實現(xiàn)按列存儲(列組),進(jìn)而對列數(shù)據(jù)引入更具針對性的編碼和壓縮方案,來降低存儲代價,提升計算性能。想要了解這一算法邏輯的,可以看Dremel的論文:Dremel: Interactive Analysis of WebScaleDatasets

          測試

          準(zhǔn)備測試數(shù)據(jù)

          首先我們生成一份測試數(shù)據(jù),這是生成數(shù)據(jù)的測試代碼

          public class ProduceTestData {
              SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd HH:MM:ss");

              @Test
              public void testRandomName() throws IOException {
                  Faker faker = new Faker(Locale.CHINA);
                  final Name name = faker.name();
                  final Address address = faker.address();
                  Number number = faker.number();
                  PhoneNumber phoneNumber = faker.phoneNumber();

                  BufferedWriter out = new BufferedWriter(new FileWriter("/Users/liuwenqiang/access.log"));
                  int num=0;
                  while (num<10000000){
                      int id = number.randomDigitNotZero();
                      String userName = name.name();
                      String time = simpleDateFormat.format(new Date(System.currentTimeMillis()));
                      String city = address.city();
                      String phonenum = phoneNumber.cellPhone();
                      StringBuilder stringBuilder = new StringBuilder();
                      stringBuilder.append(id);
                      stringBuilder.append("\t");

                      stringBuilder.append(userName);
                      stringBuilder.append("\t");

                      stringBuilder.append(city);
                      stringBuilder.append("\t");

                      stringBuilder.append(phonenum);
                      stringBuilder.append("\t");

                      stringBuilder.append(time);

                      out.write(stringBuilder.toString());
                      out.newLine();
                  }
                  out.flush();
                  out.close();
              }

          }

          下面準(zhǔn)備三張表,分別是log_text、log_orc和log_parquet

          create table log_text(
               id int,
               name string,
               city string,
               phone string,
               acctime string)
          row format delimited fields terminated by '\t'
          stored as textfile;
          LOAD DATA LOCAL INPATH '/Users/liuwenqiang/access.log' OVERWRITE INTO TABLE ods.log_text;
          create table log_orc(
               id int,
               name string,
               city string,
               phone string,
               acctime string)
          row format delimited fields terminated by '\t'
          stored as orc;
          insert overwrite table ods.log_orc select * from ods.log_text;
          create table log_parquet(
               id int,
               name string,
               city string,
               phone string,
               acctime string)
          row format delimited fields terminated by '\t'
          stored as parquet;
          insert overwrite table ods.log_parquet select * from ods.log_text;

          所有關(guān)于ORCFile的參數(shù)都是在Hive SQL語句的TBLPROPERTIES字段里面出現(xiàn)

          KeyDefaultNotes
          orc.compressZLIBhigh level compression (one of NONE, ZLIB, SNAPPY)
          orc.compress.size262,144number of bytes in each compression chunk
          orc.compress.size262,144number of bytes in each compression chunk
          orc.row.index.stride10,000number of rows between index entries (must be >= 1000)
          orc.create.indextruewhether to create row indexes

          存儲空間大小

          text

          orc

          parquet

          測試SQL 執(zhí)行效率

          測試SQL select city,count(1) as cnt from log_text group by city order by cnt desc;

          text

          orc

          parquet

          總結(jié)

          1. 介紹了行式存儲和列式存儲的特點(diǎn),以及適用場景
          2. 介紹了Hive 常見的存儲格式,Parquet 和 ORC都是二進(jìn)制存儲的,都是不可直接讀取的,Parquet和ORC 都是Apache 頂級項目,Parquet不支持ACID 不支持更新,ORC支持有限的ACID 和 更新
          3. 我們簡單對比了一下Text、ORCfile 和Parquet的存儲占用和查詢性能,因為我們的查詢比較簡單加上數(shù)據(jù)本身不是很大,所以查詢性能差異不是很大,但是占用空間存儲的差異還是很大的

          Hive 壓縮

          對于數(shù)據(jù)密集型任務(wù),I/O操作和網(wǎng)絡(luò)數(shù)據(jù)傳輸需要花費(fèi)相當(dāng)長的時間才能完成。通過在 Hive 中啟用壓縮功能,我們可以提高 Hive 查詢的性能,并節(jié)省 HDFS 集群上的存儲空間。

          HiveQL語句最終都將轉(zhuǎn)換成為hadoop中的MapReduce job,而MapReduce job可以有對處理的數(shù)據(jù)進(jìn)行壓縮。

          首先說明mapreduce哪些過程可以設(shè)置壓縮:需要分析處理的數(shù)據(jù)在進(jìn)入map前可以壓縮,然后解壓處理,map處理完成后的輸出可以壓縮,這樣可以減少網(wǎng)絡(luò)I/O(reduce通常和map不在同一節(jié)點(diǎn)上),reduce拷貝壓縮的數(shù)據(jù)后進(jìn)行解壓,處理完成后可以壓縮存儲在hdfs上,以減少磁盤占用量。

          Hive中間數(shù)據(jù)壓縮

          提交后,一個復(fù)雜的 Hive 查詢通常會轉(zhuǎn)換為一系列多階段 MapReduce 作業(yè),這些作業(yè)將通過 Hive 引擎進(jìn)行鏈接以完成整個查詢。因此,這里的 ‘中間輸出’ 是指前一個 MapReduce 作業(yè)的輸出,將會作為下一個 MapReduce 作業(yè)的輸入數(shù)據(jù)。

          可以通過使用 Hive Shell 中的 set 命令或者修改 hive-site.xml 配置文件來修改 hive.exec.compress.intermediate 屬性,這樣我們就可以在 Hive Intermediate 輸出上啟用壓縮。

          hive.exec.compress.intermediate:默認(rèn)為false,設(shè)置true為激活中間數(shù)據(jù)壓縮功能,就是MapReduce的shuffle階段對mapper產(chǎn)生中間壓縮。可以使用 set 命令在 hive shell 中設(shè)置這些屬性

          set hive.exec.compress.intermediate=true
          set mapred.map.output.compression.codec= org.apache.hadoop.io.compress.SnappyCodec
          或者
          set hive.exec.compress.intermediate=true
          set mapred.map.output.compression.codec=com.hadoop.compression.lzo.LzoCodec

          也可以在配置文件中進(jìn)行配置

          <property>
             <name>hive.exec.compress.intermediate</name>
             <value>true</value>
             <description>
               This controls whether intermediate files produced by Hive between multiple map-reduce jobs are compressed.
               The compression codec and other options are determined from Hadoop config variables mapred.output.compress*
             </description>
          </property>
          <property>
             <name>hive.intermediate.compression.codec</name>
             <value>org.apache.hadoop.io.compress.SnappyCodec</value>
             <description/>
          </property>

          最終輸出結(jié)果壓縮

          hive.exec.compress.output:用戶可以對最終生成的Hive表的數(shù)據(jù)通常也需要壓縮。該參數(shù)控制這一功能的激活與禁用,設(shè)置為true來聲明將結(jié)果文件進(jìn)行壓縮。

          mapred.output.compression.codec:將hive.exec.compress.output參數(shù)設(shè)置成true后,然后選擇一個合適的編解碼器,如選擇SnappyCodec。設(shè)置如下(兩種壓縮的編寫方式是一樣的):

          set hive.exec.compress.output=true 
          set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec
          或者
          set mapred.output.compress=true
          set mapred.output.compression.codec=org.apache.hadoop.io.compress.LzopCodec

          同樣可以通過配置文件配置

          <property>
            <name>hive.exec.compress.output</name>
            <value>true</value>
            <description>
              This controls whether the final outputs of a query (to a local/HDFS file or a Hive table) is compressed.
              The compression codec and other options are determined from Hadoop config variables mapred.output.compress*
            </description>
          </property>

          常見的壓縮格式

          Hive支持的壓縮格式有bzip2、gzip、deflate、snappy、lzo等。Hive依賴Hadoop的壓縮方法,所以Hadoop版本越高支持的壓縮方法越多,可以在$HADOOP_HOME/conf/core-site.xml中進(jìn)行配置:

          <property>  
              <name>io.compression.codecs</name>  
              <value>org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,com.hadoop.compression.lzo.LzoCodec,com.hadoop.compression.lzo.LzopCodec,org.apache.hadoop.io.compress.BZip2Codec
              </value>  
          </property>  
          <property>
           
          <property>
          <name>io.compression.codec.lzo.class</name>
          <value>com.hadoop.compression.lzo.LzoCodec</value>
          </property>

          需要注意的是在我們在hive配置開啟壓縮之前,我們需要配置讓Hadoop 支持,因為hive 開啟壓縮只是指明了使用哪一種壓縮算法,具體的配置還是需要在Hadoop 中配置

          常見的壓縮格式有:

          img

          其中壓縮比bzip2 > zlib > gzip > deflate > snappy > lzo > lz4,在不同的測試場景中,會有差異,這僅僅是一個大概的排名情況。bzip2、zlib、gzip、deflate可以保證最小的壓縮,但在運(yùn)算中過于消耗時間。

          從壓縮性能上來看:lz4 > lzo > snappy > deflate > gzip > bzip2,其中l(wèi)z4、lzo、snappy壓縮和解壓縮速度快,壓縮比低。

          所以一般在生產(chǎn)環(huán)境中,經(jīng)常會采用lz4、lzo、snappy壓縮,以保證運(yùn)算效率。

          壓縮格式對應(yīng)的編碼/解碼
          DEFAULTorg.apache.hadoop.io.compress.DefaultCodec
          Gziporg.apache.hadoop.io.compress.GzipCodec
          Bziporg.apache.hadoop.io.compress.BzipCodec
          Snappyorg.apache.hadoop.io.compress.SnappyCodec
          Lzoorg.apache.hadoop.io.compress.LzopCodec

          對于使用 Gzip or Bzip2 壓縮的文件我們是可以直接導(dǎo)入到text 存儲類型的表中的,hive 會自動幫我們完成數(shù)據(jù)的解壓

          CREATE TABLE raw (line STRING)
             ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n';
           
          LOAD DATA LOCAL INPATH '/tmp/weblogs/20090603-access.log.gz' INTO TABLE raw;

          Native Libraries

          Hadoop由Java語言開發(fā),所以壓縮算法大多由Java實現(xiàn);但有些壓縮算法并不適合Java進(jìn)行實現(xiàn),會提供本地庫Native Libraries補(bǔ)充支持。Native Libraries除了自帶bzip2, lz4, snappy, zlib壓縮方法外,還可以自定義安裝需要的功能庫(snappy、lzo等)進(jìn)行擴(kuò)展。而且使用本地庫Native Libraries提供的壓縮方式,性能上會有50%左右的提升。

          使用命令可以查看native libraries的加載情況:

          hadoop checknative -a

          完成對Hive表的壓縮,有兩種方式:配置MapReduce壓縮、開啟Hive表壓縮功能。因為Hive會將SQL作業(yè)轉(zhuǎn)換為MapReduce任務(wù),所以直接對MapReduce進(jìn)行壓縮配置,可以達(dá)到壓縮目的;當(dāng)然為了方便起見,Hive中的特定表支持壓縮屬性,自動完成壓縮的功能。

          Hive中的可用壓縮編解碼器

          要在 Hive 中啟用壓縮,首先我們需要找出 Hadoop 集群上可用的壓縮編解碼器,我們可以使用下面的 set 命令列出可用的壓縮編解碼器。

          hive> set io.compression.codecs;
          io.compression.codecs=
            org.apache.hadoop.io.compress.GzipCodec,
            org.apache.hadoop.io.compress.DefaultCodec,
            org.apache.hadoop.io.compress.BZip2Codec,
            org.apache.hadoop.io.compress.SnappyCodec,
            com.hadoop.compression.lzo.LzoCodec,
            com.hadoop.compression.lzo.LzopCodec

          演示

          首先我們創(chuàng)建一個未經(jīng)壓縮的表tmp_no_compress

          CREATE TABLE tmp_no_compress ROW FORMAT DELIMITED LINES TERMINATED BY '\n'
          AS SELECT * FROM log_text;

          我們看一下不設(shè)置壓縮屬性的輸出

          在 Hive Shell 中設(shè)置壓縮屬性:

          set hive.exec.compress.output=true;
          set mapreduce.output.fileoutputformat.compress=true;
          set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.GzipCodec;
          set mapreduce.output.fileoutputformat.compress.type=BLOCK;

          根據(jù)現(xiàn)有表 tmp_order_id 創(chuàng)建一個壓縮后的表 tmp_order_id_compress:

          CREATE TABLE tmp_compress ROW FORMAT DELIMITED LINES TERMINATED BY '\n'
          AS SELECT * FROM log_text;

          我們在看一下設(shè)置壓縮屬性后輸出:

          總結(jié)

          1. 數(shù)據(jù)壓縮可以發(fā)生在哪些階段 1 輸入數(shù)據(jù)可以壓縮后的數(shù)據(jù) 2 中間的數(shù)據(jù)可以壓縮 3 輸出的數(shù)據(jù)可以壓縮
          2. hive 僅僅是配置了開啟壓縮和使用哪種壓縮方式,真正的配置是在hadoop 中配置的,而數(shù)據(jù)的壓縮是在MapReduce 中發(fā)生的
          3. 對于數(shù)據(jù)密集型任務(wù),I/O操作和網(wǎng)絡(luò)數(shù)據(jù)傳輸需要花費(fèi)相當(dāng)長的時間才能完成。通過在 Hive 中啟用壓縮功能,我們可以提高 Hive 查詢的性能,并節(jié)省 HDFS 集群上的存儲空間。

          猜你喜歡
          Hadoop3數(shù)據(jù)容錯技術(shù)(糾刪碼)
          Hadoop 數(shù)據(jù)遷移用法詳解
          Flink實時計算topN熱榜
          數(shù)倉建模分層理論
          數(shù)倉建模方法論
          大數(shù)據(jù)組件重點(diǎn)學(xué)習(xí)這幾個


          瀏覽 33
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  男女猛干直接看 | 成人网站日皮视频 | 日本成人片在线免费观看 | 人人澡人人妻人人爽人人蜜桃 | 中国极品少妇XXX |