大數據-06-Spark之讀寫Hive數據

簡介

Hive中的表是純邏輯表,就只是表的定義等,即表的元數據。Hive自己不存儲數據,它徹底依賴HDFS和MapReduce。這樣就能夠將結構化的數據文件映射爲爲一張數據庫表,並提供完整的SQL查詢功能,並將SQL語句最終轉換爲MapReduce任務進行運行。 而HBase表是物理表,適合存放非結構化的數據。html

  1. 二者分別是什麼?

Apache Hive是數據倉庫。經過Hive可使用HQL語言查詢存放在HDFS上的數據。HQL是一種類SQL語言,這種語言最終被轉化爲Map/Reduce. 雖然Hive提供了SQL查詢功能,可是Hive不可以進行交互查詢--由於它是基於MapReduce算法。
Apache Hbase Key/Value,基礎單元是cell,它運行在HDFS之上。和Hive不同,Hbase的可以在它的數據庫上實時運行,而不是運行MapReduce任務,。java

  1. 二者的特色
    Hive幫助熟悉SQL的人運行MapReduce任務。由於它是JDBC兼容的。運行Hive查詢會花費很長時間,由於它會默認遍歷表中全部的數據。但能夠經過Hive的分區來控制。由於這樣一來文件大小是固定的,就這麼大一塊存儲空間,從固定空間裏查數據是很快的。
    HBase經過存儲key/value來工做。注意版本的功能。node

  2. 應用場景
    Hive適合用來對一段時間內的數據進行分析查詢,例如,用來計算趨勢或者網站的日誌。Hive不該該用來進行實時的查詢。由於它須要很長時間才能夠返回結果。
    Hbase很是適合用來進行大數據的實時查詢。Facebook用Hbase進行消息和實時的分析。它也能夠用來統計Facebook的鏈接數。
  3. 總結
    Hive和Hbase是兩種基於Hadoop的不一樣技術--Hive是一種類SQL的引擎,能夠直接將文件轉成數據庫。而且運行MapReduce任務,Hbase是一種在Hadoop之上的NoSQL 的Key/vale數據庫。Hive能夠用來進行統計查詢,HBase能夠用來進行實時查詢。數據也能夠從Hive寫到Hbase,再從Hbase寫回Hive。
    Note, Hive is not something you install on worker nodes. Hive is a Hadoop client. Just run Hive according to the instructions you see at the Hive site.
    Hive不須要安裝到每一個HADOOP節點,它是一個HADOOP客戶端,僅在須要的地方安裝便可mysql

安裝前提:
安裝好了hadoop,hadoop的集羣搭建
安裝好了mysql。這裏咱們就開始安裝MySQL算法

安裝MySql

1.1 卸載原有的Mysql
在root用戶下操做 找出mysql的相關目錄sql

sudo find / -name mysql

顯示結果爲:shell

/usr/share/bash-completion/completions/mysql
/etc/apparmor.d/abstractions/mysql

經過命令rm -rf將mysql有關目錄都刪除掉,例如我這裏只有上述的兩個目錄數據庫

sudo rm -rf /etc/apparmor.d/abstractions/mysql
sudo rm -rf /usr/share/bash-completion/completions/mysql

1.2 使用如下命令便可進行mysql安裝,注意安裝前先更新一下軟件源以得到最新版本apache

sudo apt-get install mysql-server  #安裝mysql

上述命令會安裝如下包:
apparmor
mysql-client-5.7
mysql-common
mysql-server
mysql-server-5.7
mysql-server-core-5.7
所以無需再安裝mysql-client等。安裝過程會提示設置mysql root用戶的密碼,設置完成後等待自動安裝便可。默認安裝完成就啓動了mysql。vim

  • 啓動和關閉mysql服務器:
service mysql start
service mysql stop
  • 確認是否啓動成功,mysql節點處於LISTEN狀態表示啓動成功:
sudo netstat -tap | grep mysql

此處輸入圖片的描述

  • 進入mysql shell界面:
mysql -u root -p

