zookeeper: marco de coordinación de servicios distribuidos

1. Descripción general de Zookeeper

1. Conceptos básicos de Zookeeper

  • Zookeeper es un proyecto Apache distribuido de código abierto que proporciona servicios de coordinación para aplicaciones distribuidas.
  • Zookeeper se entiende desde la perspectiva del patrón de diseño: es un marco de gestión de servicios distribuidos diseñado en base al patrón de observador, es responsable de almacenar y administrar los datos que interesan a todos y luego acepta el registro de los observadores. Una vez que se conoce el estado de estos cambios de datos, Zookeeper Será responsable de notificar a los observadores registrados en Zookeeper para que respondan en consecuencia, logrando así un modelo de gestión Maestro / Esclavo similar en el clúster.
  • Zookeeper = sistema de archivos + mecanismo de notificación

2. Características de Zookeeper

  • Cuidador del zoológico: un líder y un grupo de seguidores.
  • Leader es responsable de iniciar y tomar decisiones sobre la votación y actualizar el estado del sistema.
  • El seguidor se utiliza para recibir solicitudes de los clientes y devolverle los resultados, y participar en la votación durante la elección del Líder.
  • Mientras más de la mitad de los nodos del grupo sobrevivan, el clúster Zookeeper puede funcionar con normalidad.
  • Coherencia de datos global: cada servidor guarda una copia de los mismos datos y no importa a qué servidor se conecte el cliente, los datos son consistentes.
  • Las solicitudes de actualización se realizan de forma secuencial y las solicitudes de actualización del mismo cliente se ejecutan de forma secuencial en el orden en que se envían.
  • La actualización de datos es atómica, una actualización de datos tiene éxito o falla.
  • En tiempo real, dentro de un cierto rango de tiempo, el cliente puede leer los datos más recientes.

3. Estructura de datos del cuidador del zoológico

  • La estructura del modelo de datos de ZooKeeper es muy similar a la del sistema de archivos Unix: puede considerarse como un árbol en su conjunto y cada nodo se denomina ZNode.
  • El propio clúster Zookeeper mantiene un conjunto de estructuras de datos. Esta estructura de almacenamiento es una estructura de árbol, y cada nodo en ella se llama "znode". A diferencia de los nodos del árbol, el método de referencia de Znode es una referencia de ruta, similar a la ruta del archivo: /znode1/leaf1
  • Esta estructura jerárquica permite que cada nodo de Znode tenga una ruta única, que aísla claramente la información diferente como si fuera un espacio de nombres.
  • Los nodos de ZooKeeper se mantienen a través de una estructura similar a un árbol, y cada nodo está marcado y se accede a él a través de una ruta.
  • Además, cada nodo también tiene parte de su propia información, que incluye: datos, longitud de los datos, hora de creación, hora de modificación, etc.
  • A partir de las características de dicho nodo, que contiene datos y está marcado como una tabla de rutas, se puede ver que un nodo ZooKeeper puede considerarse como un archivo o un directorio, y tiene las características de ambos. Para facilitar la expresión, usaremos Znode para representar el nodo ZooKeeper en cuestión en el futuro.
  • Cada znode puede almacenar 1 MB de datos de forma predeterminada
  • Un znode es creado por el cliente. Su relación intrínseca con el cliente que lo creó determina su existencia. Generalmente, existen cuatro tipos de nodos:
    • PERSISTENTE: nodo persistente : después de que el cliente que creó este nodo se desconecte del servicio zookeeper, este nodo no se eliminará (a menos que se obligue a eliminarlo mediante la API).
    • PERSISTENT_SEQUENTIAL: nodo de número secuencial persistente : cuando el cliente solicita crear este nodo A, el cuidador del zoológico escribirá un número único en todo el directorio para este nodo A según el estado zxid de parent-znode (este número solo seguirá creciendo). Cuando el cliente se desconecta del servicio zookeeper, el nodo no se eliminará.
    • EPHEMERAL-Nodo de directorio temporal : después de que el cliente que creó este nodo se desconecte del servicio del cuidador del zoológico, este nodo (y los nodos secundarios involucrados) se eliminarán.
    • EPHEMERAL_SEQUENTIAL: nodo de directorio de números secuenciales temporales : cuando el cliente solicita la creación de este nodo A, el cuidador del zoológico escribirá un número único en todo el directorio para este nodo A según el estado zxid de parent-znode (este número solo seguirá creciendo). Cuando el cliente que creó el nodo se desconecta del servicio zookeeper, el nodo se elimina.
    • [Nota] : No importa si es un tipo de nodo EPHEMERAL o EPHEMERAL_SEQUENTIAL, el nodo también se eliminará después de que el cliente zookeeper finalice de manera anormal.

