写入elasticsearch时,Spark不支持arraylist吗?

时间:2015-07-14 15:15:17

标签: hadoop elasticsearch apache-spark

我有以下结构:

mylist = [{"key1":"val1"}, {"key2":"val2"}]
myrdd = value_counts.map(lambda item: ('key', { 
    'field': somelist 
}))

我收到错误: 15/02/10 15:54:08 INFO scheduler.TaskSetManager:执行器上的阶段2.0(TID 6)中丢失的任务1.0 ip-10-80-15-145.ec2.internal:org.apache.spark.SparkException(Data类型java.util.ArrayList不能使用)[duplicate 1]

rdd.saveAsNewAPIHadoopFile( 
            path='-', 
            outputFormatClass="org.elasticsearch.hadoop.mr.EsOutputFormat", 
            keyClass="org.apache.hadoop.io.NullWritable", 
            valueClass="org.elasticsearch.hadoop.mr.LinkedMapWritable", 
            conf={ 
        "es.nodes" : "localhost", 
        "es.port" : "9200", 
        "es.resource" : "mboyd/mboydtype" 
    }) 

我希望文档在写入ES时最终结束:

{
field:[{"key1":"val1"}, {"key2":"val2"}]
}

3 个答案:

答案 0 :(得分:3)

刚出现这个问题,解决办法将所有列表转换为元组。 转换为json也是如此。

答案 1 :(得分:3)

我觉得其他答案还缺少一些要点,例如您必须从RDD返回一个2元组(我不知道为什么),并且还需要Elasticsearch hadoop jar文件才能使其正常工作。因此,我将写出必须执行的整个过程。

  1. 下载Elasticsearch Hadoop jar文件。您可以从central maven repository下载它(最新版本在大多数情况下应该可用-请查看其official requirements README了解更多信息。)

  2. 使用以下用于演示的最小代码段创建文件run.py

    import json
    
    import pymongo_spark
    pymongo_spark.activate()
    
    from pyspark import SparkContext, SparkConf
    conf = SparkConf().setAppName('demo').setMaster('local')
    sc = SparkContext(conf=conf)
    
    rdd = sc.parallelize([{"key1": ["val1", "val2"]}])
    final_rdd = rdd.map(json.dumps).map(lambda x: ('key', x))
    
    final_rdd.saveAsNewAPIHadoopFile(
        path='-',
        outputFormatClass="org.elasticsearch.hadoop.mr.EsOutputFormat",
        keyClass="org.apache.hadoop.io.NullWritable",
        valueClass="org.elasticsearch.hadoop.mr.LinkedMapWritable",
        conf={
            "es.nodes" : "<server-ip>",
            "es.port" : "9200",
            "es.resource" : "index_name/doc_type_name",
            "es.input.json": "true"
        }
    )
    
  3. 使用以下命令./bin/spark-submit --jars /path/to/your/jar/file/elasticsearch-hadoop-5.6.4.jar --driver-class-path /path/to/you/jar/file/elasticsearch-hadoop-5.6.4.jar --master yarn /path/to/your/run/file/run.py

  4. 运行Spark作业

HTH!

答案 2 :(得分:2)

比赛有点晚了,但这是我们昨天参加比赛后想出来的解决方案。将'es.input.json': 'true'添加到您的配置中,然后对您的数据运行json.dumps()

修改您的示例,如下所示:

import json

rdd = sc.parallelize([{"key1": ["val1", "val2"]}])
json_rdd = rdd.map(json.dumps)
json_rdd.saveAsNewAPIHadoopFile( 
    path='-', 
    outputFormatClass="org.elasticsearch.hadoop.mr.EsOutputFormat", 
    keyClass="org.apache.hadoop.io.NullWritable", 
    valueClass="org.elasticsearch.hadoop.mr.LinkedMapWritable", 
    conf={ 
        "es.nodes" : "localhost", 
        "es.port" : "9200", 
        "es.resource" : "mboyd/mboydtype",
        "es.input.json": "true"
    }
)