此處輸入圖片的描述

  • 解決利用sqoop導入MySQL中文亂碼的問題(能夠插入中文,但不能用sqoop導入中文)
    致使導入時中文亂碼的緣由是character_set_server默認設置是latin1,以下圖。
    此處輸入圖片的描述
    能夠單個設置修改編碼方式set character_set_server=utf8;可是重啓會失效,建議按如下方式修改編碼方式。
    (1)編輯配置文件。sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
    (2)在[mysqld]下添加一行character_set_server=utf8。以下圖
    此處輸入圖片的描述
    (3)重啓MySQL服務。service mysql restart
    (4)登錄MySQL,並查看MySQL目前設置的編碼。show variables like "char%";
    此處輸入圖片的描述

    MySQL經常使用操做

    注意:MySQL中每一個命令後都要以英文分號;結尾。
    一、顯示數據庫
    mysql> show databases;
    MySql剛安裝完有兩個數據庫:mysql和test。mysql庫很是重要,它裏面有MySQL的系統信息,咱們改密碼和新增用戶,實際上就是用這個庫中的相關表進行操做。

二、顯示數據庫中的表
mysql> use mysql; (打開庫,對每一個庫進行操做就要打開此庫)
Database changed
mysql> show tables;

三、顯示數據表的結構:
describe 表名;

四、顯示錶中的記錄:
select * from 表名;
例如:顯示mysql庫中user表中的紀錄。全部能對MySQL用戶操做的用戶都在此表中。
select * from user;

五、建庫:
create database 庫名;
例如:建立一個名字位aaa的庫
mysql> create databases aaa;

六、建表:
use 庫名;
create table 表名 (字段設定列表);
例如:在剛建立的aaa庫中創建表person,表中有id(序號,自動增加),xm(姓名),xb(性別),csny(出身年月)四個字段
use aaa;
mysql> create table person (id int(3) auto_increment not null primary key, xm varchar(10),xb varchar(2),csny date);
能夠用describe命令察看剛創建的表結構。
mysql> describe person;
describe-person

七、增長記錄
例如:增長几條相關紀錄。
mysql>insert into person values(null,’張三’,’男’,’1997-01-02′);
mysql>insert into person values(null,’李四’,’女’,’1996-12-02′);
由於在建立表時設置了id自增,所以無需插入id字段,用null代替便可。
可用select命令來驗證結果。
mysql> select * from person;
select-from-person

八、修改紀錄
例如:將張三的出生年月改成1971-01-10
mysql> update person set csny=’1971-01-10′ where xm=’張三’;

九、刪除紀錄
例如:刪除張三的紀錄。
mysql> delete from person where xm=’張三’;

十、刪庫和刪表
drop database 庫名;
drop table 表名;

十一、查看mysql版本
在mysql5.0中命令以下:
show variables like ‘version’;
或者:select version();

Hive 安裝

配置mysql

  • 啓動並登錄mysql shell
service mysql start #啓動mysql服務
 mysql -u root -p  #登錄shell界面
  • 新建hive數據庫。
mysql> create database hive;
  • 配置mysql容許hive接入:
mysql> create user 'hive'@'%' identified by 'hive';  # 用戶,機器名,密碼
mysql> grant all on *.* to 'hive'@'%' identified by 'hive';   #將全部數據庫的全部表的全部權限賦給hive用戶,後面的hive是配置hive-site.xml中配置的鏈接密碼
mysql> flush privileges;  #刷新mysql系統權限關係表

安裝Hive

  1. 下載並解壓hive源程序
    Hive下載地址
sudo tar -zxvf ./apache-hive-2.2.0-bin.tar.gz -C /usr/local   # 解壓到/usr/local中
cd /usr/local/
sudo mv apache-hive-2.2.0-bin hive       # 將文件夾名改成hive
sudo chown -R hadoop hive                # 修改文件權限
  1. 配置環境變量
    爲了方便使用,咱們把hive命令加入到環境變量中去,編輯~/.bashrc文件vim ~/.bashrc,在最前面一行添加:
export HADOOP_HOME=/usr/local/hadoop
export HIVE_HOME=/usr/local/hive
export PATH=$PATH:$HIVE_HOME/bin

保存退出後,運行source ~/.bashrc使配置當即生效。

  1. 進入/usr/local/hive/conf目錄,這個目錄下存在的文件都是模板,須要複製和更名,要修改的以下
cp hive-env.sh.template hive-env.sh
cp hive-default.xml.template hive-site.xml
cp hive-log4j2.properties.template hive-log4j2.properties
cp hive-exec-log4j2.properties.template hive-exec-log4j2.properties
  1. 在hdfs目錄下創建三個文件,用來存放hive信息,並賦予777權限