2. Instalación e implementación de Zookeeper

1. Descargar Guardián del zoológico

En el sitio web oficial de Zookeeper , seleccione la versión que necesita descargar, la siguiente es la versión que descargué.

imagen-20230914153823247

imagen-20230914154058193

2. Instalación de Zookeeper

Instalación y despliegue en modo local (modo independiente)

Paso 1: Cargue el paquete comprimido descargado en el directorio especificado de la máquina virtual. Lo subí a /opt/software/

Paso 2: Descomprima el paquete comprimido en el directorio especificado. Lo descomprimí en /opt/app/

tar -zxvf apache-zookeeper-3.8.2-bin.tar.gz -C /opt/app/

Paso 3: cambie el nombre de la carpeta del cuidador del zoológico

mv apache-zookeeper-3.8.2-bin/ zookeeper-3.8.2

Paso 4: Configure las variables de entorno y obtenga el archivo de configuración para que surta efecto

vim /etc/profile source /etc/profile

imagen-20230914154523937

Paso 5: Ingrese /opt/app/zookeeper-3.8.2/confal directorio, cambie el nombre del archivo de configuración mv zoo_sample.cfg zoo.cfgy luego edítelo. y /opt/app/zookeeper-3.8.2/crear un nuevo directoriotouch zkData

imagen-20230914154730291

Paso 6: use el comando zkServer.sh startpara iniciar zookeeper, use el comando zkServer.sh statuspara verificar el estado del zookeeper y use el comando netstat -untlppara verificar el número de puerto.

imagen-20230914154925015

imagen-20230914155004720

Paso 7: use el comando zkCli.sh -server localhost:2181para ingresar al cliente

imagen-20230914155112299

zkServer.sh stopPaso 8: salir usando el comando

imagen-20230914155154497

Instalación e implementación distribuida (clúster en modo clúster)

  • Planificación de clusters

    • 在node1、node2、node3三个节点上部署Zookeeper。
      
  • Primero seleccione el nodo nodo1 para descomprimirlo e instalarlo. Los pasos son los mismos que para la instalación e implementación en modo local.

  • Modificar el archivo de configuración zoo.cfg

[root@node1 software]# vim /opt/app/zookeeper/conf/zoo.cfg
#修改dataDir数据目录
dataDir=/opt/module/zookeeper-3.8.2/zkData
#在文件最后增加如下配置
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888

server.A=B:C:D。
A是一个数字,表示这个是第几号服务器;
B是这个服务器的ip地址;
C是这个服务器与集群中的Leader服务器交换信息的端口;
D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
集群模式下配置一个文件myid,这个文件在dataDir目录下,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。

imagen-20230914165158962

  • /opt/app/zookeeper-3.8.2Cree una carpeta en mkdir zkDatay luego ingrese a este directorio para crear un archivo touch myidque defina el número del host actual.
#在配置zoo.cfg的时候配置了server.1/2/3这个配置项中  数字123代表的就是第几号服务器
#其中这个数字必须在zookeeper的zkData的myid文件中定义  并且定义的时候必须和配置项对应的IP相互匹配
[root@node1 zookeeper]# touch /opt/app/zookeeper/zkData/myid
[root@node1 zookeeper]# vim /opt/app/zookeeper/zkData/myid
#文件中写入当前主机对应的数字 然后保存退出即可 例 node1节点的myid写入1   node2节点的myid写入:2   node3节点的myid写入:3

imagen-20230914170134011

  • Copie el guardián del zoológico configurado a otras máquinas

    scp -r /opt/app/zookeeper-3.8.2/ root@node2:/opt/app/
    scp -r /opt/app/zookeeper-3.8.2/ root@node3:/opt/app/
    并分别修改myid文件中内容为2、3
    

