06Hadoop Federation联邦

0 阅读5分钟

Hadoop Federation联邦

Federation背景介绍

image.png

从上图中,我们可以很明显地看出现有的HDFS数据管理,数据存储2层分层的结构。也就是说,所有关于存储数据的信息和管理是放在NameNode这边,而真实数据的存储则是在各个DataNode下。而这些隶属于同一个NameNode,所管理的数据都是在同一个命名空间下的“NS”,以上结构是一个NameNode管理集群中所有元数据信息。

举个例子,一般1GB内存放1,000,000 block元数据。200个节点的集群中每个节点有24TB存储空间,block大小为128MB,能存储大概4千万个block(或更多):200*24*1024*1024/128 约为4千万。100万需要1G内存存储元数据,4千万大概需要40G内存存储元数据,假设节点数如果更多、存储数据更多的情况下,需要的内存也就越多。

通过以上例子可以看出,单NameNode的架构使得 HDFS 在集群扩展性和性能上都有潜在的问题,当集群大到一定程度后,NameNode进程使用的内存可能会达到上百G,NameNode 成为了性能的瓶颈。这时该怎么办?元数据空间依然还是在不断增大,一味调高NameNode的JVM大小绝对不是一个持久的办法,这时候就诞生了 HDFS Federation 的机制。

HDFS Federation是解决namenode内存瓶颈问题的水平横向扩展方案。Federation中文意思为联邦、联盟,HDFS Federation是NameNode的Federation,也就是会有多个NameNode。这些 namenode之间是联合的,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。分布式的datanode被用作通用的数据块存储设备。每个datanode要向集群中所有的namenode注册,且周期性地向所有 namenode 发送心跳和块报告,并执行来自所有 namenode的命令。

image.png

  1. NameNode节点之间是相互独立的联邦的关系,即它们之间不需要协调服务
  2. DataNode向集群中所有的NameNode注册,发送心跳和block块列表报告,处理来自NameNode的指令
  3. 用户可以使用ViewFs创建个性化的命名空间视图,ViewFs类似于在Unix/Linux系统中的客户端挂载表

联邦机制就是:元数据分治,复用DN存储;元数据访问隔离;DN目录隔离block

Federation搭建

ipCPU内存硬盘角色主机名
192.168.91.212C2G40GBNamenodenode01
192.168.91.222C2G40GBNamenode、DataNodenode02
192.168.91.232C2G40GBSecondaryNameNode、DataNodenode03
192.168.91.242C2G40GBSecondaryNameNode、DataNodenode04
# 所有节点

# hosts 配置
cat >> /etc/hosts << "EOF"
192.168.91.21  node01
192.168.91.22  node02
192.168.91.23  node03
192.168.91.24  node04
EOF

# JDK安装
wget https://builds.openlogic.com/downloadJDK/openlogic-openjdk/8u392-b08/openlogic-openjdk-8u392-b08-linux-x64.tar.gz
tar xf openlogic-openjdk-8u392-b08-linux-x64.tar.gz
mv openlogic-openjdk-8u392-b08-linux-x64 /usr/local/jdk8
rm -f openlogic-openjdk-8u392-b08-linux-x64.tar.gz
echo 'export JAVA_HOME=/usr/local/jdk8' >> /etc/profile
echo 'export PATH=$PATH:${JAVA_HOME}/bin' >> /etc/profile
source /etc/profile

# 关闭防火墙
systemctl stop firewalld && systemctl disable firewalld

# 关闭selinux
sed -ri 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0

# 时间同步配置,最小化安装系统需要安装ntpdate软件
yum -y install ntpdate
echo "0 */1 * * * ntpdate time1.aliyun.com" >> /var/spool/cron/root
systemctl enable ntpdate && systemctl start ntpdate

# 生成密钥并拷贝到node01节点
ssh-keygen -t rsa -P '' -f  ~/.ssh/id_rsa
ssh-copy-id node01
# node01

# 将node01节点上的authorized_keys文件复制到node02、node03、node04节点上
scp ~/.ssh/authorized_keys node02:~/.ssh
scp ~/.ssh/authorized_keys node03:~/.ssh
scp ~/.ssh/authorized_keys node04:~/.ssh

# hadoop部署
wget https://dlcdn.apache.org/hadoop/common/hadoop-3.2.4/hadoop-3.2.4.tar.gz
tar xf hadoop-3.2.4.tar.gz
chown -R root:root hadoop-3.2.4
mv hadoop-3.2.4 /usr/local/hadoop-3.2.4
echo 'export HADOOP_HOME=/usr/local/hadoop-3.2.4' >> /etc/profile
echo 'export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin' >> /etc/profile
source /etc/profile

# hadoop配置

