为了账号安全,请及时绑定邮箱和手机立即绑定

笔记:新手的Spark指南

标签:
Python


前言

既然做了Hive的整理,那就把spark的也整理下吧,当做入门指南和自己的笔记吧~与君共勉

Spark基础


Spark原理过程

webp

  1. 使用spark-submit提交一个Spark作业之后,这个作业就会启动一个对应的Driver进程。

  • Driver:运行Application的main()函数并且创建SparkContext

Driver根据我们设置的参数(比如说设定任务队列,设定最大内存等)Cluster Manager 申请运行Spark作业需要使用的资源,这里的资源指的就是Executor进程,YARN集群管理器会根据我们为Spark作业设置的资源参数,在各个工作节点上,启动一定数量的Executor进程,每个Executor进程都占有一定数量的内存和CPU core。

  • Executor:是为某Application运行在Worker Node上的一个进程,该进程负责运行Task,并且负责将数据存在内存或者磁盘上,每个Application都有各自独立的Executors

  • Cluster Manager:集群管理器,在集群上获取资源的外部服务(例如:Local、Standalone、Mesos或Yarn等集群管理系统)

申请到了作业执行所需的资源之后,river进程会将我们编写的Spark作业代码分拆为多个stage,每个stage执行一部分代码片段,并为每个stage创建一批task,然后将这些task分配到各个Executor进程中执行,一个stage的所有task都执行完毕之后,会在各个节点本地的磁盘文件中写入计算中间结果,然后Driver就会调度运行下一个stage。下一个stage的task的输入数据就是上一个stage输出的中间结果。如此循环往复,直到将我们自己编写的代码逻辑全部执行完

  • task:最小的计算单元,负责执行一模一样的计算逻辑(也就是我们自己编写的某个代码片段)


什么是RDD?

全称为弹性分布式数据集;本质上,RDD是种编程抽象,代表可以跨机器进行分割的只读对象集合。RDD可以从一个继承结构(lineage)重建(因此可以容错),通过并行操作访问,可以读写HDFS或S3这样的分布式存储,更重要的是,可以缓存到worker节点的内存中进行立即重用。由于RDD可以被缓存在内存中,Spark对迭代应用特别有效,因为这些应用中,数据是在整个算法运算过程中都可以被重用。大多数机器学习和最优化算法都是迭代的,使得Spark对数据科学来说是个非常有效的工具。另外,由于Spark非常快,可以通过类似Python REPL的命令行提示符交互式访问。

RDD特点

  • RDD在抽象上来说是一种元素集合,包含了数据。它是被分区的,分为多个分区,每个分区分布在集群中的不同节点上,从而让RDD中的数据可以被并行操作。(分布式数据集)

  • RDD的数据默认情况下存放在内存中的,但是在内存资源不足时,Spark会自动将RDD数据写入磁盘。比如每个节点最多放5万数据,结果你每个partition是10万数据。那么就会把partition中的部分数据写入磁盘上,进行保存。(弹性)

  • RDD将操作分为两类:transformation与action。无论执行了多少次transformation操作,RDD都不会真正执行运算,只有当action操作被执行时,运算才会触发。而在RDD的内部实现机制中,底层接口则是基于迭代器的,从而使得数据访问变得更高效,也避免了大量中间结果对内存的消耗。

  • RDD最重要的特性就是,提供了容错性,可以自动从节点失败中恢复过来。即如果某个节点上的RDD partition,因为节点故障,导致数据丢了,那么RDD会自动通过自己的数据来源重新计算该partition。这一切对使用者是透明的。

RDD在Spark中的地位及作用

这需要从四个方面阐述

  • 为什么会有Spark?

    因为传统的并行计算模型无法有效的解决迭代计算(iterative)和交互式计算(interactive);而Spark的使命便是解决这两个问题,这也是他存在的价值和理由。

  • Spark如何解决迭代计算?

    其主要实现思想就是RDD,把所有计算的数据保存在分布式的内存中。迭代计算通常情况下都是对同一个数据集做反复的迭代计算,数据在内存中将大大提升IO操作。这也是Spark涉及的核心:内存计算。

  • Spark如何实现交互式计算?

    因为Spark是用scala语言实现的,Spark和scala能够紧密的集成,所以Spark可以完美的运用scala的解释器,使得其中的scala可以向操作本地集合对象一样轻松操作分布式数据集。当然你也可以使用python,java,R等接口,spark也提供了相应的操作方式

  • Spark和RDD的关系?

    可以理解为:RDD是一种具有容错性基于内存的集群计算抽象方法,Spark则是这个抽象方法的实现。