imagen-20230914202418214

  • Configure las variables de entorno requeridas por zookeeper en los nodos nodo2 y nodo3.

imagen-20230914202607865

  • Inicie zookeeper por separado y verifique el estado

imagen-20230914203152616

3. El principio de implementación interna de zookeeper.

1. Mecanismo electoral

  • Medio mecanismo (protocolo Paxos): más de la mitad de las máquinas del clúster sobreviven y el clúster está disponible. Por lo tanto, zookeeper es adecuado para su instalación en un número impar de máquinas.
  • Aunque Zookeeper no especifica maestro y esclavo en el archivo de configuración. Sin embargo, cuando trabaja el cuidador del zoológico, un nodo es el líder y los demás son seguidores, y el líder se genera temporalmente a través del mecanismo de elección interna.

1. El mecanismo de elección cuando se inicia Zookeeper por primera vez.

  • Mecanismo de elección interna de Zookeeper

    • Supongamos que hay un clúster de cuidadores del zoológico compuesto por cinco servidores, sus ID varían de 1 a 5. Al mismo tiempo, todos son recién iniciados, es decir, no hay datos históricos y la cantidad de datos almacenados es la misma. Suponiendo que estos servidores se inician secuencialmente, su proceso de implementación interna es como se muestra en la figura

      imagen

      • Se inicia el servidor 1. En este momento solo se inicia un servidor. No hay respuesta a los informes que envía, por lo que su estado de elección siempre está en estado MIRANDO.
      • Se inicia el servidor 2. Se comunica con el servidor 1, que se inició al principio, e intercambia sus propios resultados electorales entre sí. Como ambos no tienen datos históricos, gana el servidor 2 con un valor de ID mayor, pero como más de la mitad de los los servidores no han llegado a Aceptar para elegirlo (más de la mitad de ellos son 3 en este ejemplo), por lo que los servidores 1 y 2 continúan manteniendo el estado MIRANDO.
      • Se inicia el servidor 3. Según el análisis teórico anterior, el servidor 3 se convierte en el líder entre los servidores 1, 2 y 3. La diferencia con lo anterior es que tres servidores lo eligieron en este momento, por lo que se convierte en el líder de esta elección.
      • Se inicia el servidor 4. Según el análisis anterior, teóricamente el servidor 4 debería ser el más grande entre los servidores 1, 2, 3 y 4. Sin embargo, como más de la mitad de los servidores anteriores han elegido el servidor 3, este solo puede recibir el pedido. de ser el hermano menor. .
      • El servidor 5 se inicia y actúa como el hermano menor como el 4.

2. El mecanismo de elección del cuidador del zoológico cuando no se inicia por primera vez.

  • SID: ID del servidor. Se utiliza para identificar de forma única una máquina en el clúster de ZooKeeper. Cada máquina no se puede repetir y es coherente con myid.
  • ZXID: ID de transacción. ZXID es un ID de transacción que se utiliza para identificar un cambio en el estado del servidor. En un momento determinado, es posible que el valor ZXID de cada máquina en el clúster no sea exactamente el mismo, esto está relacionado con la lógica de procesamiento del servidor ZooKeeper para la "solicitud de actualización" del cliente.
  • Época: el nombre en clave de cada término líder. Cuando no hay líder, el valor del reloj lógico en la misma ronda de votación es el mismo. Estos datos aumentarán cada vez que se emita un voto.

elección zk

2. Proceso de escritura de datos de Zookeeper

1. El proceso de escribir el nodo Líder directamente

escribe lider

2. Escribe directamente el proceso de Seguidor.

escribe seguidor

3. Descripción detallada del proceso de escritura de datos.

  • Por ejemplo, el Cliente escribe datos en el Servidor1 de ZooKeeper y envía una solicitud de escritura.
  • Si el Servidor1 no es el Líder, entonces el Servidor1 reenviará la solicitud recibida al Líder, porque uno de cada Servidor ZooKeeper es el Líder. El Líder transmitirá la solicitud de escritura a cada Servidor, como el Servidor1 y el Servidor2. Después de que cada Servidor escriba exitosamente El Líder será notificado.
  • Cuando el Líder recibe la mayoría de los datos del Servidor y los escribe correctamente, significa que los datos se escriben correctamente. Si hay tres nodos aquí, siempre que los datos de dos nodos se escriban correctamente, se considera que los datos se escribieron correctamente. Una vez que la escritura sea exitosa, Leader le informará al Servidor1 que los datos se escribieron exitosamente.
  • El Servidor1 notificará además al Cliente que los datos se escribieron correctamente y luego toda la operación de escritura se considerará exitosa. Todo el proceso de escritura de datos de ZooKeeper es así.

