apache-spark - Spark:日文字母在 HDFS 中创建的 Paquet 文件中出现乱码
问题描述
我有一个 Spark 作业,它在 S3 上读取一些 CSV 文件,处理并将结果保存为镶木地板文件。这些 CSV 包含日语文本。
当我在本地运行此作业,读取 S3 CSV 文件并将镶木地板文件写入本地文件夹时,日文字母看起来不错。
但是当我在我的 spark 集群上运行它,读取相同的 S3 CSV 文件并将 parquet 写入 HDFS 时,所有的日文字母都是乱码。
在 spark-cluster 上运行(数据乱码)
spark-submit --master spark://spark-master-stg:7077 \
--conf spark.sql.session.timeZone=UTC \
--conf spark.driver.extraJavaOptions="-Ddatabase=dev_mall -Dtable=table_base_TEST -DtimestampColumn=time_stamp -DpartitionColumns= -Dyear=-1 -Dmonth=-1 -DcolRenameMap= -DpartitionByYearMonth=true -DaddSpdbCols=false -DconvertTimeDateCols=true -Ds3AccessKey=xxxxx -Ds3SecretKey=yyyy -Ds3BasePath=s3a://bucket/export/e2e-test -Ds3Endpoint=http://s3.url -DhdfsBasePath=hdfs://nameservice1/tmp/encoding-test -DaddSpdbCols=false" \
--name Teradata_export_test_ash \
--class com.mycompany.data.spark.job.TeradataNormalTableJob \
--deploy-mode client \
https://artifactory.maven-it.com/spdb-mvn-release/com.mycompany.data/teradata-spark_2.11/0.1/teradata-spark_2.11-0.1-assembly.jar
在本地运行(数据看起来不错)
spark-submit --master local \
--conf spark.sql.session.timeZone=UTC \
--conf spark.driver.extraJavaOptions="-Ddatabase=dev_mall -Dtable=table_base_TEST -DtimestampColumn=time_stamp -DpartitionColumns= -Dyear=-1 -Dmonth=-1 -DcolRenameMap= -DpartitionByYearMonth=true -DaddSpdbCols=false -DconvertTimeDateCols=true -Ds3AccessKey=xxxxx -Ds3SecretKey=yyyy -Ds3BasePath=s3a://bucket/export/e2e-test -Ds3Endpoint=http://s3.url -DhdfsBasePath=/tmp/encoding-test -DaddSpdbCols=false" \
--name Teradata_export_test_ash \
--class com.mycompany.data.spark.job.TeradataNormalTableJob \
--deploy-mode client \
https://artifactory.maven-it.com/spdb-mvn-release/com.mycompany.data/teradata-spark_2.11/0.1/teradata-spark_2.11-0.1-assembly.jar
从上面可以看出,两个 spark-submit 作业都指向同一个 S3 文件,不同的是在 Spark 集群上运行时,结果是写入 HDFS。
读取 CSV:
def readTeradataCSV(schema: StructType, path: String) : DataFrame = {
dataFrameReader.option("delimiter", "\u0001")
.option("header", "false")
.option("inferSchema", "false")
.option("multiLine","true")
.option("encoding", "UTF-8")
.option("charset", "UTF-8")
.schema(schema)
.csv(path)
}
这就是我写镶木地板的方式:
finalDf.write
.format("parquet")
.mode(SaveMode.Append)
.option("path", hdfsTablePath)
.option("encoding", "UTF-8")
.option("charset", "UTF-8")
.partitionBy(parCols: _*)
.save()
有关如何解决此问题的任何提示?
输入 CSV 文件是否必须采用 UTF-8 编码?
**更新** 发现它与 Parquet 无关,而是 CSV 加载。在这里问了一个单独的问题:
解决方案
Parquet 格式没有用于encoding
或charset
cf的选项。https://github.com/apache/spark/blob/branch-2.4/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/parquet/ParquetOptions.scala
因此,您的代码无效:
finalDf.write
.format("parquet")
.option("encoding", "UTF-8")
.option("charset", "UTF-8")
(...)
这些选项仅适用于 CSV,您应该在读取源文件时设置它们(或者更确切地说是其中之一,因为它们是同义词) 。
假设您使用 Spark 数据帧 API 来读取 CSV;否则你就靠自己了。
推荐阅读
- pyspark - pyspark 数据帧上的复杂逻辑,包括前一行现有值以及动态生成的前一行值
- flutter - 处理手势时引发了以下断言: Scaffold.of() 使用不包含 Scaffold 的上下文调用
- javascript - HubSpot 嵌入式表单 - 将标签移动到输入中断表单下方
- scala - 使用字符串插值进行模式匹配
- spacy - 如何迫使 spacy 将“史密斯先生”和“史密斯夫人”识别为独立的实体
- python - 使用Python在不同的矩阵元素中使用不同的颜色
- java - org.powermock.reflect.exceptions.FieldNotFoundException
- ruby-on-rails - 尝试为我的项目运行测试时,我的堆栈级别一直太深
- java - 使用 JPA 进行 SUM 运算
- angular - 将参数传递给 ngOnChanges?