class="java">file.encoding = ANSI_X3.4-1968 sun.jnu.encoding = ANSI_X3.4-1968? ? 而其他DataNode上MR进程的相关配置,按照常理来说,这个错误是不应该发生的。
sun.jnu.encoding = UTF-8 file.encoding = UTF-8? ? 考虑到出问题的那台机器在某天重启过,定位在某次重启时执行的环境问题。执行 ?
java -Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8 ${mainClass}
?
? 参考了下面一篇文章协助解决这个问题: http://happygiraffe.net/blog/2009/09/24/java-platform-encoding/ ? 临时的解决方案,或者将这台服务器执行下线操作,或者将整个集群的mapreduce.admin.map(reduce).child.java.opts设置上加入这两个参数,保证后续所有的MR任务都使用这两个参数。 ? 那么问题始终是要找到原因的,于是马上补充一下关于locale的相关知识,下面ubuntu wiki上的内容算是说的比较全面的: http://wiki.ubuntu.org.cn/Locale ? 执行locale命令,可以得出所有的locale信息(本机的环境并没有问题,ssh到服务器上执行出来的结果也正确):LANG="zh_CN.UTF-8" LC_COLLATE="zh_CN.UTF-8" LC_CTYPE="zh_CN.UTF-8" LC_MESSAGES="zh_CN.UTF-8" LC_MONETARY="zh_CN.UTF-8" LC_NUMERIC="zh_CN.UTF-8" LC_TIME="zh_CN.UTF-8" LC_ALL=? ? 按照wiki的说明,总共分为12个大类:
“Mac OSX uses a special kind of decomposed UTF-8 to store filenames. If you need to read in filenames and write them to a ‘normal’ UTF-8 file, you must normalize them. My understanding of this is that when you pass a name with an accented character like é, it will decompose this into e plus ’ before saving it to the filesystem (this behavior is defined by the Unicode standard).”? ? 我们的远程服务器并没有显示地指定LC_*参数,那么就会出现本机登陆的相关locale信息被带到远程服务器上。由于Mac中如果没有设置默认则为:
LC_CTYPE=UTF-8? ? 这个参数会被带到相关的服务器节点中,服务器的操作系统为CentOS,而在CentOS中并没有UTF-8这个值,可以被设置为zh_CN.UTF-8或者en_US.UTF-8这两种类型,而Mac上的UTF-8是无效的。 ? 而Java虚拟机在启动的时候,会根据LC_CTYPE来决定sun.jnu.encoding和file.encoding的设置,由于Mac带过来的设置是非法的,导致这两个值被设置成:ANSI_X3.4-1968,这也是其他两个mac用户亲身实践得到的经验(Mac用户的优越感造就了一个大坑…),哈哈。 ? 最后,通过手动改变服务器启动加载的配置文件/etc/profile,强制显示地设置locale参数来Fix这个问题,这也是比较推荐的方式(相对于改变java参数来说)。
export LANG=en_US.UTF-8 export LC_CTYPE=en_US.UTF-8 export LC_NUMERIC=en_US.UTF-8 export LC_TIME=en_US.UTF-8 export LC_COLLATE=en_US.UTF-8 export LC_MONETARY=en_US.UTF-8 export LC_MESSAGES=en_US.UTF-8 export LC_PAPER=en_US.UTF-8 export LC_NAME=en_US.UTF-8 export LC_ADDRESS=en_US.UTF-8 export LC_TELEPHONE=en_US.UTF-8 export LC_MEASUREMENT=en_US.UTF-8 export LC_IDENTIFICATION=en_US.UTF-8 export LC_ALL=en_US.UTF-8