问题:要求sparksql统计json日志条数存入mysql数据库。
环境:spark1.6.2,hadoop2.7.3,mariadb10.1.4,centos7
数据处理环境:spark-shell 交互环境
数据量:100以内的测试json数据集。
存储位置:HDFS文件系统。
最终目标:统计json日志条数并存入maridb
问题解决步骤:
[数据怎么获取这里滤过]
必须提前要解决的问题:
spark sql必须能访问mysql数据库.
第一步:把mysql驱动jar包放入spark的lib路径下。例如:mysql-connector-java-5.1.26-bin.jar
第二步:修改spark-env.sh文件。
export SPARK_CLASSPATH=$SPARK_CLASSPATH:/usr/hdp/2.5.0.0-1245/spark/lib/mysql-connector-java-5.1.26-bin.jar ##你的spark lib存放mysql 驱动jar的路径。
第三步:重启spark.
手动制作测试数据集:
文件的名字以及数据:test.json
{"name":"a","size":"12"}
{"name":"a","size":"13"}
{"name":"b","size":"14"}
{"name":"b","size":"16"}
{"name":"c","size":"21"}
{"name":"d","size":"34"}
{"name":"a","size":"13"}
{"name":"b","size":"14"}
{"name":"b","size":"16"}
{"name":"c","size":"21"}
{"name":"d","size":"34"}
1.把测试数据集test.json从本地存入[put]到hdfs。
##创建测试路径:
hadoop fs -mkdir -p /test/input
##存入测试数据集到此路径
hadoop fs -put test.json /test/input
##检查数据是否存在
hadoop fs -ls /test/input
[hdfs@localhost~]$ hadoop fs -ls /test/input
Found 1 items
-rw-r--r-- 3 hdfs hdfs 18 2017-01-13 22:11 /test/input/test.json
Found 1 items
-rw-r--r-- 3 hdfs hdfs 18 2017-01-13 22:11 /test/input/test.json
2.从HDFS读取json数据。
启动spark-shell 交互环境
./spark-shell
##导入[import] spark sql相关的处理包。
import scala.xml.XML
import scala.sys.process._
import org.apache.spark.sql.SQLContext
import scala.collection.mutable.ArrayBuffer
import scala.io.Source
import java.io.PrintWriter
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SQLContext
import java.sql.DriverManager
import java.sql.PreparedStatement
import java.sql.Connection
import scala.sys.process._
import org.apache.spark.sql.SQLContext
import scala.collection.mutable.ArrayBuffer
import scala.io.Source
import java.io.PrintWriter
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SQLContext
import java.sql.DriverManager
import java.sql.PreparedStatement
import java.sql.Connection
import org.apache.spark.sql.types.IntegerType
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
import org.apache.spark.sql.Row
import java.util.Properties
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
import org.apache.spark.sql.Row
import java.util.Properties
import org.apache.spark.sql.SaveMode
import java.sql.{Connection, DriverManager, ResultSet}
import java.sql.{Connection, DriverManager, ResultSet}
import scala.collection.mutable.ArrayBuffer
##定义连接的mysql数据库的connection.
val driverUrl ="jdbc:mysql://ip:3306/test?user=root&password=123456&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8"
val sqlContext=new org.apache.spark.sql.SQLContext(sc)
val sqlContext=new org.apache.spark.sql.SQLContext(sc)
##指定路径名
val path="/test/input/*"
val all=sqlContext.read.json(path)
val all=sqlContext.read.json(path)
##临时表的名字是testtab
all.registerTempTable("testtab")
all.registerTempTable("testtab")
all.show
+----+----+
|name|size|
+----+----+
| a| 12|
| a| 13|
| b| 14|
| b| 16|
| c| 21|
| d| 34|
+----+----+
|name|size|
+----+----+
| a| 12|
| a| 13|
| b| 14|
| b| 16|
| c| 21|
| d| 34|
+----+----+
##接下来统计每个name的和。
val count_name=sqlContext.sql("select name,sum(size) as sizesum from testtab group by name")
count_name.show
count_name.show
+----+-------+
|name|sizesum|
+----+-------+
| a| 25.0|
| b| 30.0|
| c| 21.0|
| d| 34.0|
+----+-------+
|name|sizesum|
+----+-------+
| a| 25.0|
| b| 30.0|
| c| 21.0|
| d| 34.0|
+----+-------+
##最后把统计结果存入到mysql数据库。
count_name.write.mode(SaveMode.Append).jdbc(driverUrl, "testresult", new Properties) ###这个是把记录追加在表中,等于数据库的insert into table.如果数据库表已经存在,就用这个操作。
count_name.write.mode(SaveMode.OverWrite).jdbc(driverUrl, "testresult", new Properties) ###这个是创建表并把数据保存在当前的表中。相当于sql的 create table if not exits,第一次的时候,要用OverWrite.