# hadoop-env.sh脚本中JAVA_HOME配置
sed -i 's%# export JAVA_HOME=%export JAVA_HOME=/usr/local/jdk8%' $HADOOP_HOME/etc/hadoop/hadoop-env.sh
# datanode节点配置
cat > $HADOOP_HOME/etc/hadoop/workers << "EOF"
node02
node03
node04
EOF
# start-dfs.sh和stop-dfs.sh脚本中用户配置
cat > user_tmp.txt << EOF
HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
EOF
sed -i '17r user_tmp.txt' $HADOOP_HOME/sbin/start-dfs.sh
sed -i '17r user_tmp.txt' $HADOOP_HOME/sbin/stop-dfs.sh
rm -f user_tmp.txt

# core-site.xml和hdfs-site.xml配置文件如下所示

$HADOOP_HOME/etc/hadoop/core-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <!--设置挂载表名称为ClusterX-->
  <property>
    <name>fs.defaultFS</name>
    <value>viewfs://ClusterX</value>
  </property>
  <!--ClusterX挂载表配置,这里配置了data、project、user、tmp四个命名空间-->
  <property>
    <name>fs.viewfs.mounttable.ClusterX.link./data</name>
    <value>hdfs://node01:8020/data</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.ClusterX.link./project</name>
    <value>hdfs://node01:8020/project</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.ClusterX.link./user</name>
    <value>hdfs://node02:8020/user</value>
  </property>
  <property>
    <name>fs.viewfs.mounttable.ClusterX.link./tmp</name>
    <value>hdfs://node02:8020/tmp</value>
  </property>
  <!--所有未在挂载表中配置的命名空间,使用的兜底的命名空间,例如/logs-->    
  <property>
    <name>fs.viewfs.mounttable.ClusterX.linkFallback</name>
    <value>hdfs://node02:8020/home</value>
  </property>
  <!--指定hadoop的临时目录位置-->
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/var/hadooptmp/federation</value>
  </property>
</configuration>

$HADOOP_HOME/etc/hadoop/hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>dfs.replication</name>
    <value>3</value>
  </property>
  <property>
    <name>dfs.blocksize</name>
    <value>1048576</value>
  </property>
  <property>
    <name>dfs.nameservices</name>
    <value>ns1,ns2</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.ns1</name>
    <value>node01:8020</value>
  </property>
  <property>
    <name>dfs.namenode.http-address.ns1</name>
    <value>node01:50070</value>
  </property>
  <property>
    <name>dfs.namenode.secondary.http-address.ns1</name>
    <value>node03:50090</value>
  </property>
  <property>
    <name>dfs.namenode.rpc-address.ns2</name>
    <value>node02:8020</value>
  </property>
  <property>
    <name>dfs.namenode.http-address.ns2</name>
    <value>node02:50070</value>
  </property>
  <property>
    <name>dfs.namenode.secondary.http-address.ns2</name>
    <value>node04:50090</value>
  </property>
</configuration>
# node01
cd /usr/local
tar -zcvf hadoop-3.2.4-config.tar.gz hadoop-3.2.4/
for i in 2 3 4; do scp hadoop-3.2.4-config.tar.gz node0$i:/usr/local; done
# node02-node04 节点
cd /usr/local
tar xf hadoop-3.2.4-config.tar.gz
rm -f hadoop-3.2.4-config.tar.gz
echo 'export HADOOP_HOME=/usr/local/hadoop-3.2.4' >> /etc/profile
echo 'export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin' >> /etc/profile
source /etc/profile
# 格式化集群
# 在格式化node01和node02上的namenode时候,需要指定clusterId,并且两个格式化的时候这个clusterId要一致,两个namenode具有相同的clusterId,它们在一个集群中,它们是联邦的关系
# node01
$HADOOP_HOME/bin/hdfs namenode -format -clusterId viewfs
# node02
$HADOOP_HOME/bin/hdfs namenode -format -clusterId viewfs

# node01

# 启动集群
$HADOOP_HOME/sbin/start-dfs.sh

# 上传文件测试
# 创建文件夹
hdfs dfs -mkdir -p /mydata
# 上传文件
hdfs dfs -put /usr/local/hadoop-3.2.4-config.tar.gz /mydata
# 查看文件
hdfs dfs -ls /mydata
-rw-r--r--   3 root supergroup  492312858 2024-01-03 09:01 /mydata/hadoop-3.2.4-config.tar.gz
# 通过web页面http://192.168.91.22:50070/explorer.html,可以看到数据在home目录(兜底的命名空间)
# http://192.168.91.21:50070/explorer.html中查看不到数据,说明联邦机制生效了

# 停止集群
$HADOOP_HOME/sbin/stop-dfs.sh

Federation问题

HDFS Federation 并没有完全解决单点故障问题。虽然 namenode/namespace 存在多个,但是从单个namenode/namespace看,仍然存在单点故障:如果某个 namenode 挂掉了,其管理的相应的文件便不可以访问。当然Federation中每个namenode仍然像之前HDFS上实现一样,配有一个secondary namenode,以便主namenode 挂掉重启后,用于还原元数据信息,需要手动将挂掉的namenode重新启动。所以一般集群规模真的很大的时候,会采用HA+Federation 的部署方案。也就是每个联合的namenodes都是HA(High Availablity - 高可用)的