在工作中我們經(jīng)常使用的數(shù)據(jù)庫,數(shù)據(jù)庫一般存放的我們系統(tǒng)中常用的數(shù)據(jù),一般為百萬級別。如果數(shù)據(jù)量龐大,達(dá)到千萬級、億級又需要對他們進(jìn)行關(guān)聯(lián)運算,該怎么辦呢?

          前面我們已經(jīng)介紹了HDFS和MapReduce了,它倆結(jié)合起來能夠進(jìn)行各種運算,可是MapReduce的學(xué)習(xí)成本太高了,如果有一種工具可以直接使用sql將hdfs中的數(shù)據(jù)查出來,并自動編寫mapreduce進(jìn)行運算,這就需要使用到我們的hive數(shù)據(jù)倉庫。

          Hive基本概念

          什么是Hive
          Hive是基于Hadoop的一個數(shù)據(jù)倉庫工具,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張數(shù)據(jù)庫表,并提供類SQL查詢功能。
          為什么使用Hive

          * 直接使用hadoop所面臨的問題
          人員學(xué)習(xí)成本太高
          項目周期要求太短
          MapReduce實現(xiàn)復(fù)雜查詢邏輯開發(fā)難度太大
          * 為什么要使用Hive
          操作接口采用類SQL語句,提供快速開發(fā)的能力。
          避免了去寫MapReduce,減少開發(fā)人員的學(xué)習(xí)成本。
          擴展功能很方便
          Hive的特點

          * 可擴展
          Hive可以自由的擴展集群的規(guī)模,一般情況下不需要重啟服務(wù)。
          * 延展性
          Hive支持用戶自定義函數(shù),用戶可以根據(jù)自己的需求來實現(xiàn)自己的函數(shù)。注意:這里說的函數(shù)可不是存儲過程噢。
          * 容錯
          良好的容錯行,節(jié)點出現(xiàn)問題SQL仍可以完成執(zhí)行
          基本組成

          * 用戶接口:包括CLI、JDBC/ODBC、WebGUI
          * 元數(shù)據(jù)存儲:通常是存儲在關(guān)系數(shù)據(jù)庫如 mysql,derby中。
          * 解釋器、編譯器、優(yōu)化器、執(zhí)行器
          各組件的基本功能

          *
          用戶接口主要有三個:CLI、JDBC/ODBC和WebGUI。其中,CLI為shell命令行;JDBC/ODBC是Hive的JAVA實現(xiàn),與傳統(tǒng)數(shù)據(jù)庫JDBC類似;WebGUI是通過瀏覽器訪問Hive
          * 元數(shù)據(jù)存儲:Hive將元數(shù)據(jù)存儲在數(shù)據(jù)庫中。Hive中的元數(shù)據(jù)包括表的名字,表的列和分區(qū)及其屬性,是否為外部表,表的數(shù)據(jù)所在的目錄等等。
          *
          解釋器、編譯器、優(yōu)化器完成HQL查詢語句從此法分析、語法分析、編譯、優(yōu)化以及查詢計劃的生成。生成的查詢計劃存儲在HDFS中,并且隨后使用MapReduce執(zhí)行。
          Hive與Hadoop的關(guān)系
          sequenceDiagram 客戶端->>Hive處理轉(zhuǎn)換成MapReduce: 發(fā)送HSQL語句
          Hive處理轉(zhuǎn)換成MapReduce->>MapReduce運行: 提交任務(wù)到Hadoop MapReduce運行->>執(zhí)行結(jié)果文件放到HDFS或本地:
          執(zhí)行結(jié)果
          Hive與傳統(tǒng)數(shù)據(jù)庫對比

          --- Hive RDBMS
          查詢語言 HQL SQL
          數(shù)據(jù)存儲 HDFS Raw Device or Local FS
          執(zhí)行 MapReduce Excutor
          執(zhí)行延遲 高 低
          處理數(shù)據(jù)規(guī)模 大 小
          索引 0.8版本后加入位圖索引 有復(fù)雜的索引
          ==hive中具有sql數(shù)據(jù)庫,用來存儲元數(shù)據(jù)信息(如:表的屬性,數(shù)據(jù)的位置)。hive只適合用來做批量數(shù)據(jù)統(tǒng)計分析。讀多寫少==

          Hive的數(shù)據(jù)存儲

          * Hive中所有的數(shù)據(jù)都存儲在HDFS中,沒有專門的數(shù)據(jù)存儲格式(可支持Text,SequenceFile,ParqueFile,RCFile等)
          * 只需要在創(chuàng)建表的時候告訴Hive數(shù)據(jù)中的列分隔符和行分隔符。默認(rèn)列分隔符為ascii碼的控制符\001,行分隔符為換行符。
          * Hive中包含以下數(shù)據(jù)模型:DB、Table、External Table、Partition、Bucket。
          * db:在hdfs中表現(xiàn)為hive.metastore.warehouse.dir目錄下的一個文件夾
          * table:在hdfs中表現(xiàn)為所屬db目錄下的一個文件夾
          * external table:與table類似,不過其數(shù)據(jù)存放位置可以在任意指定路徑。刪除表時只會刪除元數(shù)據(jù),不會刪除實際數(shù)據(jù)
          * partition:在hdfs中表現(xiàn)為table目錄下的子目錄
          * bucket: 在hdfs中表現(xiàn)為同一個表目錄下根據(jù)hash散列之后的多個文件
          Hive的安裝部署

          安裝
          單機版(內(nèi)置關(guān)系型數(shù)據(jù)庫derby) 元數(shù)據(jù)庫mysql版
          這里使用常用的mysql版,使用derby的話不太方便,因為derby會將文件保存在你當(dāng)前啟動的目錄。如果下次你換個目錄啟動,會發(fā)現(xiàn)之前保存的數(shù)據(jù)不見了。
          元數(shù)據(jù)庫mysql版安裝

          安裝mysql數(shù)據(jù)庫
          mysql安裝僅供參考,不同版本mysql有各自的安裝流程。 # 刪除原有的mysql rpm -qa | grep mysql rpm -e
          mysql-libs-5.1.66-2.el6_3.i686 --nodeps rpm -ivh
          MySQL-server-5.1.73-1.glibc23.i386.rpm rpm -ivh
          MySQL-client-5.1.73-1.glibc23.i386.rpm # 修改mysql的密碼,并記得設(shè)置允許用戶遠(yuǎn)程連接
          /usr/bin/mysql_secure_installation # 登錄mysql mysql -u root -p
          配置hive

          配置HIVE_HOME環(huán)境變量
          vi conf/hive-env.sh #配置其中的$hadoop_home
          配置元數(shù)據(jù)庫信息
          vi hive-site.xml #添加如下內(nèi)容 <configuration> <!--配置mysql的連接地址--> <property>
          <name>javax.jdo.option.ConnectionURL</name>
          <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
          <description>JDBC connect string for a JDBC metastore</description> </property>
          <!--配置mysql的驅(qū)動--> <property> <name>javax.jdo.option.ConnectionDriverName</name>
          <value>com.mysql.jdbc.Driver</value> <description>Driver class name for a JDBC
          metastore</description> </property> <!--配置登錄用戶名--> <property>
          <name>javax.jdo.option.ConnectionUserName</name> <value>root</value>
          <description>username to use against metastore database</description>
          </property> <!--配置登錄密碼--> <property>
          <name>javax.jdo.option.ConnectionPassword</name> <value>root</value>
          <description>password to use against metastore database</description>
          </property> </configuration>
          放驅(qū)動包
          安裝hive和mysql完成后,將mysql的連接jar包拷貝到$HIVE_HOME/lib目錄下 如果出現(xiàn)沒有權(quán)限的問題,在mysql授權(quán) mysql
          -uroot -p #執(zhí)行下面的語句 *.*:表示所有庫下的所有表 %:任何ip地址或主機都可以連接 GRANT ALL PRIVILEGES ON *.*
          TO 'root'@'%' IDENDIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES;
          Jline包版本不一致問題
          到這一步其實已經(jīng)安裝好了,但是由于hadoop中的jline包版本和我們安裝hive的jline包版本不一致,會導(dǎo)致hql無法被執(zhí)行。
          因此我們還要把hive的lib目錄中的jline.2.12.jar替換掉$HADOOP_HOME/share/hadoop/yarn/lib/jline.0.9.94.jar
          啟動hive
          bin/hive
          登錄hive
          1.bin/hive 2.bin/beeline !connect jdbc:hive2://server1:10000 3.bin/beeline -u
          jdbc:hive2://server1:10000 -n hadoop
          創(chuàng)建表

          創(chuàng)建外部表
          create table tb_external(id int,name string) row format delimited fields
          terminated by',' location 'hdfs://kris/myhiveexternal';
          在hdfs中已在對應(yīng)路徑存在文件



          現(xiàn)在試試直接查詢



          ==為了保證數(shù)據(jù)的安全,我們一般把源數(shù)據(jù)表設(shè)置為外部表。數(shù)據(jù)只能通過外部加載導(dǎo)入==

          創(chuàng)建帶桶的表
          hive> create table student(id INT,age INT,name STRING) > partitioned
          by(stat_date STRING) > clustered by(id) sorted by(age) into 2 buckets > row
          format delimited fields terminated by ',';
          修改表

          增加分區(qū)
          alter table student add partition(stat_date='20190613')
          partition(stat_date='20190614'); alter table student add
          partition(stat_date='20190615') location '/user/hive/warehouse/student';
          刪除分區(qū)
          alter table student drop partition(stat_date='20190613');
          創(chuàng)建的分區(qū)會在hdfs對應(yīng)的路徑上創(chuàng)建文件夾





          ==如果增加的分區(qū)帶了路徑,那么不會在hdfs的路徑上顯示對應(yīng)的文件夾==

          顯示表分區(qū)
          show partitions student;
          重命名表
          alter table student rename to students;
          增加列
          alter table students add columns(name1 string);
          ==增加的列會在所有列后面,在partition列前面==

          替換所有列
          alter table students replace columns(id int,age int,name string);
          顯示命令
          #查看表 show tables #查看數(shù)據(jù)庫 show databases #查看分區(qū) show partitions table_name #查看方法
          show functions #顯示表詳細(xì)信息 desc extended table_name #格式話表信息 desc formatted
          table_name
          加載數(shù)據(jù)

          使用load data操作 hive會將文件復(fù)制到表對應(yīng)的hdfs文件夾下

          加載本地數(shù)據(jù)
          load data local inpath "students1.txt" [overwrite] into table students
          partition(stat_date="20190614");
          加上overwrite會講原有對應(yīng)分區(qū)的數(shù)據(jù)清除。
          如果目標(biāo)表(分區(qū))已經(jīng)有一個文件,并且文件名和filepath中的文件名沖突,那么現(xiàn)有的文件會被新文件所替代。





          導(dǎo)出數(shù)據(jù)

          保存select查詢結(jié)果的幾種方式:

          1、將查詢結(jié)果保存到一張新的hive表中
          create table t_tmp as select * from t_p;
          2、將查詢結(jié)果保存到一張已經(jīng)存在的hive表中
          insert into table t_tmp select * from t_p;
          3、將查詢結(jié)果保存到指定的文件目錄(可以是本地,也可以是hdfs)
          insert overwrite local directory '/home/hadoop/test' select * from t_p; insert
          overwrite directory '/aaa/test' select * from t_p;
          分桶示例

          插入分桶表的數(shù)據(jù)需要是已經(jīng)分好桶的,創(chuàng)建分桶的表并不會自動幫我們進(jìn)行分桶。
          #設(shè)置變量,設(shè)置分桶為true, 設(shè)置reduce數(shù)量是分桶的數(shù)量個數(shù) set mapreduce.job.reduces=2; # 或者選擇以下方式
          set hive.enforce.bucketing = true; # 向分桶表中插入數(shù)據(jù) insert into student
          partition(stat_date='20190614') select id,age,name from tmp_stu where
          stat_date='20190614' cluster by(id);


          可見在hdfs上根據(jù)id分成了兩個桶


          讓我們看看其中一個桶的內(nèi)容


          注意:
          ==1.order by 會對輸入做全局排序,因此只有一個reducer,會導(dǎo)致當(dāng)輸入規(guī)模較大時,需要較長的計算時間。==

          ==2.sort by不是全局排序,它是在數(shù)據(jù)進(jìn)去reduce task時有序。因此,如果用sort
          by進(jìn)行排序,并且設(shè)置mapreduce.job.reduces>1,則sort by只保證每個reduce task的輸出有序,不保證全局有序。==

          ==3.distribute by根據(jù)distribute by指定的內(nèi)容將數(shù)據(jù)分到同一個reducer==

          ==4.cluster by除了具有distribute by的功能外,還會對該字段進(jìn)行排序。因此我們可以這么認(rèn)為cluster by=distribute
          by + sort by==

          ==但是cluster by只能指定同一字段,當(dāng)我們要對某一字段進(jìn)行分桶,又要對另一字段進(jìn)行排序時,用distribute by + sort
          by更加靈活。==

          ==分桶表的作用:最大的作用是用來提高join操作的效率;==

          思考:select a.id,a.name,b.addr from a join b on a.id=b.id;
          如果a表和b表已經(jīng)是分桶表,而且分桶的字段是id字段。做這個join操作時,還需要全表做笛卡爾積嗎?(文末給出答案)

          分桶原理
          數(shù)據(jù)分桶的原理: 跟MR中的HashPartitioner的原理一模一樣 MR中:按照key的hash值去模除以reductTask的個數(shù)
          Hive中:按照分桶字段的hash值去模除以分桶的個數(shù) Hive也是
          針對某一列進(jìn)行桶的組織。Hive采用對列值哈希,然后除以桶的個數(shù)求余的方式?jīng)Q定該條記錄存放在哪個桶當(dāng)中。
          數(shù)據(jù)分桶的作用
          好處: 1、方便抽樣 2、提高join查詢效率
          如何將數(shù)據(jù)插入分桶表

          將數(shù)據(jù)導(dǎo)入分桶表主要通過以下步驟

          第一步:
          從hdfs或本地磁盤中l(wèi)oad數(shù)據(jù),導(dǎo)入中間表(也就是上文用到的tmp_stu)
          第二步:
          通過從中間表查詢的方式的完成數(shù)據(jù)導(dǎo)入 分桶的實質(zhì)就是對 分桶的字段做了hash 然后存放到對應(yīng)文件中,所以說如果原有數(shù)據(jù)沒有按key hash
          ,需要在插入分桶的時候hash,
          也就是說向分桶表中插入數(shù)據(jù)的時候必然要執(zhí)行一次MAPREDUCE,這也就是分桶表的數(shù)據(jù)基本只能通過從結(jié)果集查詢插入的方式進(jìn)行導(dǎo)入
          ==我們需要確保reduce 的數(shù)量與表中的bucket 數(shù)量一致,為此有兩種做法==
          1.讓hive強制分桶,自動按照分桶表的bucket 進(jìn)行分桶。(推薦) set hive.enforce.bucketing = true;
          2.手動指定reduce數(shù)量 set mapreduce.job.reduces = num; / set mapreduce.reduce.tasks =
          num; 并在 SELECT 后增加CLUSTER BY 語句 覺得不錯記得給我點贊加關(guān)注喔~ 公眾號:喜訊XiCent

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                欧美亚洲视频 | 插逼网123 | 国产亲子乱XXXXinin | 成人午夜免费无码欧美3p | 无码操逼在线观看 |