本文对安装Hadoop进行学习。
Network Topology
Hadoop cluster architecture通常包含two-level network topology,如下所示。每个rack通常包含30-40个机器,使用10GB的switch进行交互,rack之间使用core switch或router进行交互。
![a0ac5b38bd686661bf21bb705039f844.png](https://i-blog.csdnimg.cn/blog_migrate/13d7ecf9ee29d85a2a7b4094f662a225.jpeg)
Hadoop为了获得最大的性能,需要配置使其知道cluster的网络拓扑。当存在多个rack时,需要映射rack和node,这样,Hadoop在分配task和data replica到node时就能考虑性能和可靠性。Java interface DNSToSwitchMapping用来指定node和network location的映射,其默认实现ScriptBasedMapping使用user-defined的脚本来获取mapping,脚本地址使用属性net.topology.script.file.name来指定。当不存在脚本文件时,将所有node映射到/default-rack。
Cluster setup and Installation
Hadoop可以运行在unix和windows OS,但都需要安装Java。
最好创建unix user hdfs, mapred, yarn来分别处理HDFS,MapReduce和YARN,这些user都属于hadoop group。
下载hadoop后,执行下面操作来安装hadoop.
$cd /usr/local
$sudo tar xzf hadoop-x.y.z.tar.gz
$sudo chown -R hadoop:hadoop hadoop-x.y.z
$ export HADOOP_HOME=/usr/local/hadoop-x.y.z
$ export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
Hadoop需要做集群级别的操作,因此需要ssh到集群中的所有node。hdfs和yarn用户需要设置SSH来实现无需输入密码的登录集群中的机器。最简单的方法是生成公钥/私钥对,将其放在集群都能访问的NFS位置,将公钥存放在所有机器的~/.ssh/authorized_keys文件。然后使用ssh-agent和ssh-add来实现不用输入密码。
# 使用rsa算法来生成公私钥,私钥存放在~/.ssh/id_rsa,公钥存放在~/.ssh/id_rsa.pub
$ ssh-keygen -t rsa -f ~/.ssh/id_rsa
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Hadoop中提供脚本来启动和停止darmons,这些脚本存放在sbin目录中。slaves文件记录cluster中的所有machine,slaves文件的位置使用hadoop-env.sh中的HADOOP_SLAVES来指定。
HDFS daemons通过执行下面脚本来启动。该脚本通过命令hdfs getconf -namenodes来发现namenode的主机名,在这些主机上启动namenode并在slaves文件指定的所有主机上启动datanode,在所有secondarynamenodes主机上启动secondary namenode。
$ start-dfs.sh
YARN daemons通过下面脚本启动。该脚本在运行脚本的local machine上启动resource manager并在slaves文件中的所有机器上启动node manager。
$ start-yarn.sh
MapReduce daemon - job history server通过下面的脚本启动,用户为mapred。
$ mr-jobhistory-daemon.sh start historyserver
Hadoop cluster运行起来后,需要创建user dir来给用户赋予权限。
$ hadoop fs -mkdir /user/username
$ hadoop fs -chown username:username /user/username
# 限制用户在该user dir中最多使用1TB的空间
$ hdfs dfsadmin -setSpaceQuota 1t /user/username
Hadoop Configuration
Hadoop使用很多配置文件来进行配置,下面是一些比较重要的配置文件。这些文件存放在HADOOP_CONF_DIR指定路径的子路径etc/hadoop中。
![3d08ed98c6c33c5ab6ff0a2c7eef04d6.png](https://i-blog.csdnimg.cn/blog_migrate/2be6b738484cf5a2176a1b6bb1360fbf.jpeg)
Hadoop并不具有single global的位置来存放配置信息。集群中的每个node都存在自己的配置文件集,需要管理员确保这些配置文件是一致的。
hadoop-env.sh中的JAVA_HOME用来确定Java的位置,若没有设置,使用系统变量JAVA_HOME. 默认,Hadoop为每个daemon分配1000MB的内存空间,可用HADOOP_HEAPSIZE来设置。HADOOP_LOG_DIR用来指定存放system logfiles的位置,默认为$HADOOP_HOME/logs,推荐设置在global的位置来存放日志文件。
查看运行daemon的真实configuration,可通过访问web server的/conf来查看,如:http://resource-manager-host:8088/conf来查看resource manager的配置。
-HDFS
为了运行HDFS,至少需要一个机器来作为namenode,使用core-site.xml中的fs.defaultFS来指定使用的默认filesystem,若是hdfs会指定namenode的hostname或ip,其端口号为listen on的端口号,默认为8020。
<?xml version="1.0"?>
下面是hdfs-site.xml的简单示例。
<?xml version="1.0"?>
dfs.namenode.name.dir指定namenode存放filesystem metadata的目录位置,会在指定的多个目录中存放相同的数据来实现冗余数据备份;dfs.namenode.data.dir指定datanode存放block的目录,需要为每个local disk指定目录,数据只会存放在其中一个(round-robins)。dfs.namenode.checkpoint.dir指定secondary namenode存放checkpoint的位置,冗余存放。
-YARN
YARN中必须指定一个machine为resource manager,使用yarn.resourcemanager.hostname来指定该machine的hostname或IP。MapReduce Job会将中间数据和working files存放在临时的local files中,这些数据作为map tasks的输出可能会很大,使用yarn.nodemanager.local-dirs来指定位置,这些位置被round-robin使用。
yarn.nodemanager.resource.memory-mb指定可分配给containers的物理内存大小;yarn.nodemanager.vmem-pmem-ratio可分配给container的虚拟内存和物理内存的比例;yarn.nodemanager.resource.cpu-vcores指定可分配给container的cpu核数。
Hadoop daemons通常运行RPC server来在daemons之间进行通信,并运行HTTP server为用户提供web pages。
Hadoop自身并不管理user credential,它依赖于Kerberos来对user进行认证。但Kerberos并不管理权限。Hadoop来管理user的具有的权限。通过设置core-site.xml中的hadoop.security.authentication为kerberos来使用kerberos作为认证手段,并设置hadoop.security.authorization为true来启动service级别的权限控制。
Kerberos的认证过程可以简化为下图。
![3a2e4a1d64e54913f630bc1fff769227.png](https://i-blog.csdnimg.cn/blog_migrate/bbea1bdff651fbf500341d044cde0ead.jpeg)
分布式系统中存在很多client-server交互,若每次都用kerberos认证,效率会很低。Hadoop使用delegation tokens来允许后续的认证访问。解释:第一次使用RPC call来访问namenode时,client没有delegation token,使用kerberos进行认证,namenode在response中返回delegation token。后续访问,client执行携带token即可。
Hadoop管理
-HDFS
作为Hadoop管理员,很有必要知道HDFS怎么在disk上存储数据。
下面是namenode的目录。其中,VERSION用来存放HDFS的版本信息;in_use.lock为lock文件,用来lock storage dir以阻止其他namenode instance来操作相同的storage dir。
![4d9a803904313fe75d7209478e1ee5a5.png](https://i-blog.csdnimg.cn/blog_migrate/d17cb05516a3497361dbadb761ff3f3a.png)
当filesystem client执行write操作时,transaction先记录在edit log中,之后记录到namenode的in-memory filesystem metadata中。In memory metadata被read request使用。每个edit log以edits开头,拼接transaction的id范围,表示其记录的transaction范围。任何时候只有一个edit log被使用,edits_inprogress_*。当namenode存在多个目录记录filesystem metadata时,记录必须sync到所有目录之后才返回success。
fsimage文件是filesystem metadata的complete persistent checkpoint。恢复namenode时,只需要加载最新的fsimage,然后执行edit log中记录的之后的所有transaction即可。
由于namenode重启时会将最新的fsimage加载进内存,并依次执行edit log中的transation来获得最新的状态。在此期间,namenode不可以使用。为了缩减重启的时间,增加secondary namenode,用来将edit log中的transaction在最新的fsimage上生成更新的fsimage。过程展示如下。
![f707ae8139cd263145fe0a51e4ed1630.png](https://i-blog.csdnimg.cn/blog_migrate/abf181a0cdb57d3d73d4cc3ca44850f2.jpeg)
下面是datanode directory structure。HDFS blocks存放在文件blk_*中,每个block有一个关联的metadata文件*.meta。每个block属于block pool,每个block pool都有自己的storage dir。当每个dir中的block增长到dfs.datanode.numblocks(默认64)指定的数量便创建新的dir来存放。
![39f24430ef66afb98965aabf6362ab24.png](https://i-blog.csdnimg.cn/blog_migrate/a06468c6ea64933f61a9ae6c54dcda9c.png)
当namenode启动时,加载fsimage到内存并apply edit log中的每个edit来创建新的fsimage,这个过程中,client只能读,为safe mode。
HDFS可以log所有的filesystem access requests,默认情况下被disabled。可以通过在hadoop-env.sh中如下设置来开启。Audit log被记录在hdfs-audit.log中。
export HDFS_AUDIT_LOGGER="INFO,RFAAUDIT"
HDFS中提供一些工具。dfsadmin用来获取HDFS的状态并执行admin操作。fsck用来检查HDFS上文件的health。
# fsck寻找组成文件的block
$ hdfs fsck /user/tom/part-00007 -files -blocks -racks
balancer为Hadoop daemon,在遵循block replica placement policy的情况下重新部署block,使得block在datanode上均匀存放。