(java语言版) spark+hive+hbase 离线大数据分析统计及运行效率实验

首先介绍一下我做实验的前提,我的数据都是存在Hbase中的,现在我的需求是要对Hbase中的数据进行大数据分析。

这里有一个前提条件,我的Hbase里的数据都是String类型,这个时候就存在一个Hbase排序的问题。因为hbase是根据ascii码进行字典排序,那么比如说:速度这种数字类型的字段,我保存成String以后,速度20,实际上比速度3小。不理解的可以自己去百度Hbase的数据排序规则。由于这个原因,如果我想查询速度<20的全部数据有一些困难,而且只用Hbase的scan进行查询效率也很慢。因此需要用到其他的大数据技术来满足我的需求。

以下我做的实验有很多,目的是找到一个快速的大数据分析方案,目前的阶段,我只需要生成报表,而不进行数据导出。

当然最终的方案是使用spark进行大数据分析,毕竟这是目前的主流技术。

首先介绍下我的实验环境,我这里是用3台机器搭建的最小集群,实习的生产环境至少比我的测试环境快10倍以上,当然现阶段不可能在生产环境上测试效率。我这里用的是linux centos6.5虚拟机,16G内存,8核CPU。

集群版本:我这里用的是HDP的Ambari集成的环境,说下我用到的技术的版本,因为版本不同,代码写法和注意事项也不一样,跟我环境不一样的只能进行参考。

HDFS 2.7.1.2.4

MapReduce2 2.7.1.2.4

YARN 2.7.1.2.4

Hive 1.2.1.2.4

HBase 1.1.2.2.4

Spark 1.6.0.2.4

这里首先我初始化了1000万条数据,作为数据集。

实验一:  Hive与HBase结合

Hive可以解决HBase排序问题。因为有必须使用HBase这个前提,所以我创建的是 EXTERNAL  表,即Hive的外部表。具体创建Hive表语句参考我的另外一个帖子,地址如下:

https://blog.csdn.net/lwb314/article/details/80346993

我这里做的实验是查询SOC字段<20;

首先是hive,代码如下

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

public class HiveTest2 {

	/*
	 * 之前网上有个错误的例子,加载路径是org.apache.hadoop.hive.jdbc.HiveDriver,多了一个hadoop,应该是比较老的版本的
	 * 我用的hive版本是1.2.1
	 */
	private static String driverName = "org.apache.hive.jdbc.HiveDriver";

	public static void main(String[] args) {
		try {
			Class.forName(driverName);
			Connection con = null;
			con = DriverManager.getConnection("jdbc:hive2://10.10.171.169:10000", "hive", "hive");// 之前是jdbc:hive:可能也是老版本的写法
			Statement stmt = con.createStatement();
			ResultSet res = null;
			// String sql =
			// "select * from lwb_test1 where vin = 'LBVHY1101JMK00005' and soc<10 limit 10";
			String sql = " select count(1) from lwb_test1 where soc<20";
			System.out.println("");
			System.out.println("Running: " + sql);
			long startTime = System.currentTimeMillis();
			res = stmt.executeQuery(sql);
//			ResultSetMetaData rsm = res.getMetaData(); // 获取列名
//			for (int i = 0; i < rsm.getColumnCount(); i++) {
//				System.out.print(rsm.getColumnName(i + 1).split("\\.")[1] + "\t");//输出列名
//			}
			System.out.println();
			long k = 0;
			while (res.next()) {
				k++;
				//System.out.println(res.getString(1));
//				System.out.println(res.getString(1) + "\t" + res.getString(2) + "\t" + res.getInt(3) + "\t" + res.getInt(4) + "\t"
//						+res.getString(5) + "\t" + res.getString(6) );
			}
			long endTime = System.currentTimeMillis();
			System.out.println("用时:" + (endTime - startTime));
			System.out.println("总共条数:" + k);
			stmt.close();
			con.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("error");
		}

	}

}

结果:

Running:  select count(1) from lwb_test1 where soc<20

记录条数:2001000
用时:50430

这里是从hive的1000万数据条数据里查询出来200万条的数量,条件查询,用时50秒。这是count

我把语句修改成如下,查询全部字段进行遍历

select * from lwb_test1 where soc<23然后屏蔽上循环里的打印语句,打印会降低执行效率

程序执行结果如下:

Running:  select * from lwb_test1 where soc<22
用时:160525
总共条数:2201156

以下是我的HBase查询代码

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.NavigableMap;
import java.util.Map.Entry;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
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.client.Table;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.util.Bytes;


public class SocScan {

	public static Configuration configuration;
	public static String zkHost = "devhadoop3,devhadoop2,devhadoop1";
	public static String zkPort = "2181";
	public static String zkParent = "/hbase-unsecure";
	private static Connection connection;

	static {
		configuration = HBaseConfiguration.create();
		configuration.set("hbase.zookeeper.quorum", zkHost);
		configuration.set("hbase.zookeeper.property.clientPort", zkPort);
		configuration.set("zookeeper.znode.parent", zkParent);
		try {
			connection = ConnectionFactory.createConnection(configuration);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception {
		try {

			Table table = connection.getTable(TableName.valueOf("lwb_test1"));
			Scan scan = new Scan();
			// scan.setStartRow(start.getBytes());
			// scan.setStopRow(stop.getBytes());
			// scan.setReversed(true);//
			// 倒序,倒序时候的开始结束rowkey也得反过来,例如不设置之前start是1,stop是3,那么设置之后start是3,stop是1
			Filter filter = new SingleColumnValueFilter("data".getBytes(), "soc".getBytes(), CompareOp.LESS, "29".getBytes());
			scan.setFilter(filter);
			scan.setCaching(1000);
			scan.setCacheBlocks(false);
			long startTime = System.currentTimeMillis();
			ResultScanner scanner = table.getScanner(scan);
			byte[] vin = "vin".getBytes();
			byte[] soc = "soc".getBytes();
			long k=0;
			for (Result result : scanner) {
//				NavigableMap<byte[], byte[]> map = result.getFamilyMap("data".getBytes());
//				System.out.println(new String(map.get(vin)) + "," + new String(map.get(soc)));
				k++;
			}
			long endTime = System.currentTimeMillis();
			System.out.println("用时:"+(endTime-startTime));
			System.out.println("总共条数:"+k);
			scanner.close();
			table.close();
			connection.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Hbase查询结果:

用时:83657
总共条数:2200369

 

实验一结论:

简单条件查询,基数相同,查询结果集相同的条件下,Hive用时基本是Hbase的一倍。但是Hive查询结果是正确的。

 

实验二:使用hive内部表进行查询

首先创建一张Hive自己的表,就是创建hbase关联表的第一行代码。创建后表里是没有数据的,那么这里复制数据的语句如下:

insert into lwb_test3 select * from lwb_test1;

这是直接从之前的lwb_test1表里查出全部数据,存入lwb_test3;

之后还是运行hive代码,只是把表名换一下。可以看到,时间基本上还要比HbaseScan快一点,多次测试,基本和HbaseScan时间一样。

Running:  select * from lwb_test3 where soc<22

用时:79297

总共条数:2201156

实验二结论:

hive使用内部表的查时间是外部表的一半,和HbaseScan的效率基本一样,而且结果正确。

 

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页