python+sparkStreaming+kafka之大数据实时流

首先需要的是环境,我安装的是spark2…1,kafka0-10,hadoop2.7,scala2.11,因为spark是Scala语言写的,所以这个必须的安装,大数据传输存储需要用到Hadoop,HDFS,所以Hadoop需要安装,streaming接受流数据源有两种大的方式,一种是文件和套接字,直接读取文件和通过套接字传输,另一种是高级API形式,可以通过额外的实用程序类获得诸如Kafka,Flume,Kinesis等,这里用kafka。可参见官方文档(在此建议kafka安装版本不要太高,太高会有很多报错),环境安装好之后还需要一个下载一个依赖包,spark-stream-kafka-0.10_2.11-2.1.0.jar,下载地址,这里2.11是Scala版本,2.1.0是spark版本,0-10是kafka版本,下载的时候要看清楚自己的版本,然后下载编译包spark-streaming-kafka-0-10-assembly_2.11-2.1.1,选择中央地址,下载地址,下载完之后两个都放到spark/jars目录下,这样依赖与环境就都配置好了。
启动Hadoop,HDFS,在根目录下输入,等待逐步启动

start-all.sh

之后启动kafka,先启动zookeeper,进入kafka安装目录输入

bin/zookeeper-server-start.sh config/zookeeper.properties

启动kafka

bin/kafka-server-start.sh config/server.properties

创建一个test主题

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

查看创建的主题

kafka-topics.sh --describe --zookeeper localhost:2181 --topic test

用python编码流数据处理代码,这里用两种方式
第一种套接字形式(官方例子,此方式不必启动kafka服务)

import sys

from pyspark import SparkContext
from pyspark.streaming import StreamingContext


if __name__ == "__main__":

    if len(sys.argv) != 3:
        print("Usage: network_wordcount.py  ", file=sys.stderr)
        sys.exit(-1)
    sc = SparkContext(appName="PythonStreamingNetworkWordCount")
    ssc = StreamingContext(sc, 1)

    lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))
    counts = lines.flatMap(lambda line: line.split(" "))\
                  .map(lambda word: (word, 1))\
                  .reduceByKey(lambda a, b: a+b)
    counts.pprint()
    ssc.start()
    ssc.awaitTermination()

然后进入spark目录下执行

./bin/spark-submit ~/Desktop/wordcount.py localhost 9999

打开另一个终端输入

nc -lk 9999

之后就可以输入内容,上面处理的功能是按照空格切分统计词频。
第二种方式,kafkaAPI

#-- coding: UTF-8 --
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
from pyspark.streaming.kafka import KafkaUtils

#设置使用两个线程,设置程序的名字为KafkaWordCount
sc=SparkContext("local[*]","KafkaWordCount")

#处理时间间隔为2s
ssc=StreamingContext(sc,2)

#设置zookeeper
# zookeeper="192.168.23.200:2181,192.168.23.201:2181,192.168.23.202:2181"

#设置要监听的主题
topic={"test":0,"test":1,"test":2}

#在/user/kafka/config/consumer.properties 查看groupid="test-consumer-group"
groupids="test"

'''
构造函数为KafkaUtils.createDstream(ssc, [zk], [consumer group id], [per-topic,partitions] )
使用了receivers来接收数据,利用的是Kafka高层次的消费者api,
对于所有的receivers接收到的数据将会保存在spark executors中,
然后通过Spark Streaming启动job来处理这些数据,默认会丢失,可启用WAL日志,该日志存储在HDFS上

直接方法(无接收者)
createDirectStream必须要传的参数有ssc,topic(主题,列表格式),kafka参数
基于接受者的方式
createStream必须接收的参数ssc,zkQuorum(要接收的服务地址,集群的话多个写在一起),/
/groupid(分组,这个可以自己定义),topic(主题dict格式,数字代表分区且都在自己的线程中进行),

两者比较,基于接受者的方式可能会发生数据丢失,为防止丢失,需要启用预写日志,将kafka数据写入HDFS的日志中
直接方法的优点
简化的并行性:无需创建多个输入Kafka流并将它们合并。Spark Streaming将创建与要使用的Kafka分区/
/一样多的RDD分区,所有这些分区都将从Kafka并行读取数据。因此,Kafka和RDD分区之间存在一对一的映射,/
/这更易于理解和调整。

效率:为了实现零数据丢失,第一种方法要求将数据存储在预写日志中,该日志进一步复制了数据。/
/这实际上是低效的,因为数据被有效地复制了两次-一次是通过Kafka复制,另一次是通过“预写日志”复制。/
/第二种方法消除了该问题,因为没有接收器,因此不需要预写日志。只要您有足够的Kafka保留时间,/
/就可以从Kafka中恢复邮件。

一次语义:第一种方法使用Kafka的高级API将消耗的偏移量存储在Zookeeper中。传统上,这是从Kafka消费数据的方式。/
/尽管这种方法(与预写日志结合使用)可以确保零数据丢失(即至少一次语义),但在某些故障下,/
/某些记录可能会被消耗两次,这是很小的机会。发生这种情况是由于Spark Streaming可靠接收的数据/
/与Zookeeper跟踪的偏移量之间存在不一致。因此,在第二种方法中,我们使用不使用Zookeeper的简单Kafka API。/
/Spark Streaming在其检查点内跟踪偏移。这样可以消除Spark Streaming与Zookeeper 、 Kafka之间的不一致,/
/因此即使出现故障,Spark Streaming也会有效地一次接收每条记录。为了实现一次语义精确的结果输出。

具体课参考官方文档:https://spark.apache.org/docs/latest/streaming-kafka-0-8-integration.html
'''
# 直接方法(无接收者)
#lines=KafkaUtils.createDirectStream(ssc, ['test'], {'metadata.broker.list': 'localhost:9092'})
# 基于接受者的方式
lines = KafkaUtils.createStream(ssc, 'localhost:2181', 'test', topic)
lines_map=lines.map(lambda x:x[1])

#对两秒内接收到的数据按空格分割
words=lines_map.flatMap(lambda line:line.split(" "))

#映射为(word,1)元组
pairs=words.map(lambda word:(word,1))

#每一行相同的key相加
wordcounts=pairs.reduceByKey(lambda x,y:x+y)

#输出保存到文件,前缀+自动加日期
wordcounts.saveAsTextFiles("/pythonwork/PythonProject/sparkStreaming/log")

wordcounts.pprint()

#启动spark streaming
ssc.start()

#等待计算终止
ssc.awaitTermination()

我的在这里写入文件的时候有点问题,待我再研究研究。
进入kafka安装目录,创建生产者

bin/kafka-console-producer.sh --broker-list localst:9092 --topic test

之后进入wordcount.py目录执行

/usr/local/spark/bin/spark-submit --jars /usr/local/spark/jars/spark-streaming-kafka-0-8-assembly_2.11-2.1.1.jar wordcount2.py

就可以看到每隔两秒就会输出时间,然后在创建生产者界面输入内容,就可以看到输出

参考文章
https://blog.csdn.net/qq_41562377/article/details/89603578
http://dblab.xmu.edu.cn/blog/2373/
https://www.cnblogs.com/zhumengke/articles/10553284.html
官方文档spark编程指南
streaming+kafka集成指南
pyspark streamingAPI文档

你可能感兴趣的:(虚拟机+大数据)