在网上找了很久python的Kafka+sparkstreaming+elasticsearch的代码找不到,基本都是scala或者java的(好像是spark自己本身提供了库给java和scala写入ES?然而并没有可以提供给python的😓),所以自己写了一个,能正常运行,但是感觉这样写不太好,想发出来和大家交流一下。
from elasticsearch import Elasticsearch
from pyspark.streaming import StreamingContext
from pyspark.sql.session import SparkSession
from pyspark.sql import SQLContext
from pyspark.streaming.kafka import KafkaUtils
import os
os.environ['JAVA_HOME'] = "/usr/local/java/bin"
es = Elasticsearch(['Master:9200'])
# 创建传入Es的数据
def create_send_data(lines):
for rec in lines:
es_dict = {}
es_dict['timestamp'] = rec[0:10]
es_dict['user_id'] = rec[10:14]
es_dict['lat'] = rec[14:23]
es_dict['lng'] = rec[23:32]
es_dict['gps_timestamp'] = rec[32:42]
es_dict['angle'] = rec[42:45]
es.index(index="user_point", doc_type="test", body=es_dict)
# 处理从Kafka接收到的数据
def Dstream_opt(ssc):
topic = "test0210"
#创建direct连接,指定要连接的topic和broker地址
ks = KafkaUtils.createDirectStream(ssc,[topic],{"metadata.broker.list":"Master:9092"})
ks.pprint()
#以下代码每操作一次,就打印输出一次
lines = ks.map(lambda x:x[1])
# lines.pprint()
return lines
if __name__ == '__main__':
# 创建SparkContext
print("========================创建spark=========================")
spark = SparkSession.builder.master("local[2]").getOrCreate()
sc = spark.sparkContext
ssc = StreamingContext(sc, 3)
sqlContext = SQLContext(sc)
# 获得接收到的Dstream
lines = Dstream_opt(ssc)
lines.pprint()
lines.foreachRDD(lambda rdd: rdd.foreachPartition(create_send_data))
ssc.start()
#等待计算结束
ssc.awaitTermination()
这套代码提交到spark集群中是可以正常运行的,其实就是将发过来的一串数字,剪切之后再存入ES,登录进Kibana也是可以查到存进去的数据的。