4. Operación de línea de comando del cliente Zookeeper

  • Utilice el comando para conectarse al grupo de cuidadores del zoológicozkCli.sh -server node:2181,node2:2181,node3:2181

1. Sintaxis de la línea de comando

Sintaxis de comando básica Función descriptiva
ayuda Mostrar todos los comandos de operación
ls camino [ver] Utilice el comando ls para ver el contenido del znode actual
ls -s ruta [ver] Ver información del nodo actual
crear [-e] [-s] Crear nodo -s con secuencia -e temporal (reiniciar o desaparecer después del tiempo de espera)
obtener ruta [ver] Obtener el valor de un nodo
colocar Establecer el valor específico del nodo.
estadística Ver el estado del nodo
borrar Eliminar nodo
rmr/eliminar todo Eliminar nodos recursivamente

2. Operaciones básicas de línea de comando

  1. Inicie el cliente de línea de comando

    zkCli.sh -server node1:2181,node2:2181,node3:2181
    

    imagen-20230917155449174

  2. Mostrar todos los comandos de operación

    help
    

    imagen-20230917155652051

    imagen-20230917155719895

  3. Ver información del nodo znode

    ls / 
    

    imagen-20230917155526869

  4. Ver información detallada sobre un nodo en znode

    [zk: node1:2181(CONNECTED) 5] ls -s / 
    [zookeeper]cZxid = 0x0 
    ctime = Thu Jan 01 08:00:00 CST 1970 
    mZxid = 0x0 
    mtime = Thu Jan 01 08:00:00 CST 1970 
    pZxid = 0x0 
    cversion = -1 
    dataVersion = 0 
    aclVersion = 0 
    ephemeralOwner = 0x0 
    dataLength = 0 
    numChildren = 1 
    
     (1)czxid:创建节点的事务 zxid 每次修改 ZooKeeper 状态都会产生一个 ZooKeeper 事务 ID。事务 ID 是 ZooKeeper 中所 有修改总的次序。每次修改都有唯一的 zxid,如果 zxid1 小于 zxid2,那么 zxid1 在 zxid2 之前发生。 
     (2)ctime:znode 被创建的毫秒数(从 1970 年开始) 
     (3)mzxid:znode 最后更新的事务 zxid 
     (4)mtime:znode 最后修改的毫秒数(从 1970 年开始) 
     (5)pZxid:znode 最后更新的子节点 zxid
     (6)cversion:znode 子节点变化号,znode 子节点修改次数 
     (7)dataversion:znode 数据变化号 
     (8)aclVersion:znode 访问控制列表的变化号 
     (9)ephemeralOwner:如果是临时节点,这个是 znode 拥有者的 session id。如果不是 临时节点则是 0。 
     (10)dataLength:znode 的数据长度 
     (11)numChildren:znode 子节点数量
    
  5. Crear un nodo normal (nodo permanente + sin número de serie)

    create /sanguo "weishuwu"
    

    imagen-20230917160623571

  6. Obtener el valor de un nodo

    get -s /test 
    
  7. Crear un nodo con un número de serie (nodo permanente + con un número de serie)

    create  -s  /a
    
    create  -s  /a 
    
    create  /a 
    
    如果原来没有序号节点,序号从 0 开始依次递增。如果原节点下已有 2 个节点,则再排序时从 2 开始,以此类推。
    

    imagen-20230917161532151

  8. Crear un nodo transitorio (nodo efímero + sin número de serie o con número de serie)

     (1)创建短暂的不带序号的节点 
    create -e /b
    
     (2)创建短暂的带序号的节点 
    create -e -s /b
    
     (3)在当前客户端是能查看到的 
    ls /
    
     (4)退出当前客户端然后再重启客户端 
     [zk: node1:2181(CONNECTED) 12] quit 
     [root@node1 zookeeper-3.5.7]$ bin/zkCli.sh 
     (5)再次查看根目录下短暂节点已经删除 
    ls /
    

    imagen-20230917161824546

    imagen-20230917161947604

  9. Modificar el valor de los datos del nodo

    [zk: node1:2181(CONNECTED) 6] set /sanguo/weiguo "simayi"
    
  10. Eliminar nodo

    delete /test
    
  11. Eliminar nodos recursivamente

    deleteall /test
    

    imagen-20230917161321106

  12. Ver el estado del nodo

    stat /sanguo 
    

    imagen-20230917160608475

    13. Monitorear los cambios de datos de los nodos.

    get -w /sanguo
    

    14. Escuche los cambios en los nodos secundarios de un nodo.

    ls -w /sanguo
    

    imagen-20230917161125996

