使用spark将从hbase中读取数据
val sparkConf = new SparkConf().setAppName(“xxxx”).setMaster(“local”)
//从数据库中读取数据
val sparkTask = SparkTaskDao.findTaskById(sparkConf.get(GlobalConstants.RUN_TASK_ID).toLong)
//判断 sparkTask 是否正确
if (sparkTask == null) {
throw new SparkException("与 taskID 对应的 任务不存在")
}
//如果sparkTask 存在,将sparkTask中的task_param转换为对象(这里用到了json)
//阿里巴巴编写的JSON可以将对象转换成json字符串,还可以将json字符串转换成对象
val taskParam = JSON.parseObject(sparkTask.task_param)
//开始创建 hbase 配置
val hbaseConf = HBaseConfiguration.create()
hbaseConf.set(GlobalConstants.HBASE_ZOOKEEPER_QUORUM, ConfigurationManager.getProperty(GlobalConstants.HBASE_ZOOKEEPER_QUORUM))
hbaseConf.set(GlobalConstants.HBASE_ZOOKEEPER_PROPERTY, ConfigurationManager.getProperty(GlobalConstants.HBASE_ZOOKEEPER_PROPERTY))
//设置表
hbaseConf.set(TableInputFormat.INPUT_TABLE, EventLogConstants.HBASE_EVENT_LOG_TABLE)
//设置扫描器
val scan = initScan(taskParam)
if(scan == null)return
//如果scan不为空,则将其进行序列化
val protoScan = ProtobufUtil.toScan(scan)
val stringScan = Base64.encodeBytes(protoScan.toByteArray)
hbaseConf.set(TableInputFormat.SCAN,stringScan)//定义scan的输入格式
//开始初始化 SparkContext
val sc = new SparkContext(sparkConf)
//加载hbase中的日志数据
//开始读取hbase中的数据(hbase 的配置,输入格式,输入的key,输入的value)【注意】这里,我们只需要hbase中的value值
val eventLogRDD = sc.newAPIHadoopRDD(hbaseConf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result])
//解析加载的数据,解析成元组
val sessionidActionRDD = eventLogRDD.map(result => {
//uuid
val uuid = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLMUN_NAME_UUID.getBytes()))
//println(uuid)
//会话ID
val sid = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLMUN_NAME_SID.getBytes()))
//服务器时间
val serverTime = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLUMN_NAME_SERVER_TIME.getBytes()))
//时间名称
val eventName = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLMUN_NAME_EVENT_NAME.getBytes()))
//国家(后面并没有用到,所以可以忽略掉)
val country = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLUMN_NAME_COUNTRY.getBytes()))
//省份
val province = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLUMN_NAME_PROVINCE.getBytes()))
//市
val city = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLUMN_NAME_CITY.getBytes()))
//点击的商品id
val goodsId = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLUMN_NAME_GOODS.getBytes()))
//获取URL
val url = Bytes.toString(result.getValue(EventLogConstants.HBASE_EVENT_LOG_TABLE_FAMILY.getBytes(),EventLogConstants.LOG_COLUMN_NAME_URL.getBytes()))
(sid,(uuid, sid, eventName, serverTime, province, city, goodsId))
})
/**
* 由于sessionidActionRDD会被多次引用,那么意味着它可能多次从hbase中读取数据
* 那么这个读取过程是非常耗时的,在这里可以对读取出来的数据进行持久化,以便下次可以直接从内存或磁盘中读取
*/
sessionidActionRDD.cache()
//【重点】将session进行聚合(sessionId,sid=sdsd|uuid=aksja|sid=askfja|clickGoodisI)
val sessionFullAggrInfoRDD = aggregateBySessionId(sessionidActionRDD)
sessionFullAggrInfoRDD.foreach(println(_))
sc.stop()