hdfs dfs -mkdir -p /user/hive/warehouse
hdfs dfs -mkdir -p /user/hive/tmp
hdfs dfs -mkdir -p /user/hive/log
hdfs dfs -chmod -R 777 /user/hive/warehouse
hadoop fs -chmod 777 /user/hive/tmp
hdfs dfs -chmod -R 777 /user/hive/tmp 
hdfs dfs -chmod -R 777 /user/hive/log
  1. 修改hive-env.sh文件
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HADOOP_HOME=/usr/local/hadoop
export HIVE_HOME=/usr/local/hive
export HIVE_CONF_DIR=/usr/local/hive/conf
  1. 在hive-site.xml文件中 字段的配置:
<property>
    <name>hive.exec.scratchdir</name>
    <value>/usr/local/hive/tmp</value>
</property>
<property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/user/hive/warehouse</value>
</property>
<property>
    <name>hive.querylog.location</name>
    <value>/user/hive/log</value>
</property>

<property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>root</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>root</value>
  </property>
  <property>
    <name>hive.exec.script.wrapper</name>
    <value/>
    <description/>
  </property>
  <property>
    <name>hive.metastore.schema.verification</name>
    <value>false</value>
  </property>

注意!! hive.exec.script.wrapper須要在數據庫相關配置以後。

  1. 建立/usr/local/hive/tmp文件夾
sudo mkdir /usr/local/hive/tmp

而後在配置文件hive-site.xml中,把全部的${system:java.io.tmpdir} 都替換爲/usr/local/hive/tmp,把全部的${system:user.name}替換爲root

  1. 配置jdbc的驅動
    下載mysql-connector-java-5.1.46-bin.jar 包(也能夠在下載頁面,選擇Looking for previous GA versions?去找想要的版本),複製放到/usr/local/hive/lib目錄下就能夠了
  2. 初始化hive,在hive2.0之後的版本,初始化命令都是:
schematool -dbType mysql -initSchema

在Hive中建立數據庫和表

進入Shell命令提示符狀態。由於須要藉助於MySQL保存Hive的元數據,因此,請首先啓動MySQL數據庫:

service mysql start  #能夠在Linux的任何目錄下執行該命令

因爲Hive是基於Hadoop的數據倉庫,使用HiveQL語言撰寫的查詢語句,最終都會被Hive自動解析成MapReduce任務由Hadoop去具體執行,所以,須要啓動Hadoop,而後再啓動Hive。
而後執行如下命令啓動Hadoop:

cd /usr/local/hadoop
./sbin/start-all.sh
cd /usr/local/hive
./bin/hive  #因爲已經配置了path環境變量,這裏也能夠直接使用hive,不加路徑 我這裏用了一次 ,彷佛後面spark操做須要啓動後面這個服務 bin/hive --service metastore &

經過上述過程,咱們就完成了MySQL、Hadoop和Hive三者的啓動。
下面咱們進入Hive,新建一個數據庫sparktest,並在這個數據庫下面建立一個表student,並錄入兩條數據。
下面操做請在Hive命令提示符下操做:

hive> create database if not exists sparktest;//建立數據庫sparktest
hive> show databases; //顯示一下是否建立出了sparktest數據庫
//下面在數據庫sparktest中建立一個表student
hive> create table if not exists sparktest.student(
> id int,
> name string,
> gender string,
> age int);
hive> use sparktest; //切換到sparktest
hive> show tables; //顯示sparktest數據庫下面有哪些表
hive> insert into student values(1,'Xueqian','F',23); //插入一條記錄
hive> insert into student values(2,'Weiliang','M',24); //再插入一條記錄
hive> select * from student; //顯示student表中的記錄

經過上面操做,咱們就在Hive中建立了sparktest.student表,這個表有兩條數據。

鏈接Hive讀寫數據

如今咱們看如何使用Spark讀寫Hive中的數據。注意,操做到這裏以前,你必定已經按照前面的各個操做步驟,啓動了Hadoop、Hive、MySQL和spark-shell(包含Hive支持)。
在啓動以前,咱們須要作一些準備工做,咱們須要修改「/usr/local/sparkwithhive/conf/spark-env.sh」這個配置文件:

cd /usr/local/spark/spark-2.3.0-bin-hadoop2.7/conf
vim spark-env.sh