5. Construcción de un clúster HA-Hadoop de alta disponibilidad

1. Descripción general de HA de alta disponibilidad

  • El llamado HA (alta disponibilidad) significa alta disponibilidad (servicio ininterrumpido 7*24 horas).
  • La estrategia más crítica para lograr una alta disponibilidad es eliminar los puntos únicos de falla. Estrictamente hablando, HA debe dividirse en mecanismos de HA para cada componente: HDFS HA ​​y YARN HA.
  • Antes de Hadoop2.0, NameNode tenía un punto único de falla (SPOF) en el clúster HDFS.
  • NameNode afecta principalmente al clúster HDFS en los dos aspectos siguientes:
    • Si ocurre un accidente en la máquina NameNode, como un tiempo de inactividad, el clúster quedará inutilizable hasta que el administrador lo reinicie.
    • La máquina NameNode debe actualizarse, incluidas las actualizaciones de software y hardware, y el clúster no se podrá utilizar en este momento.
  • La función HDFS HA ​​​​resuelve los problemas anteriores configurando dos nameNodes, Activo/En espera, para implementar una copia de seguridad en caliente del NameNode en el clúster. Si ocurre una falla, como una falla de la máquina o la máquina necesita ser actualizada y mantenida, el NameNode se puede cambiar rápidamente a otra máquina de esta manera.

2. Mecanismo de trabajo HDFS-HA: elimine los puntos únicos de falla a través de nodos de nombre duales

  • Puntos de trabajo HDFS-HA

    • Es necesario cambiar los métodos de gestión de metadatos (no se requiere SecondaryNameNode)

      内存中各自保存一份元数据;
      Edits日志只有Active状态的namenode节点可以做写操作;
      两个namenode都可以读取edits;
      共享的edits放在一个共享存储中管理(qjournal和NFS两个主流实现);
      
    • Se requiere un módulo de función de gestión de estado

      实现了一个zkfailover,常驻在每一个namenode所在的节点,每一个zkfailover负责监控自己所在namenode节点,利用zk进行状态标识,当需要进行状态切换时,由zkfailover来负责切换,切换时需要防止brain split现象的发生。
      
    • Se debe garantizar que sea posible iniciar sesión sin contraseña SSH entre los dos NameNodes.

    • Aislamiento (cerca) significa que solo un NameNode proporciona servicios externos al mismo tiempo.

3. Configuración del clúster HDFS-HA

  • Preparación del entorno:

    • Modificar IP

    • Modificar el nombre de host y la asignación entre el nombre de host y la dirección IP

    • Desactivar el cortafuegos

    • inicio de sesión sin contraseña ssh

    • Instale JDK, configure variables de entorno, etc.

  • Planificación de un clúster

