###1. 向HDFS写文件时报没有权限
错误信息类似如下:
| 1 2 3 4 5 6 7 8 9 10 11 12
 | Exception in thread "main" org.apache.hadoop.security.AccessControlException: Permission denied: user=Louz, access=WRITE, inode="/test":hduser:supergroup:drwxr-xr-x     at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:234)     at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:214)     at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:158)     at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkPermission(FSNamesystem.java:5185)     ...... Caused by: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException): Permission denied: user=Louz, access=WRITE, inode="/test":hduser:supergroup:drwxr-xr-x     at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:234)     at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:214)     at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:158)     ......
 | 
原因:
这是由于写文件时是以客户端的用户名往hdfs里写的,如果客户端的用户在服务器上不存在或者没有对应目录的权限,所以会报以上的错
解决方法1:
在服务器端给对应的目录赋权,使用hdfs dfs -chmod命令,如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13
 | [hduser@hadoop2 ~]$ hdfs dfs -ls -R / drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:39 /abc drwxr-xr-x   - hduser supergroup          0 2014-05-20 09:29 /pc-demo drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test/folder1 drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test/folder2 [hduser@hadoop2 ~]$ hdfs dfs -chmod -R 777 /pc-demo [hduser@hadoop2 ~]$ hdfs dfs -ls -R / drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:39 /abc drwxrwxrwx   - hduser supergroup          0 2014-05-20 09:29 /pc-demo drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test/folder1 drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test/folder2
 | 
可以看到现在/pc-demo目录权限已经修改成所有人可读写
成功写入的文件权限类似
| 1 2 3 4 5 6 7
 | [hduser@hadoop2 ~]$ hdfs dfs -ls -R / drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:39 /abc drwxrwxrwx   - hduser supergroup          0 2014-05-20 09:34 /pc-demo -rw-r--r--   1 Louz   supergroup          9 2014-05-20 09:34 /pc-demo/demo.txt drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test/folder1 drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test/folder2
 | 
解决方法2:
在服务器端修改hdfs-site.xml文件
| 1 2 3 4 5 6 7 8 9 10 11 12
 | <configuration>   <property>     <name>dfs.replication</name>     <value>1</value>     <description></description>   </property>   <property>     <name>dfs.permissions</name>           <value>false</value>        </property> </configuration>
 | 
重启Hadoop服务,再执行程序,讲文件demo.txt上传至/test目录
| 1 2 3 4 5 6 7 8
 | [hduser@hadoop2 ~]$ hdfs dfs -ls -R / drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:39 /abc drwxrwxrwx   - hduser supergroup          0 2014-05-20 09:34 /pc-demo <- 该目录是通过chmod后,实现可上传文件,目录的权限为所有人可读写 -rw-r--r--   1 Louz   supergroup          9 2014-05-20 09:34 /pc-demo/demo.txt drwxr-xr-x   - hduser supergroup          0 2014-05-20 11:03 /test    <- 该目录是通过修改hdfs-site.xml,实现可上传文件,目录权限为其他人只读 -rw-r--r--   1 Louz   supergroup          9 2014-05-20 11:03 /test/demo.txt drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test/folder1 drwxr-xr-x   - hduser supergroup          0 2014-05-19 16:38 /test/folder2
 | 
###2. windows运行客户端程序时报winutils  not found
问题: 在windows运行MR测试程序时,报类似的错误:
| 1 2 3 4 5
 | 2016-03-11 18:18:30,702 ERROR [main] util.Shell (Shell.java:getWinUtilsPath(374)) - Failed to locate the winutils binary in the hadoop binary path java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.   at org.apache.hadoop.util.Shell.getQualifiedBinPath(Shell.java:356)   at org.apache.hadoop.util.Shell.getWinUtilsPath(Shell.java:371) ......
 | 
解决方法:
步骤一:首先要在环境变量里设置好HADOOP_HOME参数,值为hadoop解压包所在目录,例如我的是:D:\software\hadoop\hadoop-2.7.1
步骤二:需要把winutils.exe文件放到%HADOOP_HOME%\bin目录去,winutils.exe可以在 https://github.com/steveloughran/winutils 下载
步骤三:重启一下IDE
3. 在windows运行客户端的Job报UnsatisfiedLinkError错
问题: 报错信息如下:
| 1 2 3 4 5
 | java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z   at org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Native Method)   at org.apache.hadoop.io.nativeio.NativeIO$Windows.access(NativeIO.java:609)   at org.apache.hadoop.fs.FileUtil.canRead(FileUtil.java:977)
 | 
