在本文中,我将Apache Spark连接到Oracle数据库,直接读取数据,并将其写入DataFrame。
随着我们日常生活中产生的数据量的快速增长,大数据技术已经很快进入我们的生活。 我们现在使用的工具能够快速有效地解决我们的业务,而不是传统的解决方案。 Apache Spark的使用是一种可以满足我们需求的常用技术。
Apache Spark基于一个可以非常快速和分布式地处理数据的框架。 在本文中,我不会详细描述Apache Spark技术,因此对细节感兴趣的人应该查看Apache Spark文档。
使用Apache Spark处理我们存储在RDBMS数据库中的数据的首选方法是首先将数据迁移到Hadoop(HDFS),分布式读取我们存储在Hadoop(HDFS)中的数据,然后使用Apache Spark处理它。 正如具有Hadoop生态系统经验的人所知,我们正在使用与Sqoop集成到Hadoop生态系统的工具在Hadoop生态系统和其他系统(RDBMS-NoSQL)之间交换数据。 Sqoop是一种易于使用,通用且高效的数据传输工具。
这是在RDBMS之前将要处理的数据移动到Hadoop环境,然后使用Apache Spark导入要处理的数据所涉及的一些成本。 我们不使用我们移动到HDFS的数据这一事实将导致我们在HDFS中丢失一定的空间,并且还会增加处理时间。Apache Spark有一种方法可以直接读取和使用RDBMS,而无需转存到HDFS那里。
我使用的工具和版本如下:
Hadoop: Hadoop 2.7.1
Apache Spark: Apache Spark 2.1.0
Oracle database: Oracle 11g R2, Enterprise Edition
Linux: SUSE Linux
为此,我们需要在系统中包含ojdbc6.jar文件。 你可以使用此链接下载它。
我们将在Oracle数据库中创建表,我们将从Oracle中读取这些表并在其中插入样本数据。
CREATE TABLE EMP
(
EMPNO NUMBER,
ENAME VARCHAR (10),
JOB VARCHAR (9),
MGR NUMBER,
SAL NUMBER,
COMM NUMBER,
DEPTNO NUMBER
);
INSERT INTO EMP VALUES
(7369, 'SMITH', 'CLERK', 7902, 800, 50, 20);
INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698, 1600, 300, 30);
INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698, 1250, 500, 30);
INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839, 2975, NULL, 20);
INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698, 1250, 1400, 30);
INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839, 2850, NULL, 30);
INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839, 2450, NULL, 10);
INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566, 3000, NULL, 20);
INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL, 5000, NULL, 10);
INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698, 1500, 0, 30);
INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788, 1100, NULL, 20);
INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698, 950, NULL, 30);
INSERT INTO EMP VALUES
(7902, 'FORD', 'ANALYST', 7566, 3000, NULL, 20);
INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782, 1300, NULL, 10);
CREATE TABLE DEPT
(
DEPTNO NUMBER,
DNAME VARCHAR (14),
LOC VARCHAR (13)
);
INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');
COMMIT;
现在我们从带有Pyspark接口(Python接口)的linux终端启动Apache Spark。
bin/pyspark
--jars "/home/jars/ojdbc6.jar"
--master yarn-client
--num-executors 10
--driver-memory 16g
--executor-memory 8g
我们启动了Apache Spark。 现在让我们编写Python代码来从数据库中读取数据并运行它。
empDF = spark.read \
.format("jdbc") \
.option("url", "jdbc:oracle:thin:@//hostname:portnumber/SID") \
.option("dbtable", "hr.emp") \
.option("user", "db_user_name") \
.option("password", "password") \
.option("driver", "oracle.jdbc.driver.OracleDriver") \
.load()
在我们写入empDF dataframe时,让我们看一下这个dataframe的内容。
empDF.printSchema()
empDF.show()
我使用Apache Spark直接连接到Oracle数据库。 同样,也可以以相同的方式获得查询结果。
query = "(select empno,ename,dname from emp, dept where emp.deptno = dept.deptno) emp"
empDF = spark.read \
.format("jdbc") \
.option("url", "jdbc:oracle:thin:username/password@//hostname:portnumber/SID") \
.option("dbtable", query) \
.option("user", "db_user_name") \
.option("password", "password") \
.option("driver", "oracle.jdbc.driver.OracleDriver") \
.load()
empDF.printSchema()
empDF.show()
从上面的例子中可以看出,使用起来非常简单实用。
使用此方法,可以直接并行地加载大型表,但我将在另一篇文章中进行性能评估。
------------------------------------------------
如果说需要直接在编译器中运行如(Spyder, PyCharm),需要从外部导入ojcbc6.jar包,则需要在spark环境中配置jar包的地址.具体方式参考pyspark连接hbase,注意一点!如果是集群的话,则每一台机器都需要导入包并修改配置文件.
------------------------------------------------