YARN的架构
YARN的执行流程
MapReduce
处理数据流程图
Hadoop Streaming 实现word count
Mapper.py
Reducer.py
1 . cat xxx.txt|python3 mapper.py|sort|python3 reducer.py
hadoop-streaming会主动将map的输出数据进行字典排序
2 . run.sh:通过Hadoop Streaming 提交作业到Hadoop集群
HADOOP_CMD="/hadoop_home/bin/hadoop" #hadoop安装路径
STREAM_JAR_PATH="/hadoop_home/share/hadoop/tools/lib/hadoop-streaming-2.6.0-cdh5.7.0.jar" # hadoop streaming jar包所在位置
INPUT_FILE_PATH="/xxx.txt" #要进行词频统计的文档在hdfs中的路径
OUTPUT_PATH="/output" #MR作业后结果的存放路径
$HADOOP_CMD fs -rmr -skipTrash $OUTPUT_PATH # 输出路径如果之前存在 先删掉否则会报错
#执行hadoop-streaming进行计算
$HADOOP_CMD jar $STREAM_JAR_PATH\
-D stream.map.output.field.separator=\t\ #表示将map输出的结果按照制表符进行拆分,系统会默认对拆分的数据进行排序
-input $INPUT_FILE_PATH\
-output $OUTPUT_PATH\
-mapper "/usr/local/python3/bin/python3 mapper.py"\
-reducer "/usr/local/python3/bin/python3 reducer.py"\
-file "mapper.py"\
-file "reducer.py"
MRJob实现wordcount
#定义一个类继承MRJob
#定义两个方法:mapper和reducer
python word_count.py -r inline input.txt > output.txt
python word_count.py -r local input.txt > output1.txt
python word_count.py -r hadoop hdfs:///test.txt -o hdfs:///output
MRJob实现topN统计
import sys
from mrjob.job import MRJob,MRStep
import heapq
mapper,combiner,reducer_sum,top_n_reducer#利用heapq将数据进行排序,将最大的2个取出top_n_reducer
#实现steps方法用于指定自定义的mapper,comnbiner和reducer方法
def steps(self):
return [
MRStep(mapper=self.mapper,
combiner=self.combiner,
reducer=self.reducer_sum),
MRStep(reducer=self.top_n_reducer)
]
join文件合并
reducer_opt.py
data_iter = read_line(sys.stdin) #data_iter is iterator,not real data
for key,kviter in groupby(data_iter,itemgetter(0)):
实时流处理框架
Storm
Spark Streaming
Flink
Flume运行机制
Source
Avro Source 序列化数据源
ThriftSource 序列化数据源
Exec Source 执行Linux命令行的数据源
NETCAT Source 通过指定端口,ip监控的数据源
Kafka Source 直接对接Kafka的数据源
自定义Source
Channel
Memory Channel
File Channel
Kafka Channel
JDBC Channel
Sink
HDFS Sink 写入到HDFS
Hive Sink 写入到Hive
Avro Sink 写入到序列化
HBase Sinks 写入到HBase
HBase Sink 同步写入到HBase
Async HBase Sink 异步写入到Hbase
采集指定端口的数据并输出到控制台
netcat
memory
logger
从A服务器采集文件到B服务器
A服务器
exec-source
memory-channel
avro-sink
B服务器
avro-source
memory-channel
logger-sink
采集目录到HDFS
spool-source
memory-channel
hdfs-sink
采集文件到HDFS
exec-source
memory-channel
hdfs-sink
A|B---->C
A|B
exec
memory
avro
C
avro-source
memory-channel
hdfs-sink
启动Flume
conf/flume-ng agent -c conf -f conf/test.conf -n a1 -Dflume.root.logger=INFO,console
-c conf 指定 flume 自身的配置文件所在目录
-f conf/netcat-logger.con 指定我们所描述的采集方案
-n a1 指定我们这个 agent 的名字
Kafka
发布订阅模型则是一个基于推送的消息传送模型。发布订阅模型可以有多种不同的订阅者,临时订阅者只在主动监听主题时才接收消息,而持久订阅者则监听主题的所有消息,即使当前订阅者不可用,处于离线状态。
kafka-server-start.sh config/server.properties
Kafa python API
创建producer
1,命令行方式:普通的发送方式
2,命令行方式:发送json字符串
3,命令行方式:发送普通字符串
from kafka import KafkaProducer
from kafka import KafkaConsumer
Flume和kafka整合
需求:利用flume监听网络端口的数据,通过kafka将flume传递的数据传入到broker中,利用kafka内置的consumer进行数据消费
在flume的conf目录下编辑kafka.conf
netcat
memory
org.apache.flume.sink.kafka.KafkaSink
kafka的整体结构图
spark-core实现wordcount
1.pycharm执行
spark = SparkSession.builder.appName('test').getOrCreate()
sc = spark.sparkContext
words = sc.textFile('file:///root/bigdata/data/spark_test.log') \
.flatMap(lambda line: line.split(" ")) \
.map(lambda x: (x, 1)) \
.reduceByKey(lambda a, b: a + b).collect()
2.系统执行
spark-submit xxx.py
生成RDD
-
从外部文件创建:
sc.textFile(“xxx/xxx.txt”)
sc.textFile(“xxx/xxx.gz”)
sc.textFile(“xxx/xxx/”)
sc.textFile(“hdfs://node-teach:8020/xxx/xxx.log”)
2.集合并行化:把非RDD数据转成RDD:
data=[1,2,3,4,5]
rdd1 = sc.parallelize(data,[numPar])
参数numPar可以定义切片数量,每个切片启动一个task处理任务生成RDD
3.从父RDD生成子RDD
RDD三类算子
Transformation:map,filter,groupBy,reduceBy
rdd1 = sc.parallelize([1,2,3,4,5])
rdd2 = rdd1.map(lambda x:x*2)
rdd3 = rdd2.filter(lambda x:x>3)
rdd3.collect()
rdd1 = sc.parallelize(["a b c","d e f","h i j"])
rdd2 = rdd1.flatMap(lambda x:x.split(" "))
rdd2.collect()
rdd1 = sc.parallelize([("a",1),("b",2)])
rdd2 = sc.parallelize([("c",1),("b",3)])
rdd3 = rdd1.union(rdd2)
rdd3.collect()
rdd4 = rdd1.intersection(rdd2)
rdd4.collect()
rdd1 = sc.parallelize([("a",1),("b",2)])
rdd2 = sc.parallelize([("c",1),("b",3)])
rdd3 = rdd1.union(rdd2)
rdd3.collect()
rdd4 = rdd3.groupByKey()#返回的元组中第1个元素是可迭代对象,需要进一步遍历才能得到结果
rdd4.collect()
rdd1 = sc.parallelize([("a",1),("b",2)])
rdd2 = sc.parallelize([("c",1),("b",3)])
rdd3 = rdd1.union(rdd2)
rdd4 = rdd3.reduceByKey(lambda a,b:a+b)
rdd4.collect()
rdd5 = rdd4.sortByKey(ascending=False)
rdd5.collect()
rdd6 = rdd4.map(lambda x:(x[1],x[0])).sortByKey(ascending=False).map(lambda x:(x[1],x[0]))
rdd6.collect()
Action:count,reduce,saveAsTextFile
rdd1 = sc.parallelize([1,2,3,4,5])
rdd1.reduce(lambda a,b:a+b)
Persistence:
1.cache()方法调用的也是persist方法,缓存策略均为MEMORY_ONLY
2.可以通过persist方法手工设定StorageLevel来满足工程需要的存储级别
spark-core实战
import sys
from pyspark.sql import SparkSession
import datetime
def birth_to_zodiac(birth):
def user_profile(idcard, order_time):
def idcardSplit(x):
spark = SparkSession.builder.appName('user_profile').getOrCreate()
sc = spark.sparkContext
userRDD = sc.textFile(sys.argv[1])
# 将数据进行脱敏
userMaskRDD = userRDD.map(lambda x: idcardSplit(x)).cache()
userProfileRDD = userMaskRDD.filter(lambda x: len(x[0]) > 18).map(lambda x: user_profile(x[0], x[1]))
# 脏数据
dirty_data = userProfileRDD.filter(lambda x: x[1] == 0)
dirty_data.take(0)
cleanRDD = userProfileRDD.filter(lambda x: x[1] > 0)
cleanRDD.saveAsTextFile(sys.argv[2])
sc.stop()