解决方法:将编译后hadoop的bin目录中的hadoop.dll文件拷贝到%HADOOP_HOME%\bin即可
4. MapReduce程序的Classpath
一般运行MR程序的命令都是
| 1
 | hadoop jar user.jar MainClass .......
 | 
这时候程序的classpath分别有:
- hadoop框架本身的*.jar
- user.jar里的class
- user.jar里lib目录下的*.jar
要注意的是: 如果user.jar是放在hadoop环境的classpath中,那么user.jar依赖的jar包也必须放到hadoop环境的classpath中,不能放在user.jar里的lib目录中;但如果不把user.jar放到hadoop环境的classpath中,则可以将依赖包打到user.jar的lib目录中,原因如下:
- 如果user.jar放在hadoop classpath,那么执行- hadoop jar user.jar MainClass ......
 的时候,user.jar中的class由hadoop的classloader(下面称为- parent classloader)从hadoop classpath中的jar包load进来
 
- 而user.jar中的lib目录下的jar包是在- org.apache.hadoop.util.RunJar的main方法中将user.jar解压到一个临时目录,再创建一个classloader(下面称为- child classloader),将解压后的lib/*.jar加载进来。
 
- 如果user.jar放在hadoop的classpath中,user.jar本身的class由parent classloader加载,其依赖的类则是由child classloader加载,根据JVM的加载模型,parent classloader是不知道child classloader加载的类的,所有此时会报- ClassNotFoundException的错误;
 
- 如果user.jar不放在hadoop的classpath中,user.jar本身的class以及依赖的lib/*.jar都是有child classloader加载,自然能正常运行。 
5. 如何设置只有Mapper的程序
参考文档:http://unmeshasreeveni.blogspot.com/2014/05/map-only-jobs-in-hadoop.html
需要在客户端程序中设置
| 1
 | job.setNumReduceTasks(0);
 | 
这样就不会有reduce阶段,否则会默认使用Identity Reducer进行处理,白白多了shuffle阶段
6. 如何编译hadoop
官方文档
编译后可得出前面提到的winutils.exe、hadoop.dll等文件
| 1 2 3 4 5 6 7 8 9 10 11 12
 | Requirements: * Windows System * JDK 1.6+ * Maven 3.0 or later * Findbugs 1.3.9 (if running findbugs) * ProtocolBuffer 2.5.0 * CMake 2.6 or newer * Windows SDK or Visual Studio 2010 Professional * Unix command-line tools from GnuWin32 or Cygwin: sh, mkdir, rm, cp, tar, gzip * zlib headers (if building native code bindings for zlib) * Internet connection for first build (to fetch all Maven and Hadoop dependencies)
 | 
- 利用VirtualBox或VMWare安装windows,我采用的是VirtualBox + Windows7 32位
- 安装- Windows SDK
 建议下载完整包进行安装,完整包地址
 
- 安装- CMake
 我安装的是- 3.6.2版本
 
- 安装- JDK
 我安装的是- JDK8 update 101,加上- JAVA_HOME环境变量(路径中不能有空格)
 
- 设置- Platform环境变量
 根据目标平台设置该环境变量
 | 1 2
 | set Platform=x64 (when building on a 64-bit system) set Platform=Win32 (when building on a 32-bit system)
 |  
 
- 安装- Maven
 我安装的是- 3.3.9,设置- M2_HOME环境变量,并将- %M2_HOME%\bin加到- PATH环境变量中
 
- 解压- Hadoop源代码
 我使用的是- 2.7.1版本
 
- 安装- Cygwin
 选择- http://mirrors.sohu.com/cygwin这个源,速度比较快。假设安装路径为- C:\cygwin,将- C:\cygwin\bin加入到- PATH环境变量中,以便可以在windows命令行执行- sh等命令
 
- 安装- protobuf
 官方地址,我使用的是- protoc-2.5.0-win32,解压后将目录加入到- PATH变量中
 
- 执行构建
 在- Windos SDK的命令行执行以下命令:
 | 1 2
 | cd %HADOOP_HOME% mvn package -Pdist -Dmaven.javadoc.skip=true -DskipTests
 |