spark-sql读写elasticsearch的坑

// 写elasticsearch的代码
ds.write
      .format("org.elasticsearch.spark.sql")
      .option("es.nodes.wan.only", "true")
      .option("es.mapping.id", "_id")
      .option("es.mapping.exclude", "_id")
      .option("es.nodes", host)
      .option("es.port", port)
      .option("es.update.script.lang","painless")
      .option("es.update.script.inline",script)  // es.update.script.inline 6.0以及之后的版本
      .option("es.update.script.params", params)
      .option("es.write.operation", "upsert")
      .option("es.batch.write.retry.count", 3)
      .option("es.update.retry.on.conflict", 3)
      .option("es.mapping.exclude", "_id")
      .mode("append")
      .save(index_name)
// 读取elasticsearch的代码配置
val ds = spark.read
      .format("org.elasticsearch.spark.sql")
      .option("es.read.metadata", "true") // 读取元数据信息
      .option("es.read.metadata.field", "_metadata")
      .option("es.nodes.wan.only","true") // 公网的时候必传
      .option("pushdown", "true")
      .option("es.port",port)
      .option("es.net.ssl","false")
      .option("es.nodes", host)
      .option("query", query) // 传入查询的dsl语句
      .option("es.read.field.include", includeField) // 读取数据的时候可以在这个进行字段筛选
      .option("es.read.field.as.array.include", arrIncludeField) // 在读取数组的时候需要加这个参数,否则无法识别
      .option("es.mapping.date.rich", "false")
      .load(index_name)

1、es.nodes.wan.only

如果运行的spark程序和你的elasitcsearch是在同一个网段的时候,不加这个是没有问题的。但是如果不在同一个网段比如是在公网上面的话,则会报请求失败的错误。

2、es.update.retry.on.conflict

如果是并发更新的时候,如果是更新到同一条记录上的时候则会报冲突,所以要设置这个参数

3、es.update.script.inline

elasticsear的spark插件在6.0版本之前是es.update.script这个参数,由于我自己用的是5.x的版本所以用的是es.update.script参数,但是这里在更新嵌套类型的数据结构的时候会报无法转成scala.tuple2的错误,只需要使用es.update.script.inline这个参数就能解决,但是使用这个参数在更新es7.0的时候还是会报这个错误:https://discuss.elastic.co/t/upsert-nested-fields-with-spark/128813

附上spark on elasticsearch的配置项链接:https://www.elastic.co/guide/en/elasticsearch/hadoop/current/configuration.html

4、spark-sql的udf里面获取广播变量的问题

今天碰到一个类似于:https://segmentfault.com/q/1010000008010132这个的问题,在udf里面调用广播变量的value获取值一直报空指针,后来在udf的类里面 将广播变量作为成员变量获取到了。由于udf的函数的类文件会分发到各个excutor节点上进行调用所以构造好的广播变量的成员变量在各个executor上也能顺利获取到。

你可能感兴趣的:(spark-sql读写elasticsearch的坑)