尝试了解火花流媒体工作

时间:2017-02-27 03:58:22

标签: python apache-spark spark-streaming

试图弄清楚如何编写流媒体作业依赖于某些第三方模块和查找表来工作,如下所示:

# custom.py
# this is the 3rd party or user defined python module,
# there're some module-level variables
# and some functions which rely on the moduel-level variables to work
VAR_A = ...
VAR_B = ...


# load external data files to initialize VAR_A and VAR_B
def init_var(external_file):
  with open(external_file, 'r') as f:
    for l in f:
      VAR_A.append(l)
      VAR_B.check(l)
      ....

# relies on VAR_A and VAR_B to work
def process(x):
  if x in VAR_A:
    ...
  if VAR_B.check(x):
    ...

流媒体驱动程序如下,基本上,对于每个rdd,我想通过custom应用process的{​​{1}}函数,但handle函数依赖于一些查找变量可以工作,即processVAR_A,所以我必须在Spark contenxt中明确地广播这些查找变量吗?

VAR_B

如果我必须使用第三方模块,我想知道如何使其工作?

更新

假设带有单词行的实时流输入,例如

# driver.py
import custom

def handle(x):
  ...
  custom = shared.value
  return custom.process(x)


if __name__ == '__main__':
  sc = SparkContext(appName='porn_score_on_name')
  ssc = StreamingContext(sc, 2)

  custom.init('/path/to/external_file')

  # since each task node will use custom, so I try to make it a shared one
  # HOWEVER, this won't work, since module cannot be pickled
  shared = sc.broadcast(custom)

  # get stream data
  data = ...
  processed = data.map(handle)

  # further processing
  ...

  ssc.start()
  ssc.awaitTermination()

我希望在预先计算的词汇表(V)中找到包含单词的行。

所以我有这个想法: 写一个流作业来处理传入的数据,这意味着我有多个并行运行的执行器来使用数据,对于每个执行器,预先计算的词汇表V应该始终可用。 现在问题是我该如何实现呢?

以下是我的主要内容: 我制作了一个包含词汇表和我的自定义代码的zip包,例如: pack.zip,然后我通过word1 word2 word3 word5 word7 word1 ... 提交这个pack.zip,以便这个pack.zip在每个执行器机器上都可用,然后我应该做一些事情让每个执行器从pack.zip加载词汇表到内存中的查找表,现在每个执行程序都可以访问词汇表,这样他们就可以在驱动程序开始运行时正确处理实时流数据。

然而事实证明,上述想法可行,但每个执行者每批次一次又一次地加载词汇表,这是不可接受的。 所以这是我的第二次采取: 我应该在驱动程序中加载词汇表(所以这发生在本地机器上,而不是在执行程序上),然后我将词汇表查找表广播给所有执行程序,然后完成工作。

1 个答案:

答案 0 :(得分:0)

您的示例似乎并不是一个流媒体问题,而是如何加载全局变量......

我不会尝试广播整个模块,只是单独需要的变量。

例如,您应该能够像这样使用广播变量。 (代码未经测试)

# One of the first things you do
vocab = sc.broadcast(open('vocab.txt').readlines())  # broadcast to all executors

def vocab_filter(line):
    words = line.split()
    return [w for w in words if w in vocab.value]

ssc = StreamingContext(sc, 1)  # Some streaming context
lines = ssc.socketTextStream("localhost", 9999)  # Some stream
# remove extraneous words from the lines and flatten all words in the stream
lines_filtered = lines.flatMap(vocab_filter)