如何操作RDD?

Step1-获取RDD

  • 自己创建个RDD,如以下语句:rdd = sc.parallelize(['1,2,3,4','5,6,6','9,10,11'])

  • 从共享的文件系统获取,(如:HDFS)

  • 通过已存在的RDD转换

  • 将已存在scala集合(只要是Seq对象)并行化,通过调用SparkContext的parallelize方法实现

  • 改变现有RDD的之久性;RDD是懒散,短暂的.(RDD的固化:cache缓存至内错;save保存到分布式文件系统)

Step2-操作RDD

Transformation:根据数据集创建一个新的数据集,计算后返回一个新RDD;例如:Map将数据的每个元素经过某个函数计算后,返回一个新的分布式数据集即RDD。

值得注意的是,RDD的转化操作都是惰性求值得,也就意味着在被调用行动操作之前Spark不会开始计算,相反,Spark会在内部记录下所要求执行的操作的相关信息,因此在调用sc.textFile()时候,数据并没有读取进来,而是在必要的时候才会进行读取。所以也就导致了导入文件的时候感觉很快的错觉

  • Transformation的一些例子

webp

image

def func(a):
    line_split = a.split(",")    return sum(map(int,line_split))

data = sc.parallelize(['1,2,3,4','5,6,6','9,10,11'])  # 生成rddt_rdd= data.map(func)  # rdd的Transformation过程a_rdd = t_rdd.collect()  # action过程  [10, 17, 30]

Actions:对数据集计算后返回一个数值value给驱动程序;例如:Reduce将数据集的所有元素用某个函数聚合后,将最终结果返回给程序。返回的是一个新的数据类型,这里注意的是,返回的并不是新的RDD,只有Transformation之后是新的RDD

  • Actions具体内容

webp

image

spark执行步骤

  1. 定义一个或多个RDD,可以通过获取存储在磁盘上的数据(HDFS,Cassandra,HBase,Local Disk),并行化内存中的某些集合,转换(transform)一个已存在的RDD,或者,缓存或保存。

  2. 通过传递一个闭包(函数)给RDD上的每个元素来调用RDD上的操作。Spark提供了除了Map和Reduce的80多种高级操作。

  3. 使用结果RDD的动作(action)(如count、collect、save等)。动作将会启动集群上的worker机器进行计算。

当Spark在一个worker上运行闭包时,闭包中用到的所有变量都会被拷贝到节点上,但是由闭包的局部作用域来维护。Spark提供了两种类型的共享变量,这些变量可以按照限定的方式被所有worker访问。广播变量会被分发给所有worker,但是是只读的。累加器这种变量,worker可以使用关联操作来“加”,通常用作计数器。

Spark实际操作

那么, sc的是什么鬼?

你可以把他理解成由SparkContext构造出来的实例,通过这个实例我们可以构造自己的RDD

# -*- coding:utf-8 -*-from pyspark import SparkContext, SparkConffrom pyspark.streaming import StreamingContextimport math
appName ="hellospark" #你的应用程序名称master= "local"#设置单机conf = SparkConf().setAppName(appName).setMaster(master)#配置SparkContextsc = SparkContext(conf=conf)# 一个简单的wordcount测试str_ = '''this is a word count test only test show twice'''data = sc.parallelize(str_.split(" "))
data.map(lambda x:(x,1)).reduceByKey(lambda x,y:x+y).collect()# spark.akka.frameSize: 控制Spark中通信消息的最大容量 (如 task 的输出结果),默认为10M。当处理大数据时,task 的输出可能会大于这个值,需要根据实际数据设置一个更高的值。# SparkConf为Spark配置类,配置已键值对形式存储,封装了一个ConcurrentHashMap类实例settings用于存储Spark的配置信息;配置项包括:master、appName、Jars、ExecutorEnv等等# SparkContext用于连接Spark集群、创建RDD、累加器(accumlator)、广播变量(broadcast variables),所以说SparkContext为Spark程序的根

注意sc的构造是怎么来的

方法一:在jupyter中操作(推荐)

当然,你得把pyspark的kernel配到jupyter中,可参考解决:win远程连接ubuntu服务器安装jupyter,启动pyspark

webp

这里写图片描述

方法二:使用spark-submit pythonfile.py来实现提交python脚本操作