nodo1 nodo2 nodo3
NombreNodo NombreNodo -
Nodo de diario Nodo de diario Nodo de diario
Nodo de datos Nodo de datos Nodo de datos
ZK ZK ZK
Administrador de recursos
Administrador de nodos Administrador de nodos Administrador de nodos
  • Configuración del clúster Zookeeper: ¡ya está registrado en las notas anteriores!

  • Configure el clúster HDFS-HA:

    • Configurar hadoop-env.sh

      export JAVA_HOME=/opt/app/jdk
      
    • Configurar core-site.xml

      <configuration>
      <!-- 把两个NameNode的地址组装成一个集群HadoopCluster -->
            <property>
                <name>fs.defaultFS</name>
                <value>hdfs://HC</value>
            </property>
            <!-- 指定hadoop运行时产生文件的存储目录 -->
            <property>
                <name>hadoop.tmp.dir</name>
                <value>/opt/app/hadoop-3.1.4/metaData</value>
            </property>
            <!--配置连接的zookeeper的地址-->
            <property>
                <name>ha.zookeeper.quorum</name>
                <value>node1:2181,node2:2181,node3:2181</value>
            </property>
      </configuration>
      

    imagen-20230914213405059

    • Configurar hdfs-site.xml

      <configuration>
            <!-- 完全分布式集群名称 -->
        <property>
            <name>dfs.nameservices</name>
            <value>HC</value>
        </property>
        <!-- 集群中NameNode节点都有哪些 -->
        <property>
            <name>dfs.ha.namenodes.HC</name>
            <value>nn1,nn2</value>
        </property>
        <!-- nn1的RPC通信地址 -->
        <property>
            <name>dfs.namenode.rpc-address.HC.nn1</name>
            <value>node1:9000</value>
        </property>
        <!-- nn2的RPC通信地址 -->
        <property>
            <name>dfs.namenode.rpc-address.HC.nn2</name>
            <value>node2:9000</value>
        </property>
        <!-- nn1的http通信地址 -->
        <property>
            <name>dfs.namenode.http-address.HC.nn1</name>
            <value>node1:9870</value>
        </property>
        <!-- nn2的http通信地址 -->
        <property>
            <name>dfs.namenode.http-address.HC.nn2</name>
            <value>node2:9870</value>
        </property>
        <!-- 指定NameNode元数据在JournalNode上的存放位置 -->
        <property>
            <name>dfs.namenode.shared.edits.dir</name>
            <value>qjournal://node1:8485;node2:8485;node3:8485/HadoopCluster</value>
        </property>
        <!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
        <property>
            <name>dfs.ha.fencing.methods</name>
            <value>sshfence</value>
        </property>
        <!-- 使用隔离机制时需要ssh无秘钥登录-->
        <property>
            <name>dfs.ha.fencing.ssh.private-key-files</name>
            <value>/root/.ssh/id_rsa</value>
        </property>
        <!-- 声明journalnode服务器存储目录-->
        <property>
            <name>dfs.journalnode.edits.dir</name>
            <value>/opt/app/hadoop-3.1.4/journalnodeData</value>
        </property>
        <!-- 关闭权限检查-->
        <property>
            <name>dfs.permissions.enable</name>
            <value>false</value>
        </property>
        <!-- 访问代理类:client,HadoopCluster,active配置失败自动切换实现方式-->
        <property>
              <name>dfs.client.failover.proxy.provider.HC</name>
            <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
        </property>
            <property>
                <name>dfs.replication</name>
                <value>3</value>
            </property>
            <property>
                <name>dfs.namenode.datanode.registration.ip-hostname-check</name>
                <value>true</value>
            </property>
          <property>
            <name>dfs.ha.automatic-failover.enabled</name>
            <value>true</value>
          </property>
       </configuration>
      
    • Copie el entorno hadoop configurado a otros nodos

    scp /opt/app/hadoop-3.1.4/etc/hadoop/core-site.xml root@node2:/opt/app/hadoop-3.1.4/etc/hadoop/
    scp /opt/app/hadoop-3.1.4/etc/hadoop/core-site.xml root@node3:/opt/app/hadoop-3.1.4/etc/hadoop/
    scp /opt/app/hadoop-3.1.4/etc/hadoop/hdfs-site.xml root@node3:/opt/app/hadoop-3.1.4/etc/hadoop/
    scp /opt/app/hadoop-3.1.4/etc/hadoop/hdfs-site.xml root@node2:/opt/app/hadoop-3.1.4/etc/hadoop/
    
  • Iniciar el clúster HDFS-HA

    • Instalar el software psmisc

    La conmutación por error automática de zkfc debe completarse con la ayuda del software psmisc, por lo que este software debe instalarse en tres nodos.

    yum install -y psmisc
    

    imagen-20230914231656221

    • En cada nodo JournalNode, ingrese el siguiente comando para iniciar el servicio journalnode:
      sbin/hadoop-daemon.sh start journalnode

    imagen-20230914232428309

    • En [nn1], formatéelo y comience:
      rm -rf metaData/ journalnodeData/  删除三台节点
     /opt/app/hadoop-3.1.4   hdfs namenode -format  只需要在第一台节点格式化
                             hadoop-daemon.sh start namenode    只需要执行一次即可,之后就不需要再执行
    
    • Encontré un error, como se muestra en la figura.

      • imagen-20230914233530301
      • vim /opt/app/hadoop-3.1.4/etc/hadoop/hadoop-env.shimagen-20230914233727627
      • scp /opt/app/hadoop-3.1.4/etc/hadoop/hadoop-env.sh root@node2:/opt/app/hadoop-3.1.4/etc/hadoop/
      • scp /opt/app/hadoop-3.1.4/etc/hadoop/hadoop-env.sh root@node3:/opt/app/hadoop-3.1.4/etc/hadoop/
      • imagen-20230914234007915
      • puesta en marchastart-dfs.sh
        • imagen-20230914234221142
    • En [nn2], sincronice la información de metadatos de nn1:
      bin/hdfs namenode -bootstrapStandby solo es necesario ejecutarlo una vez y no es necesario ejecutarlo nuevamente;

      hadoop-daemon.sh start namenodee iniciar namenode en el segundo nodo

    • Inicie el nodo de datos en tres nodoshadoop-daemon.sh start datanode

    • Reiniciar HDFS

      • Cierre todos los servicios HDFS: sbin/stop-dfs.sh
      • Inicie el clúster Zookeeper: bin/zkServer.sh start
      • Inicialice el estado de HA en Zookeeper: bin/hdfs zkfc -formatZK
      • Inicie el servicio HDFS: sbin/start-dfs.sh
      • Inicie el controlador de conmutación por error DFSZK en cada nodo NameNode. ¿Qué máquina se inicia primero? El NameNode de qué máquina es el NameNode activo: sbin/hadoop-daemin.sh start zkfc
    • verificar

      • imagen-20230917171516996
      • imagen-20230917171551592
      • Elimine el proceso de Active NameNode: elimine -9 la identificación del proceso del namenode
        • imagen-20230917171646083
      • Desconectar la máquina Active NameNode de la red: parada de red de servicio
        • imagen-20230917171634976

