spark-sql中文字符使用问题

本文档展示了在Spark SQL环境中处理中文字符的步骤,包括确认文本文件的UTF-8编码,设置正确的客户端语言环境(如`en_US.UTF-8`),以及在遇到乱码问题时如何排查和解决,如通过`iconv`命令转码和调整终端字符显示设置。

所有涉及数据源显示都涉及原始数据的字符集编码和客户端语言环境的设置。

那么在spark-sql环境,只要正确的字符集编码和正确的客户端语言环境设置,显示,使用中文,完全不是困难。

#上传的文本文件编码,确认是utf8

[root@slave2 test]# cat city_test.txt
浙江,杭州,300
浙江,宁波,150
浙江,温州,200
浙江,嘉兴,100
江苏,南京,270
江苏,苏州,299
江苏,某市,200
江苏,某某市,100
[root@slave2 test]# file city_test.txt
city_test.txt: UTF-8 Unicode text

[root@slave2 test]# echo $LANG
en_US.UTF-8
[root@slave2 test]#

##############

[root@snn spark]# echo $LANG
en_US.UTF-8

[root@snn spark]# which spark-sql
/opt/hadoop/spark-latest/bin/spark-sql
[root@snn spark]# /opt/hadoop/spark-latest/bin/spark-sql
15/12/20 13:37:35 WARN MetricsSystem: Using default name DAGScheduler for source because spark.app.id is not set.
SET hive.support.sql11.reserved.keywords=false
15/12/20 13:38:56 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
SET spark.sql.hive.version=1.2.1
SET spark.sql.hive.version=1.2.1
spark-sql> show tables;
external_2000w  false
external_2000w_new      false
external_bz2_tbl_6005   false
external_tar_gz_tbl_6005        false
external_tbl_6005       false
hive_user_info  false
pcp     false
pcp2    false
pcp2_16787      false
sqoop_test      false
tbl_6005        false
test_table_16538        false
test_table_16539        false
Time taken: 3.543 seconds, Fetched 13 row(s)
spark-sql> select * from pcp2;
浙江    杭州    300
浙江    宁波    150
浙江    温州    200
浙江    嘉兴    100
江苏    南京    270
江苏    苏州    299
江苏    某市    200
江苏    某某市  100
Time taken: 17.689 seconds, Fetched 8 row(s)

spark-sql>

#########################################################

有时候需要转码,比如大量文件已经是GBK编码,那么iconv命令是可以转码的。

有时候发现转码后,file <文件名> 命令看到已经改了编码,下载到windows下看,也能看。

这就说明,文本编码已经好了,但是由于显示终端的字符设置不对,导致显示乱码,修改终端的字符显示即可。

为了测试,我把一个文件转成集中编码,设置不同的环境设置进行显示。






### Spark SQL 中解决 `'ascii' codec can't encode characters` 错误的方法 在 Spark SQL 中遇到 `'ascii' codec can't encode characters in position 4027-4033: ordinal not in range(128)` 的错误通常是由于数据中存在非 ASCII 字符,而默认编码未能正确处理这些字符所致。以下是几种有效的解决方案: --- #### 方案一:设置 JVM 默认编码为 UTF-8 Spark 是基于 Java 构建的,因此其内部依赖于 JVM 的默认编码。可以通过启动 Spark 应用时设置 `-Dfile.encoding=UTF-8` 来更改 JVM 的默认编码: ```bash export SPARK_SUBMIT_OPTIONS="--conf spark.executor.extraJavaOptions=-Dfile.encoding=UTF-8 --conf spark.driver.extraJavaOptions=-Dfile.encoding=UTF-8" spark-submit your_script.py ``` 这样可以确保整个 Spark 应用程序及其 executor 均使用 UTF-8 编码[^1]。 --- #### 方案二:在 PySpark 中手动重置编码 如果仅限于 PySpark 环境下的问题,可以在脚本开头显式地重新设置 Python 的默认编码(尽管此方法不推荐用于生产环境): ```python import sys reload(sys) # 需要导入 reload 函数 sys.setdefaultencoding("utf-8") # 设置默认编码为 UTF-8 ``` 需要注意的是,这种做法可能会带来潜在的风险,尤其是在复杂的应用环境中[^3]。 --- #### 方案三:调整 DataFrame 展示逻辑 当调用 `DataFrame.show()` 方法展示数据时容易触发该类错误。为了避免这一情况,可以选择禁用自动截断功能或者自定义显示方式: ```python df.select("*").foreach(lambda row: print(row)) # 自定义打印函数代替 show() ``` 此外还可以通过以下配置减少每列宽度以降低风险: ```python spark.conf.set("spark.sql.repl.eagerEval.maxNumRows", "100") spark.conf.set("spark.sql.repl.eagerEval.truncate", "false") ``` --- #### 方案四:清洗源数据中的非法字符 从根本上解决问题的最佳办法是对原始数据进行预处理,移除或替换其中无法被 ASCII 表达的内容。例如,在加载 CSV 文件之前先做一轮过滤: ```python from pyspark.sql.functions import col, regexp_replace cleaned_df = df.withColumn("column_name", regexp_replace(col("column_name"), "[^\\x00-\\x7F]", "")) ``` 这段代码利用正则表达式将所有超出 ASCII 范围内的字符替换成空白字符串[^1]。 --- #### 方案五:升级 Scikit-Learn 版本 (若有相关依赖) 有时类似的编码问题可能是由第三方库版本差异引起。比如某个 pickle 文件是在较新版本 scikit-learn 下保存的模型对象,而在较低版本环境下加载就会发生兼容性冲突。此时应当统一各节点上的软件版本号,并清除残留的老版缓存文件以防干扰[^2]。 --- ### 总结 综上所述,面对 Spark SQL 场景下出现的 `'ascii' codec can't encode characters` 类型异常,可以从多个角度入手排查并修复。首选建议是从根本层面改善数据质量以及合理配置运行参数;其次才是借助临时手段规避症状表现。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值