###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
|