通过检查点加入DStream和RDD

时间:2018-09-03 07:21:53

标签: python-3.x apache-spark pyspark rdd dstream

我一直在努力在DStream和RDD之间执行联接。设置场景:

  • 火花-2.3.1
  • Python-3.6.3

RDD

我正在从CSV文件中读取RDD,拆分记录并生成一对RDD。

sku_prices = sc.textFile("sku-catalog.csv")\
    .map(lambda line: line.split(","))\
    .map(lambda fields: (fields[0], float(fields[1])))

这是sku_prices.collect()的输出:

[('0003003001', 19.25),
 ('0001017002', 2.25),
 ('0001017003', 3.5),
 ('0003013001', 18.75),
 ('0004017002', 16.5),
 ('0002008001', 2.25),
 ('0004002001', 10.75),
 ('0005020002', 10.5),
 ('0001004002', 3.5),
 ('0002016003', 14.25)]

DStream

我正在从Kafka中读取DStream。

orders = kstream.map(lambda n: n[1]).map(lambda n: json.loads(n))

items = orders.map(lambda order: order['items'])\
              .flatMap(lambda items: [(i['sku'], i['count']) for i in items])\
              .reduceByKey(lambda x, y: x + y)

当我在pprint()上运行orders时,得到的输出如下:

-------------------------------------------
Time: 2018-09-03 06:57:20
-------------------------------------------
('0004002001', 3)
('0002016003', 1)
('0003013001', 1)

加入

现在,我想将items DStream加入到sku_prices RDD中。我知道我不能直接进行联接,但是我的阅读建议我可以在DStream上使用transform()方法来完成这项工作。这就是我所拥有的:

items.transform(lambda rdd: rdd.join(sku_prices)).pprint()

我希望获得一个看起来像这样的DStream:

-------------------------------------------
Time: 2018-09-03 06:57:20
-------------------------------------------
('0004002001', (3, 10.75))
('0002016003', (1, 14.25))
('0003013001', (1, 18.75))

Spark documentation建议这样做应该起作用,并且确实起作用:结果正是我所得到的! :)

检查点

但是我也想做一个有状态的操作,所以我需要引入检查点。

ssc.checkpoint("checkpoint")

仅添加检查点会导致在transform()上出现此错误:

  

您似乎正在尝试广播RDD或引用   动作或变换的RDD。 RDD转换和动作   只能由驱动程序调用,不能在其他内部调用   转变;例如rdd1.map(lambda x:rdd2.values.count()*   x)无效,因为值转换和计数操作   不能在rdd1.map转换内部执行。

this thread的答案表明检查点和外部RDD不能混合使用。有没有解决的办法?当StreamingContext启用检查点功能时,是否可以加入DStream和RDD?

谢谢, 安德鲁。

0 个答案:

没有答案