# 前提是在一个文件夹中,不然要定位文件位置$ spark-submit --driver-memory 6G --queue 如果有队列填上队列名字 testpy.py 可带参数# pyspark test# 中文测试

方法三:使用ipython在pyspark的shell中操作

# 启动local spark:pyspark --master local[2]# local[2]是开双核的意思,[4]即是开4核xiaoju@map-traffic-spd131.gz01:~$ pyspark --master local[2]

In [8]: line = sc.textFile("file:/home/xiaoju/user/xukai/test.tx #创建RDD载入的路径这里是机器路径
   ...: t")

In [9]: pythonlines = line.filter(lambda line:"test" in  line) # 转化操作

In [10]: pythonlines.first() # 行动操作
Out[10]: u'test;'# 当一个文本读取为RDD时,输入的每一行都会成为RDD的一个元素In [21]: line.first()
Out[21]: u'this is a test txtfile!'

In [24]: print line.first().split(" ")[0] # 这样就可以流畅使用python进行操作了,只是导入的时候用的是RDD存储
this

In [26]: stringlist = line.first().split(" ")
In [27]: nums = sc.parallelize(stringlist) # 用sparkContext的parallelize制作RDD的,是ParallelCollectionRDD,创建一个并行集合。

In [28]: squared = nums.map(lambda x:x=="this").collect()

In [29]: for num in squared:
    ...:     print num
    ...:
True
False
False
False
False

In [34]: words = lines.flatMap(lambda line:line.split(" ")).collec
    ...: t()  # 使用collece()才能进行for输出,flatmap文件中的所有行数据仅返回了一个数组对象

In [35]: for i in words:
    ...:     print i
    ...:
this
is
a
test# 产生新的键值对pair类型RDDIn [56]: rdd = sc.parallelize([1,2,3,3])# 操作过程中,转化并不会被执行,需要有个动作操作才被执行,比如collect()In [57]: rdd.collect()
Out[57]: [1, 2, 3, 3]
In [59]: rdd1 = rdd.map(lambda x:(x,x+1))

In [60]: rdd1.collect()
Out[60]: [(1, 2), (2, 3), (3, 4), (3, 4)]

In [64]: rdd2 = rdd1.filter(lambda x: x[0]>2)

In [65]: rdd2.collect()
Out[65]: [(3, 4), (3, 4)]

In [67]: rdd1.sortByKey().collect()
Out[67]: [(1, 2), (2, 3), (3, 4), (3, 4)]

一些Demo

# -*- coding:utf-8 -*-# 如果使用jupyter的话,sc已经构造好了,不需要再倒入包from pyspark import SparkContext, SparkConffrom pyspark.streaming import StreamingContextimport math
appName ="hellospark" #你的应用程序名称master= "local"#设置单机conf = SparkConf().setAppName(appName).setMaster(master)#配置SparkContextsc = SparkContext(conf=conf) 
# parallelize:并行化数据,转化为RDD# 并行集合的一个重要参数是slices,表示数据集切分的份数。Spark将会在集群上为每一份数据起一个任务。# 典型地,你可以在集群的每个CPU上分布2-4个slices. 一般来说,Spark会尝试根据集群的状况,# 来自动设定slices的数目。data = [1, 2, 3, 4, 5]
distData = sc.parallelize(data, numSlices=10)  # numSlices为分块数目,根据集群数进行分块
 #--------------------------------------------------# textFile读取外部数据rdd = sc.textFile("file:/data/map_da/xukai/sparkstreaming/test/test.txt")  # 以行为单位读取外部文件,并转化为RDDprint rdd.collect()#  打印出的结果是  [u'lslsllslsiiiiiiiiiii']#--------------------------------------------------# map:迭代,对数据集中数据进行单独操作def my_add(l):
    return (l,l)
data = [1, 2, 3, 4, 5]
distData = sc.parallelize(data)  # 并行化数据集result = distData.map(my_add)print (result.collect())  # 返回一个分布数据集# 打印出的结果  [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]#--------------------------------------------------# filter:过滤数据def my_add(l):
    result = False
    if l > 2:
        result = True
    return result
data = [1, 2, 3, 4, 5]
distData = sc.parallelize(data)#并行化数据集,分片result = distData.filter(my_add)print (result.collect())#返回一个分布数据集
 # [3, 4, 5]# zip:将两个RDD对应元素组合为元组#--------------------------------------------------x = sc.parallelize(range(0,5))
y = sc.parallelize(range(1000, 1005))print x.zip(y).collect() 
# [(0, 1000), (1, 1001), (2, 1002), (3, 1003), (4, 1004)]
 
 
 #union 组合两个RDDprint x.union(x).collect()# [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]# Aciton操作#--------------------------------------------------
 # collect:返回RDD中的数据rdd = sc.parallelize(range(1, 10))print rddprint rdd.collect()# ParallelCollectionRDD[11] at parallelize at PythonRDD.scala:423# [1, 2, 3, 4, 5, 6, 7, 8, 9]#--------------------------------------------------# collectAsMap:以rdd元素为元组,以元组中一个元素作为索引返回RDD中的数据m = sc.parallelize([('a', 2), (3, 4)]).collectAsMap()print m['a']print m[3]#2#4#--------------------------------------------------# groupby函数:根据提供的方法为RDD分组:rdd = sc.parallelize([1, 1, 2, 3, 5, 8])def fun(i):
    return i % 2result = rdd.groupBy(fun).collect()print [(x, sorted(y)) for (x, y) in result] 
# [(0, [2, 8]), (1, [1, 1, 3, 5])]#--------------------------------------------------# reduce:对数据集进行运算rdd = sc.parallelize(range(1, 10))
result = rdd.reduce(lambda a, b: a + b)print result# 45#--------------------------------------------------a = sc.parallelize([i for i in range(9)], 3)print a.collect()#[0, 1, 2, 3, 4, 5, 6, 7, 8]y = a.map(lambda a:(a,a*2))  # 需要的表现形式为(a,a*2)的形式,而a是传递的参数print y.collect()#[(0, 0), (1, 2), (2, 4), (3, 6), (4, 8), (5, 10), (6, 12), (7, 14), (8, 16)]z = a.map(lambda a:a*2)print print z.collect()#[0, 2, 4, 6, 8, 10, 12, 14, 16]y = a.flatMap(lambda a:(a*2,a*3))print y.collect();#[0, 0, 2, 3, 4, 6, 6, 9, 8, 12, 10, 15, 12, 18, 14, 21, 16, 24]#--------------------------------------------------# union有点像appendx = sc.parallelize(['A','A','B'])
y = sc.parallelize(['D','C','A'])
z = x.union(y)
z2 = x.intersection(y)
print(x.collect())#['A', 'A', 'B']print(y.collect())#['D', 'C', 'A']print(z.collect())#['A', 'A', 'B', 'D', 'C', 'A']print(z2.collect())# ['A']#--------------------------------------------------x = sc.parallelize([1,2,3])
y = x.groupBy(lambda x: 'A' if (x%2 == 1) else 'B' )
print(x.collect())#[1, 2, 3]print([(j[0],[i for i in j[1]]) for j in y.collect()])#[('A', [1, 3]), ('B', [2])]#--------------------------------------------------x=sc.parallelize([1,3,1,2,3])
y=x.countByValue()print y[1]#2#--------------------------------------------------# 按升序排,取前n个x = sc.parallelize([1,3,1,2,3,4,1,6])
y=x.takeOrdered(5)# [1, 1, 1, 2, 3]

小结

  1. 总的来说,RDD之所以被描述为"弹性",是因为在任何时候都能进行重算,因为保存RDD数据的一台机器失败时,Spark可以使用这种特性来重算出丢弃的部分分区。

  2. 转化RDD的时候,是返回新的RDD而不是对现有的RDD进行操作,只有在执行动作的时候返回的是其他数据类型 。


Spark进阶

这里会总结下我以前实习时候用到过的一些处理方法

使用MySqldb+Pyspark操作Mysql

  1. 首先得知道,这个数据库在哪,也就是数据库所在服务器的ip地址,才能进行连接

# 使用ping命令进行所需要连接的数据库的ip地址获取$ ping 服务器PING xxxxxx bytes of data.
64 bytes from xxxxxx: icmp_seq=1 ttl=64 time=0.020 ms
  1. 使用Mysqldb包进行数据库的连接操作

In [22]: import MySQLdb
In [23]: conn = MySQLdb.connect(host=ip地址,user=用户名
    ...: ,passwd=密码,db='test',charset='utf8')# 这边连接的时候最好制定数据库,即添加 db="test",charset="utf8",如不制定,则在sql语句中选择上指定的数据库名字In [24]: cursor = conn.cursor()

In [25]: count = cursor.execute("select count(*) from test_uk ")

In [26]: print cursor.fetchall()
((8L,),)# 打开服务器上的Mysql查看一下,ok,没问题,获取行数正确mysql> select * from test_uk;
+----+----+-------+| id | tp | value |+----+----+-------+|  3 |  1 |  0.75 ||  4 |  5 |     0 ||  5 |  6 |     2 ||  6 |  4 |     0 ||  9 |  7 |     3 || 11 |  9 |     2 || 12 | 10 |    11 || 14 | 13 |    13 |+----+----+-------+8 rows in set (0.00 sec)# 写入test数据库中的tbl_realtime_statis表,记得需要提交mysql> desc tbl_realtime_statis

+-------+---------+------+-----+---------+-------+| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       || value | double  | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

# 开始执行insert动作

In [38]: cursor.execute('INSERT INTO tbl_realtime_statis (id,value) VALUE
    ...: S (1,11)')
Out[38]: 1L

In [39]: cursor.connection.commit()

mysql> select * from tbl_realtime_statis;
+------+-------+
| id   | value |+------+-------+|    1 |    11 |
+------+-------+
1 row in set (0.00 sec)

更多语句参考:python使用mysqldb连接数据库操作方法示例详解

使用spark-submit pythonfile来执行本地txt写入指定数据库的操作

在文件同目录下创建名为txttosql.py的python脚本,填写如下

conn = MySQLdb.connect(host='',user='',passwd='',db='test',charset='utf8')
cursor = conn.cursor()

datapath = "test.txt"with open(datapath) as f:    for line in f.readlines():
        linesplit = line.strip().split(",")
        key = int(linesplit[0])
        value = int(linesplit[1])
        sqlstring = 'INSERT INTO tbl_realtime_statis (id,value) VALUES (%d,%d)'%(key,value)
        cursor.execute(sqlstring)
        cursor.connection.commit()

cursor.close()
conn.close()

之后执行spark-submit txttosql.py即可,注意数据库如果已有数据,将不会被覆盖,而是之后插入操作

使用JDBC+Pypark进行MySql操作

建一个parallelize的RDD

In [12]: rdd1 = sc.parallelize([(1,'id1',100000,12,1.2),(2,'id2',2000000,13,1.22)])

转化成为DataFrame的RDD

In [13]: rdd2 = rdd1.toDF()# 会耗费比较长的时间In [14]: rdd2.collect()
Out[14]:
[Row(_1=1, _2=u'id1', _3=100000, _4=12, _5=1.2),
 Row(_1=2, _2=u'id2', _3=2000000, _4=13, _5=1.22)]

In [15]: rdd2.show()
+---+---+-------+---+----+| _1| _2|     _3| _4|  _5|+---+---+-------+---+----+|  1|id1| 100000| 12| 1.2||  2|id2|2000000| 13|1.22|+---+---+-------+---+----+

In [18]: rdd2.filter("_3 > 100000").show()
+---+---+-------+---+----+| _1| _2|     _3| _4|  _5|+---+---+-------+---+----+|  2|id2|2000000| 13|1.22|+---+---+-------+---+----+# 可以修改别名,貌似只有一次改的?In [34]: rdd2.withColumnRenamed("_2","name_string").withColumnRenamed("_3","money_bigint")
Out[34]: DataFrame[_1: bigint, name_string: string, money_bigint: bigint, _4: bigint, _5: double]# 尝试在toDF的时候就写好名字In [41]: rdd3 = rdd1.toDF(["id_int","name_string","money_bigint","age_double","tall_float"])

In [42]: rdd3.write.jdbc("jdbc:mysql://xxxx/test", "testalltype", "overwrite", {"
    ...: user":"", "password":""})    
# 查看mysql> select * from testalltype;
+--------+-------------+--------------+------------+------------+| id_int | name_string | money_bigint | age_double | tall_float |+--------+-------------+--------------+------------+------------+|      2 | id2         |      2000000 |         13 |       1.22 ||      1 | id1         |       100000 |         12 |        1.2 |+--------+-------------+--------------+------------+------------+2 rows in set (0.00 sec)# 插入语句可以用append,使用另一种方法创建dataframeIn [48]: newline = [(932,'Alice', 1929291,2,22.92)]
In [51]: rdd4 = sqlContext.createDataFrame(newline,['id_int','name
    ...: _string','money_bigint','age_double','tall_float'])

In [52]: rdd4.show()
+------+-----------+------------+----------+-----------+|id_int|name_string|money_bigint|age_double|tall_float|+------+-----------+------------+----------+-----------+|   932|      Alice|     1929291|         2|      22.92|+------+-----------+------------+----------+-----------+


In [55]: rdd4.write.jdbc("jdbc:mysql://xxxx/test","t
    ...: estalltype","append",{"user":"","password":"
    ...: "})# 查看mysql> select * from testalltype;
+--------+-------------+--------------+------------+------------+| id_int | name_string | money_bigint | age_double | tall_float |+--------+-------------+--------------+------------+------------+|      2 | id2         |      2000000 |         13 |       1.22 ||      1 | id1         |       100000 |         12 |        1.2 ||    932 | Alice       |      1929291 |          2 |       22.92 |+--------+-------------+--------------+------------+-------------+##############使用pyspark+jdbc将本地csv存储到mysql###########In [1]: datapath = "dataform.csv"In [2]: with open(datapath) as f:
   ...:     k = 1
   ...:     parallelizelist = []
   ...:     for line in f.readlines():
   ...:         linesplit = line.strip().split("|")
   ...:         tuple_data = tuple(linesplit)
   ...:         if k == 1:
   ...:             tuple_title = linesplit
   ...:         else:
   ...:             parallelizelist.append(tuple_data)
   ...:
   ...:         k +=1# 方法1:sqlContext.createDataFrameIn [3]: rdd3 = sqlContext.createDataFrame(parallelizelist,tuple_title)

In [4]: rdd3.write.jdbc("jdbc:mysql://xxxx/test","testallty
   ...: pe","overwrite",{"user":"","password":"
   ...: "})# 方法2:toDFIn [8]: rdd4 = sc.parallelize(parallelizelist)

In [9]: rdd5 = rdd4.toDF(tuple_title)

In [10]: rdd5.write.jdbc("jdbc:mysql://xxxx/test","testallt
    ...: ype","append",{"user":"","password":""
    ...: })

Spark对Hive表操作

首先理解下什么是SparkContext, SQLContext 和HiveContext,原文可参考@pig2--让你真正理解什么是SparkContext, SQLContext 和HiveContext这位版主很厉害!这里简单总结下

  • SparkContext:用于连接Spark集群、创建RDD、累加器(accumlator)、广播变量(broadcast variables),所以说SparkContext为Spark程序的根,你只要知道它能让一个普通的列表编程rdd就行了,非常牛逼,就是传说中的sc!

  • SparkSQL:是spark的一个模块,是spark的一个模块,SparkSQL 用来处理结构化数据,所以SparkSQL你的data必须定义schema.在spark1.3.1,sparksql继承dataframes 和SQL 查询引擎

    • SQLContext:spark处理结构化数据的入口。允许创建DataFrame以及sql查询

    • HiveContext:spark sql执行引擎,集成hive数据

In [68]: from pyspark.sql import HiveContext,Row

In [69]: hiveCtx = HiveContext(sc)

In [70]: rows = hiveCtx.sql("SELECT * FROM test.table1 limit
    ...: 5")

In [71]: firstRow = rows.first()
[Stage 32:=====> 
[Stage 32:========>
[Stage 32:==========>
[Stage 32:=============>
[Stage 32:================>
[Stage 32:==================>
[Stage 32:=====================>
[Stage 32:======================>
In [72]: print firstRow.business_id
257

In [73]: print firstRow.order_id
3057564118


In [74]: hiveowntest = HiveContext(sc)

In [75]: rows2 = hiveowntest.sql("SELECT * FROM test.owntest")

In [76]: rows2.show()
+--------+---+
|    name|age|
+--------+---+
|shangsan| 20|
|    lisi| 22|
|  zhouwu| 21|
+--------+---+# 保存入表,其实就是讲hive表读入RDD,然后再写入新的hive表中In [79]: rows2.saveAsTable("hive_test_spark")# 然后进入hive中进行操作,虽然有点错误,单还是可以执行查询动作hive> select * from hive_test_spark;OK
hive_test_spark.name    hive_test_spark.age
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
shangsan    20
lisi    22
zhouwu  21hive> select * from hive_test_spark where name="shangsan";OK
hive_test_spark.name    hive_test_spark.age
shangsan    20
Time taken: 0.645 seconds, Fetched: 1 row(s)



作者:mrlevo520
链接:https://www.jianshu.com/p/a3bb01cc4622

转载请注明出处:http://blog.csdn.net/MrLevo520/article/details/76087612


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消