线上执行MapReduce任务计算时,经过排查发现了某些服务器计算的数据出现中文乱码问题,但是服务器的配置是完全一致的。由于我们使用的key可能包含中文,中文乱码问题体现在每次合并map记录的时候计算数据的随机性,每次执行的结果都不一样(由于Map任务执分配的随机性)。
(注:此文章大部分都参考了同事查找到的问题解决方法。)
 
在执行Java进程的过程中,通过命令:jinfo+Java进程号 可以查看java进程运行的一些环境信息,其中也包括-D设置的相关参数。
 
截取的所有信息中,我们比较感兴趣的是下面两行配置:
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}
 
参考了下面一篇文章协助解决这个问题:
 
临时的解决方案,或者将这台服务器执行下线操作,或者将整个集群的mapreduce.admin.map(reduce).child.java.opts设置上加入这两个参数,保证后续所有的MR任务都使用这两个参数。
 
那么问题始终是要找到原因的,于是马上补充一下关于locale的相关知识,下面ubuntu wiki上的内容算是说的比较全面的:
 
执行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个大类:
  • 语言符号及其分类(LC_CTYPE)
  • 数字(LC_NUMERIC)
  • 比较和排序习惯(LC_COLLATE)
  • 时间显示格式(LC_TIME)
  • 货币单位(LC_MONETARY)
  • 信息主要是提示信息,错误信息, 状态信息, 标题, 标签, 按钮和菜单等(LC_MESSAGES)
  • 姓名书写方式(LC_NAME)
  • 地址书写方式(LC_ADDRESS)
  • 电话号码书写方式(LC_TELEPHONE)
  • 度量衡表达方式(LC_MEASUREMENT)
  • 默认纸张尺寸大小(LC_PAPER)
  • 对locale自身包含信息的概述(LC_IDENTIFICATION)。
 
其中的设置又分为相应的优先级,LC_ALL>LC_*>LANG,LC_ALL是最上级设定或者强制设定,而LANG是默认设定值,当前集群中的所有服务器都没有进行这些参数的手动设置。
 
经过检查,发现mac的字符集确实与其他的有所不同,具体可以参考下面这篇文章:
 
其中说到了:
“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
 
 

locale错误导致Java中文乱码错误的总结的更多相关文章

  1. java中文乱码解决之道(一)-----认识字符集

    沉寂了许久(大概有三个多月了吧),LZ"按捺不住"开始写博了! java编码中的中文问题是一个老生常谈的问题了,每次遇到中文乱码LZ要么是按照以前的经验修改,要么则是baidu.c ...

  2. java中文乱码解决之道(二)-----字符编码详解:基础知识 + ASCII + GB**

    在上篇博文(java中文乱码解决之道(一)-----认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述字符集.字符编码等基础知识和ASCII.GB的详情. 一.基 ...

  3. java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**

    原文出处:http://cmsblogs.com/?p=1412 在上篇博文(java中文乱码解决之道(一)—–认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述 ...

  4. java中文乱码解决之道(一)—–认识字符集

    原文出处:http://cmsblogs.com/?p=1395 沉寂了许久(大概有三个多月了吧),LZ“按捺不住”开始写博了! java编码中的中文问题是一个老生常谈的问题了,每次遇到中文乱码LZ要 ...

  5. java中文乱码分析整理

    在JavaWeb应用开发中,经常会出现页面中本该显示中文的地方却是乱码的情况.究其原因,主要是由于在Web组件之间.或Web组件与浏览器.与数据库所使用的字符集标准不统一,Web应用程序运行过程中,中 ...

  6. java中文乱码解决之道(九)-----总结

    乱码,我们前台展示的杀手,可能有些朋友和我的经历一样:遇到乱码先按照自己的经验来解决,如果没有解决就google,运气好一搜就可以解决,运气不好可能够你折腾一番了.LZ之所以写这个系列博客就是因为遇到 ...

  7. java中文乱码解决之道(七)-----JSP页面编码过程

    我们知道JSP页面是需要转换为servlet的,在转换过程中肯定是要进行编码的.在JSP转换为servlet过程中下面一段代码起到至关重要的作用. <%@ page language=" ...

  8. 关于Java中文乱码与日期格式

    关于Java中文乱码与日期格式 Java中文乱码的问题其实很普遍了,首先,一般不会在Windows平台下面出现,同时,一般在Tomcat应用服务器下也都正常,但是到了WebSphere,Weblogi ...

  9. Java中文乱码解决方案

    Java中文乱码解决方案   1.中文乱码解决方案,确保每个文件的默认编码是UTF-8         加入 URIEncoding="UTF-8" 代码中的设置 1>在se ...

随机推荐

  1. AndroidStudio构建常见错误解答解决思路

    一.Error:Configuration with name 'default' not found.解决思路 出现这问题的原因是你依赖的工程没有make project,意思是你导入项目的工程没有 ...

  2. 写给iOS开发者的React Native学习路线(转)

    我是一名iOS开发者,断断续续一年前开始接触React Native,最近由于工作需要,专职学习React Native也有一个多月了.网络上知识资源非常的多,但能让人豁然开朗.迅速学习的还是少数,我 ...

  3. APUE学习笔记——7main()函数启动与退出

    程序的启动与退出过程 先上图,了解进程运行的机制.     内核首先调用exec,运行C启动进程,C启动进程会调用main()函数.     其他所有函数都是由main函数直接或间接调用的.     ...

  4. Linux:tr命令详解

    tr tr命令可以对来自标准输入的字符进行替换.压缩和删除 语法 tr(选项)(SET1 SET2) 选项 -c或——complerment:取代所有不属于第一字符集的字符: -d或——delete: ...

  5. Scala函数式编程——近半年的痛并快乐着

    从9月初啃完那本让人痛不欲生却又欲罢不能的<七周七并发模型>,我差不多销声匿迹了整整4个月.这几个月里,除了忙着讨食,便是继续啃另一本"锯著"--<Scala函数 ...

  6. MySQL开放外部链接

    问题 指令空格 执行命令netstat -nat | grep :3306的时候,注意grep后一定要有空格!!! 该指令的功能为:让服务器接受远程连接.不过这样只能用于本地连接. 真正外部链接详见 ...

  7. Centos kvm+ceph

    Centos kvm+ceph 一. centos6.5 安装kvm 1. disable selinux 2. 确认支持intel虚拟化 3. 安装需要的包 4.设置桥接网络 5.运行kvm ins ...

  8. enum枚举类型的定义

    enum枚举类型的定义方式与某种用法 #include <iostream> using namespace std; int main() { enum TOT{ zero, one, ...

  9. 页面提交 string数组和list对象集合举例

    ajax表单提交   $.ajax({                 cache: true,                 type: "POST",             ...

  10. shell编程--遍历目录下的文件

    假定目录text下有如下文件      目录:dir_1.dir_2.dir_3 文件:text_1.text_2 遍历目录下所有的文件是目录还是文件 if -- if类型: #!bin/sh for ...