6. Configuración de hilo-HA

Configurar el clúster YARN-HA

  • Preparación ambiental
    • Modificar IP
    • Modificar el nombre de host y la asignación entre el nombre de host y la dirección IP
    • Desactivar el cortafuegos
    • inicio de sesión sin contraseña ssh
    • Instale JDK, configure variables de entorno, etc.
    • Configurar el clúster Zookeeper
  • Planificación de un clúster
nodo1 nodo2 nodo3
NombreNodo NombreNodo
Nodo de diario Nodo de diario Nodo de diario
Nodo de datos Nodo de datos Nodo de datos
ZK ZK ZK
Administrador de recursos Administrador de recursos
Administrador de nodos Administrador de nodos Administrador de nodos
  • Configuración específica: configurar en cada nodo

    • sitio-hilado.xml

      <configuration>
        <property>
            <name>yarn.nodemanager.aux-services</name>
            <value>mapreduce_shuffle</value>
        </property>
        <!--启用resourcemanager ha-->
        <property>
            <name>yarn.resourcemanager.ha.enabled</name>
            <value>true</value>
        </property>
        <!--声明两台resourcemanager的地址-->
        <property>
            <name>yarn.resourcemanager.cluster-id</name>
            <value>cluster-yarn1</value>
        </property>
        <property>
            <name>yarn.resourcemanager.ha.rm-ids</name>
            <value>rm1,rm2</value>
        </property>
        <property>
            <name>yarn.resourcemanager.hostname.rm1</name>
            <value>node1</value>
        </property>
        <property>
            <name>yarn.resourcemanager.hostname.rm2</name>
            <value>node2</value>
        </property>
        <!--指定zookeeper集群的地址--> 
        <property>
            <name>yarn.resourcemanager.zk-address</name>
            <value>node1:2181,node2:2181,node3:2181</value>
        </property>
        <!--启用自动恢复--> 
        <property>
            <name>yarn.resourcemanager.recovery.enabled</name>
            <value>true</value>
        </property>
        <!--指定resourcemanager的状态信息存储在zookeeper集群--> 
        <property>
            <name>yarn.resourcemanager.store.class</name>     
            <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
        </property>
      </configuration>
      
    • Actualizar sincrónicamente la información de configuración de otros nodos.

      • scp /opt/app/hadoop-3.1.4/etc/hadoop/yarn-site.xml root@node2:/opt/app/hadoop-3.1.4/etc/hadoop/
        scp /opt/app/hadoop-3.1.4/etc/hadoop/yarn-site.xml root@node3:/opt/app/hadoop-3.1.4/etc/hadoop/
        

        imagen-20230917230055889

  • Inicie hdfs (no necesita realizar este paso si ha creado un clúster HA-Hadoop)

    • En cada nodo JournalNode, ingrese el siguiente comando para iniciar el servicio journalnode: sbin/hadoop-daemon.sh start journalnode

    • En [nn1], formatéelo y comience:

      bin/hdfs namenode -format
      sbin/hadoop-daemon.sh start namenode
      
    • En [nn2], sincronice la información de metadatos de nn1: bin/hdfs namenode -bootstrapStandby

    • Iniciar [nn2]: sbin/hadoop-daemon.sh inicia namenode

    • Inicie todos los nodos de datos: sbin/hadoop-daemons.sh inicie el nodo de datos

    • Cambie [nn1] a Activo: bin/hdfs haadmin -transitionToActive nn1

  • hilo de inicio

    • Ejecutar en el nodo1: sbin/start-yarn.sh
    • Ejecutar en el nodo 2: sbin/yarn-daemon.sh inicia el administrador de recursos
    • Verifique el estado del servicio: bin/yarn rmadmin -getServiceState rm1

