Hive、MySQL、HBase数据互导
Hive预操作
hive> create table dblab.user_action(id STRING,uid STRING, item_id STRING, behavior_type STRING, item_category STRING, visit_date DATE, province STRING) COMMENT 'Welcome to XMU dblab! ' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE;
确认这个数据文件在HDFS中确实已经被创建
cd /usr/local/hadoop
./bin/hdfs dfs -ls /user/hive/warehouse/dblab.db/user_action
将bigdata_user表中的数据插入到user_action
hive> INSERT OVERWRITE TABLE dblab.user_action select * from dblab.bigdata_user;
查询上面的插入命令是否成功
hive> select * from user_action limit 10;
使用Sqoop将数据从Hive导入MySQL
登录MySQL
mysql –u root –p
执行上面命令后,就进入mysql>命令提示符状态
创建数据库
mysql> show databases; #显示所有数据库
mysql> create database dblab; #创建dblab数据库
mysql> use dblab; #使用数据库
注意:使用下面的命令查看数据库编码:
mysql>show variables like "char%";
请确认当前编码格式为utf-8,否则无法导入中文。
若编码格式需要修改,参照博客:https://blog.csdn.net/weixin_42208645/article/details/80857416
创建表
mysql> CREATE TABLE `dblab`.`user_action` (`id` varchar(50),`uid` varchar(50),`item_id` varchar(50),`behavior_type` varchar(10),`item_category` varchar(50), `visit_date` DATE,`province` varchar(20)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> exit #创建成功后退出
导入数据
cd /usr/local/sqoop
./bin/sqoop export --connect jdbc:mysql://localhost:3306/dblab --username root --password hadoop --table user_action --export-dir '/user/hive/warehouse/dblab.db/user_action' --fields-terminated-by '\t'; #导入命令
如果输出类似以下信息,表示导入成功
查看MySQL中user_action表数据
mysql -u root -p
mysql> use dblab;
mysql> select * from user_action limit 10;
至此,从Hive导入数据到MySQL中的操作,顺利完成。
使用Sqoop将数据从MySQL导入HBase
cd /usr/local/hbase
./bin/start-hbase.sh
启动HBase shell
cd /usr/local/hbase
./bin/hbase shell
解决方法:
(1)原因:运行hbase(zookeeper)的用户无法写入zookeeper文件,导致znodedata为空。
解决:在hbase-site.xml指定一个运行hbase的用户有写入文件权限的目录作为zookeeper数据目录,如
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/home/user88/zk_data</value>
</property>
(2)hbase-site.xml文件中的
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoop1:49002/hbase</value>
</property>
rootdir中的IP设定很重要,需要设定对应的IP
与core-site.xml中fs.defaultFS中的路径不相同
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop1:9000</value>
</property>
(3)修改hbase-env.sh 配置文件,将其中的exportHBASE_MANAGES_ZK=false,重新启动hbase。若还是出现同样的错误,则进入zookeeper中删除hbase数据
试着解决了一下,打开了Hbase的配置文件,想对它进行修改,但是失败了。
后来重新启动Hadoop和Hbase,成功解决。
创建表user_action
hbase> create 'user_action', { NAME => 'f1', VERSIONS => 5}
导入数据
cd /usr/local/sqoop
./bin/sqoop import --connect jdbc:mysql://localhost:3306/dblab --username root --password hadoop --table user_action --hbase-table user_action --column-family f1 --hbase-row-key id --hbase-create-table -m 1
查看HBase中user_action表数据
hbase> scan 'user_action',{LIMIT=>10} #只查询前面10行
使用HBaseJava API把数据从本地导入到HBase中
cd /usr/local/hadoop
./sbin/start-all.sh
cd /usr/local/hbase
./bin/start-hbase.sh
数据准备
cd /usr/local/bigdatacase/dataset
/usr/local/hadoop/bin/hdfs dfs -get /user/hive/warehouse/dblab.db/user_action .
#将HDFS上的user_action数据复制到本地当前目录,注意'.'表示当前目录
cat ./user_action/* | head -10 #查看前10行数据
cat ./user_action/00000* > user_action.output #将00000*文件复制一份重命名为user_action.output,*表示通配符
head user_action.output #查看user_action.output前10行
编写数据导入程序(这里采用Eclipse编写Java程序实现HBase数据导入功能)
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;
public class HBaseImportTest extends Thread {
public Configuration config;
public HTable table;
public HBaseAdmin admin;
public HBaseImportTest() {
config = HBaseConfiguration.create();
// config.set("hbase.master", "master:60000");
// config.set("hbase.zookeeper.quorum", "master");
try {
table = new HTable(config, Bytes.toBytes("user_action"));
admin = new HBaseAdmin(config);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
if (args.length == 0) { //第一个参数是该jar所使用的类,第二个参数是数据集所存放的路径
throw new Exception("You must set input path!");
}
String fileName = args[args.length-1]; //输入的文件路径是最后一个参数
HBaseImportTest test = new HBaseImportTest();
test.importLocalFileToHBase(fileName);
}
public void importLocalFileToHBase(String fileName) {
long st = System.currentTimeMillis();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
fileName)));
String line = null;
int count = 0;
while ((line = br.readLine()) != null) {
count++;
put(line);
if (count % 10000 == 0)
System.out.println(count);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
table.flushCommits();
table.close(); // must close the client
} catch (IOException e) {
e.printStackTrace();
}
}
long en2 = System.currentTimeMillis();
System.out.println("Total Time: " + (en2 - st) + " ms");
}
@SuppressWarnings("deprecation")
public void put(String line) throws IOException {
String[] arr = line.split("\t", -1);
String[] column = {"id","uid","item_id","behavior_type","item_category","date","province"};
if (arr.length == 7) {
Put put = new Put(Bytes.toBytes(arr[0]));// rowkey
for(int i=1;i<arr.length;i++){
put.add(Bytes.toBytes("f1"), Bytes.toBytes(column[i]),Bytes.toBytes(arr[i]));
}
table.put(put); // put to server
}
}
public void get(String rowkey, String columnFamily, String column,
int versions) throws IOException {
long st = System.currentTimeMillis();
Get get = new Get(Bytes.toBytes(rowkey));
get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column));
Scan scanner = new Scan(get);
scanner.setMaxVersions(versions);
ResultScanner rsScanner = table.getScanner(scanner);
for (Result result : rsScanner) {
final List<KeyValue> list = result.list();
for (final KeyValue kv : list) {
System.out.println(Bytes.toStringBinary(kv.getValue()) + "\t"
+ kv.getTimestamp()); // mid + time
}
}
rsScanner.close();
long en2 = System.currentTimeMillis();
System.out.println("Total Time: " + (en2 - st) + " ms");
}
}
数据导入
注意:在导入之前,先清空user_action表。
hbase> truncate 'user_action'
下面运行hadoop jar命令,运行刚刚的程序
/usr/local/hadoop/bin/hadoop jar /usr/local/bigdatacase/hbase/ImportHBase.jar HBaseImportTest /usr/local/bigdatacase/dataset/user_action.output
查看HBase中user_action表数据
habse> scan 'user_action',{LIMIT=>10} #只查询前面10行
利用R进行数据可视化分析
$ sudo vim /etc/apt/sources.list
$ deb http://mirrors.xmu.edu.cn/CRAN/bin/linux/ubuntu/ trusty/
$ sudo apt-get update
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 51716619E084DAB9
$ sudo apt-get install r-base
$ R
用 >q() 退出R
安装依赖库
> install.packages('ggplot2')
> install.packages('devtools')
$ sudo apt-get install libssl-dev
$ sudo apt-get install libssh2-1-dev
$ sudo apt-get install libcurl4-openssl-dev
> devtools::install_github('taiyun/recharts')
可视化分析
连接MySQL并获取数据
$ service mysql start
$ mysql -u root -p
查询数据
mysql> use dblab;
mysql> select * from user_action limit 10;
使用如下命令让R连接到MySQL数据库:
>library(RMySQL)
>conn <- dbConnect(MySQL(),dbname='dblab',username='root',password='hadoop',host="127.0.0.1",port=3306)
>user_action <- dbGetQuery(conn,'select * from user_action')
此处又出现了一个错误,解决办法:
1、停止mysql服务
[root@localhost bin]# chkconfig --list |grep -i mysql
mysql 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
[root@localhost bin]# service mysql stop
Shutting down MySQL
2、用mysqld_safe重启服务
3、重设密码
4、重启服务
5、再次连接数据库
分析消费者对商品的行为:
>summary(user_action$behavior_type)
>summary(as.numeric(user_action$behavior_type))
用柱状图展示:
>library(ggplot2)
>ggplot(user_action,aes(as.numeric(behavior_type)))+geom_histogram()
分析销量排行前十的商品及其销量
>temp <- subset(user_action,as.numeric(behavior_type)==4) # 获取子数据集
>count <- sort(table(temp$item_category),decreasing = T) #排序
>print(count[1:10]) # 获取第1到10个排序结果
用散点图表示:
>result <- as.data.frame(count[1:10]) #将count矩阵结果转换成数据框
>ggplot(result,aes(Var1,Freq,col=factor(Var1)))+geom_point()
分析每年的哪个月份销量最大
>month <- substr(user_action$visit_date,6,7) # visit_date变量中截取月份
>user_action <- cbind(user_action,month) # user_action增加一列月份数据
用柱状图表示:
>ggplot(user_action,aes(as.numeric(behavior_type),col=factor(month)))+geom_histogram()+facet_grid(.~month)
分析国内哪个省份的消费者最有购买欲望
>library(recharts)
>rel <- as.data.frame(table(temp$province))
>provinces <- rel$Var1
>x = c()
>for(n in provinces){
>x[length(x)+1] = nrow(subset(temp,(province==n)))
>}
>mapData <- data.frame(province=rel$Var1,count=x, stringsAsFactors=F) # 设置地图信息
>eMap(mapData, namevar=~province, datavar = ~count) #画出中国地图
本地数据集上传到数据仓库Hive和 Hive数据分析的实验参照:大数据实验(一)