1. RDD創建
spark core
從文件讀取
>>> lines = sc.textFile("file:///user/data_path") # local
Scala> val lines = sc.textFile("hdfs://localhost:9000/user/data_path") # from hdfs
>>> lines.foreach(print)
通過並行集合創建
array = [1,2,3,4,5]
rdd = sc.parallelize(array)
rdd.foreach(print)
2. RDD 操作
轉換操作
filter(),map(),flatMap(),groupByKey(),reduceByKey(func)
每次轉換操作生成新的RDD惰性機制
操作 | 含義 |
filter() | 篩選滿足條件的元素返回一個新的數據集 |
map() | 每個元素map到新的元素返回一個新的數據集 |
flatMap() | 與map()相似但是每個輸入元素都可以映射到或多個結果 |
groupByKey() | 應用於(K,V)對應的數據集,返回一個新的(K,Iterable)的數據集 |
reduceByKey(func) | 應用於(K,V)對應的數據集,返回一個新的(K,V)形式的數據集每個值是將每個key傳遞到函數func中進行聚合的結果 |
1. filter()
linesWithSpark = lines.filter(lambda line:"Spark" in line)
2.map()
data = [1,2,3,4,5]
rdd1 = sc.parallelize(data)
rdd2 = rdd1.map(lambda x:x+10)
rdd2.foreach(print)
3.flatMap()
# RDD(lines) -> RDD(word array) -> RDD(words)
words = lines.flatMap(lambda line:lines.split(" "))
4.groupByKey
words=sc.parallelize([("Hadoop",1),("is",1),("is",1)])
words1=words.groupByKey()
words1.foreach(print)
# result:
# ('Hadoop',<pyspark.resultiterable.ResultIterable object at 0x7fb210552c88>)
# ('is',<pyspark.resultiterable.ResultIterable object at 0x7fb210552c88>)
5.reduceByKey
words=sc.parallelize([("Hadoop",1),("is",1),("is",1)])
words1=words.reduceByKey(lambda a,b:a+b)
words1.foreach(print)
# result:
# ('Hadoop',1)
# ('is',2)
首先執行了groupByKey操作,然後運用reduce函數進行了計算
行動操作
count(),collect(),first(),take(n),reduce(func),foreach(func)
rdd = sc.parallelize([1,2,3,4,5])
rdd.count()
# 5
rdd.first()
# 1
rdd.take(3)
# [1,2,3]
rdd.reduce(lambda a,b:a+b)
# 15
rdd.collect()
# [1,2,3,4,5]
rdd.foreach(lambda elem:print(elem))
# 1
# 2
# 3
# 4
# 5
3. 持久化
persist()對一個RDD標記爲持久化在行動操作以後實現真正持久化保留在緩存中之後還可以繼續利用
.persist(MEMORY_ONLY/MEMORY_AND_DISK ) == RDD.cache()
.unpersist 從內存裏刪除
list = ['Hadoop','spark']
rdd = sc.parallelize(list)
rdd.cache() # 暫時並不會緩存,這時候rdd還沒有被計算生成
print(rdd.count()) # 第一次行動操作,觸發一次真正從頭到尾的計算,這時候rdd.cahche()纔會被實行,把這個rdd放到緩存裏
# 2
print(','.join(rdd.collect ())) # 第二次行動操作,不需要從頭到尾的計算,只需要重複使用上面緩存中的rdd
# Hadoop,spark
4. RDD 分區
分區的好處增加並行度 2.減少通信開銷(表連接消耗減少)
分區個數 =集羣種CPU的個數
Spark.default.parallelism
list = [1,2,3,4,5]
rdd = sc.parallelize(list,2)
#也可以用repartition重新分區
自定義分區方法
from pyspark import SparkConf,SparkContext
def MyPartitioner(key):
return %10
def main():
conf = SparkConf().setMaster('local').setAppName('MyApp')
sc = SparkContext(conf = conf)
data = sc.parallelize(range(10),5)
data.map(lambda x:(x,1))\
.partitionBy(10,MyPartitioner)\
.map(lambda x:x[0])\
.saveAsTextFile("file:///user/rdd")
if __name__ == '__main__':
main()
運行
$ cd /user/rdd
$ python3 TestPartitioner.py
5. 鍵值RDD創建
(key,vaule)形式:
讀文件/並行集合等方法來建立RDD
lines = sc.textFile('files:///user/local/spark/word.txt')
pairRDD = lines.flatMap(lambda line:line.split(" ")).map(lambda word:(word,1))
pairRDD.foreach(print)
# ('I',1)
# ('Hadoop',1)
常用RDD轉換操作
groupByKey vs. reduceByKey
groupByKey對每個key進行操作,只生成一個seq,本身不能定義函數,需要先用groupByKey生成RDD,然後通過map進行自定義函數操作; reduceByKey對於每個key對應的多個value進行merge操作,可以在本地進行merge操作,並且merge操作可以通過函數自定義。
# using reduceByKey
words = ['one','two','two']
wordPairRDD = sc.parallelize(words).map(lambda word:(word,1))
wordCountsWithReduce = wordPairRDD.reduceByKey(lambda a,b:a+b)
wordCountsWithReduce.foreach(print)
# ('one',1)
# ('two',2)
# using groupByKey
wordCountsWithGroup = wordPairRDD.groupByKey().map(lambda t:(t[0],sum(t[1])))
wordCountsWithGroup.foreach(print)
# ('one',1)
# ('two',2)
keys:把pairRDD中的key返回形成一個新的RDD
value:把pairRDD中的value返回形成一個新的RDD
sortByKey():排序
mapValues(func):只對value進行func操作
join:join by key
6. 數據讀寫
一. 本地文件系統/分佈式文件系統HDFS
# 本地
textFile = sc.textFile("files:///user/local/word.txt")
textFile.first()
saveAsTextFile("file:///user/rdd/writeback")
# HDFS
textFile = sc.textFile("hdfs://user/hadoop/word.txt")
textFile = sc.textFile("/user/hadoop/word.txt")
textFile = sc.textFile("word.txt")
saveAsTextFile("writeback")
二. HBase 讀寫
HBsase簡介
HBase 是一種列式的分佈式數據庫,是由當年的 Google 公佈的 BigTable 的論文而生。不過這裏也要注意 HBase 底層依舊依賴 HDFS 來作爲其物理存儲。
關係數據庫:按行存儲;而HBase按單元格保存。
表: 表由行與列組成
行: 每個行有row key唯一標識
列族: 每個列族有多個列
列限定符:列族裏的數據通過列限定符來定位
時間戳:每個單元格都保存則同一份數據的多個版本,採用時間戳進行索引
單元格:行/列族/列限定符 確定一個單元格,數據沒有數據類型,字節數byte
四維定位:行+列族+列限定符+時間戳 -> 數據
存儲原理:把表格分割成多個單元格在不同電腦上存儲
創建一個HBase表
# 啓動hadoop
$cd /user/local/hadoop
$./sbin/start-all.sh
#啓動HBase
$cd user/local/hbase
$./bin/start-hbase.sh //啓動HBase
$./bin/hbase shell //啓動hbase shell
創建表
hbase> create 'student','info'
hbase> put 'student','1','info:name','Xueqian'
hbase> put 'student','1','info:gender','F'
hbase> put 'student','1','info:age','23'
# put '表名稱', 'row key','column name','value'