一、数据及部分代码来源:
解析geojson数据:https://github.com/jwills/geojson
纽约出租车数据:http://www.andresmh.com/nyctaxitrips/
https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page
二、需求
=====1.已经将2013年全年的出租车载客数据上传到HBase,放入ODS层。=====
一个月的数据为一张表,每张表的数据量大概1500万条,总量约1.8亿条。
=====2.确定分析需求:=====
#分析出租车的利用率,利用率和乘客的下车地点直接相关,下车地点会影响下一单载客的等待时长。
通过统计各个区域的下车量,以及各个区域出租车接单的平均等待时长,可以知道一下结论:
出租车的最佳候客地点在哪里?
乘客在某个地点在指定时间叫到出租车的概率有多大?
=====3.根据分析需求将纽约出租车数据按主题划分,放入EDW层。=====
EDW层数据:
(年份主题)将每个月的数据,经过异常和非法数据过滤后,汇总成一整年的数据。
【需要过滤掉的记录】
@无法提取到位置、时间信息,或提取异常的记录。
@位置坐标值为0的数据记录。
@不符合实际情况的记录,例如:下车时间早于上车时间,即乘车时间为负数。
=====4.分析EDW层主题数据,计算结果,放入ODS层。=====
=====5.将ODS层数据用于可视化展示。=====
三、代码
import java.io.IOException
import java.util.UUID
import com.cloudera.science.entity.Trip
import com.esri.core.geometry.Point
import org.apache.hadoop.hbase.client._
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.spark.HBaseContext
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.hbase._
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession
import org.apache.spark.{SparkConf, SparkContext}
import org.joda.time.Duration
import java.util.NavigableMap
import org.apache.hadoop.hbase.mapred.TableOutputFormat
import org.apache.hadoop.mapred.JobConf
/**
* @Author: gh
* @Description: 处理hbase ODS层的原始(出租车)数据。
* 进行数据过滤。
* 【需要过滤掉的记录】
* 无法提取到位置、时间信息,或提取异常的记录。
* 位置坐标值为0的数据记录。
* 不符合实际情况的记录,例如:下车时间早于上车时间,即乘车时间为负数。
*/
object DoHbaseOdsData {
private final val TABLE_NAME_ODS = "ods_original_testdb:taxi_nyc_2013_12"
private final val TABLE_NAME_EDW = "edw_testdb:taxi_nyc_2013_12"
private final val CF_EDW = "taxi"
private final val ZOOKEEPER_QUORUM = "zyb1:2181,zyb2:2181,zyb9:2181"
//hbaseconfig
val config = HBaseConfiguration.create
config.set("hbase.zookeeper.quorum", ZOOKEEPER_QUORUM)
config.set("hbase.hstore.blockingStoreFiles", "25")
//hadoop JobConf
var jobConf = new JobConf(config)
jobConf.set(TableOutputFormat.OUTPUT_TABLE,TABLE_NAME_EDW)
jobConf.setOutputFormat(classOf[TableOutputFormat])
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setAppName("Spark sql on hbase")
.setMaster("local[*]")
.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") //序列化
val sc: SparkContext = new SparkContext(conf)
val spark:SparkSession = SparkSession.builder().config(conf).getOrCreate()
/*val config: Configuration = HBaseConfiguration.create()
config.set(HConstants.ZOOKEEPER_QUORUM,ZOOKEEPER_QUORUM)*/
//hbase表格
val hbaseContext = new HBaseContext(sc, config)
val tableName: TableName = TableName.valueOf(TABLE_NAME_ODS)
var scan:Scan = new Scan()
//必须序列化,不然报错:ERROR:java.i