imagen-20230917230905317

imagen-20230917231006420

7. Cómo utilizar el programa MR para contar palabras en un entorno de alta disponibilidad

Edite wc.txt y cárguelo en hdfs

imagen-20230918092044257

imagen-20230918092053070

Abra una idea, cree un proyecto maven e introduzca dependencias de programación en pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.kang</groupId>
  <artifactId>ha-test</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>

  <name>ha-test</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>3.1.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-hdfs</artifactId>
      <version>3.1.4</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.1</version>
    </dependency>
  </dependencies>
</project>

Escribir código MapReduce

imagen-20230918112525372

package com.kang;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class WCMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
    
    
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws IOException, InterruptedException {
    
    
        String line = value.toString();
        String[] words = line.split(" ");
        for (String word : words) {
    
    
            context.write(new Text(word),new LongWritable(1L));
        }
    }
}


package com.kang;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

public class WCReduce extends Reducer<Text, LongWritable,Text,LongWritable> {
    
    
    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException, InterruptedException {
    
    
        long sum = 0L;
        for (LongWritable value : values) {
    
    
            sum += value.get();
        }
        context.write(key,new LongWritable(sum));
    }
}



package com.kang;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import javax.xml.soap.Text;
import java.io.IOException;

public class WCDriver {
    
    
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
    
    
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS","hdfs://HC");

        Job job = Job.getInstance(conf);
        job.setJarByClass(WCDriver.class);
        FileInputFormat.setInputPaths(job,new Path("/wc.txt"));

        job.setMapperClass(WCMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);

        job.setReducerClass(WCReduce.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);
        job.setNumReduceTasks(0);

        FileOutputFormat.setOutputPath(job,new Path("/output"));

        boolean flag = job.waitForCompletion(true);
        System.exit(flag?0:1);
    }
}

Exporte hdfs-site.xml y core-site.xml desde la máquina virtual al directorio del proyecto Java

imagen-20230918112631575

Luego ejecute WCDriver, recibirá un mensaje de error y mostrará permisos insuficientes, luego para lograr esta tarea modificamos los permisos.

imagen-20230918112748878

imagen-20230918112901312

Ejecute el programa nuevamente y devuelva el código 0, lo que significa que la operación fue exitosa.

imagen-20230918112950486

imagen-20230918113032239

Finalmente, restauramos los permisos predeterminados de archivos y directorios en el Sistema de archivos distribuido de Hadoop (HDFS) a los tipos de permisos predeterminados.

imagen-20230918113342735

Supongo que te gusta

Origin blog.csdn.net/weixin_57367513/article/details/132979385
Recomendado
Clasificación