這樣就使用vim編輯器打開了spark-env.sh這個文件,這文件裏面之前可能包含一些配置信息,所有刪除,而後輸入下面內容:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export SCALA_HOME=/usr/local/scala/scala-2.10.7
export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)
export CLASSPATH=$CLASSPATH:/usr/local/hive/lib
export HIVE_CONF_DIR=/usr/local/hive/conf
export SPARK_CLASSPATH=$SPARK_CLASSPATH:/usr/local/hive/lib/mysql-connector-java-5.1.46-bin.jar

保存spark-env.sh這個文件,退出vim編輯器。

爲了讓Spark可以訪問Hive,須要把Hive的配置文件hive-site.xml拷貝到Spark的conf目錄下,請在Shell命令提示符狀態下操做:

cp /usr/local/hive/conf/hive-site.xml /usr/local/spark/spark-2.3.0-bin-hadoop2.7/conf

把鏈接用的jar文件拷貝到指定位置

cp mysql-connector-java-5.1.46-bin.jar /usr/local/spark/spark-2.3.0-bin-hadoop2.7/jars/

好了,通過了前面如此漫長的準備過程,如今終於能夠啓動spark-shell,編寫調試Spark鏈接Hive讀寫數據的代碼了。

下面,請在spark-shell(包含Hive支持)中執行如下命令從Hive中讀取數據:

Scala> import org.apache.spark.sql.Row
Scala> import org.apache.spark.sql.SparkSession
 
Scala> case class Record(key: Int, value: String)
 
// warehouseLocation points to the default location for managed databases and tables
Scala> val warehouseLocation = "spark-warehouse"
 
Scala> val spark = SparkSession.builder().appName("Spark Hive Example").config("spark.sql.warehouse.dir", warehouseLocation).enableHiveSupport().getOrCreate()
 
Scala> import spark.implicits._
Scala> import spark.sql
//下面是運行結果
scala> sql("SELECT * FROM sparktest.student").show()
+---+--------+------+---+
| id|    name|gender|age|
+---+--------+------+---+
|  1| Xueqian|     F| 23|
|  2|Weiliang|     M| 24|
+---+--------+------+---+

啓動後就進入了hive命令提示符狀態,而後輸入以下命令查看sparktest.student表中的數據:

hive> use sparktest;
OK
Time taken: 0.016 seconds
 
hive> select * from student;
OK
1   Xueqian F   23
2   Weiliang    M   24
Time taken: 0.05 seconds, Fetched: 2 row(s)

下面,咱們編寫程序向Hive數據庫的sparktest.student表中插入兩條數據,請切換到spark-shell(含Hive支持)終端窗口,輸入如下命令:

scala> import java.util.Properties
scala> import org.apache.spark.sql.types._
scala> import org.apache.spark.sql.Row
 
//下面咱們設置兩條數據表示兩個學生信息
scala> val studentRDD = spark.sparkContext.parallelize(Array("3 Rongcheng M 26","4 Guanhua M 27")).map(_.split(" "))
 
//下面要設置模式信息
scala> val schema = StructType(List(StructField("id", IntegerType, true),StructField("name", StringType, true),StructField("gender", StringType, true),StructField("age", IntegerType, true)))
 
//下面建立Row對象,每一個Row對象都是rowRDD中的一行
scala> val rowRDD = studentRDD.map(p => Row(p(0).toInt, p(1).trim, p(2).trim, p(3).toInt))
 
//創建起Row對象和模式之間的對應關係,也就是把數據和模式對應起來
scala> val studentDF = spark.createDataFrame(rowRDD, schema)
 
//查看studentDF
scala> studentDF.show()
+---+---------+------+---+
| id|     name|gender|age|
+---+---------+------+---+
|  3|Rongcheng|     M| 26|
|  4|  Guanhua|     M| 27|
+---+---------+------+---+
//下面註冊臨時表
scala> studentDF.registerTempTable("tempTable")
 
scala> sql("insert into sparktest.student select * from tempTable")

而後,請切換到剛纔的hive終端窗口,輸入如下命令查看Hive數據庫內容的變化:

hive> select * from student;
OK
1   Xueqian F   23
2   Weiliang    M   24
3   Rongcheng   M   26
4   Guanhua M   27
Time taken: 0.049 seconds, Fetched: 4 row(s)
相關文章
相關標籤/搜索