Red de conocimiento informático - Material del sitio web - Cómo utilizar el marco RPC de hadoop para interactuar con NameNode

Cómo utilizar el marco RPC de hadoop para interactuar con NameNode

Antes de eso, debemos preparar:

código fuente de hadoop

versión protobuf 2.5

JDK

la versión hadoop 2.x usa protocolo El búfer (protobuf para abreviar) sirve como una herramienta de serialización y deserialización, por lo que cuando modificamos el código fuente, necesitamos escribir mensajes de acuerdo con las reglas correspondientes para lograr la transmisión de datos.

¿Qué es protobuf?

Protobuf es el estándar interno de datos de lenguaje mixto de Google, ideal para almacenamiento de datos o formatos de intercambio de datos RPC. Es un formato de datos estructurados serializados, extensibles, independientes del idioma y de la plataforma que se puede utilizar en protocolos de comunicación, almacenamiento de datos y otros campos. En definitiva, las principales ventajas de Protobuf son: sencillez y rapidez.

Hay información en Internet sobre el proceso de instalación de protobuf y compilación de hadoop. La omitiré directamente. Podemos importar el proyecto hadoop Maven a través de Idea para modificar fácilmente el código fuente.

1. Modificar el archivo proto y definir Mensajes y Servicios

Supongamos que ahora queremos implementar un proyecto que verifica si los permisos de un archivo o carpeta cumplen con 755 y devuelve un valor booleano al cliente. Este es un método que pertenece al cliente que interactúa con NameNode, así que busquemos rápidamente ClientNamenodeProtocol. proto y agregue el mensaje correspondiente (los datos estructurados se llaman mensaje)

message CheckPermissionRequestProto {

cadena requerida src = 1;

}

message CheckPermissionResponseProto {

require bool checkPerm = 1;

}

Veremos en este archivo que además de cadenas, el tipo bool habrá También habrá tres reglas de miembros de mensajes a continuación, sus significados son los siguientes:

obligatorio: este campo debe ser exactamente 1 en el mensaje

opcional: este campo puede ser 0 o 1 en el mensaje

repetido: este campo puede ser múltiple en el mensaje, incluido 0

Busque el servicio en el archivo y agregue el método checkPermission método

servicio ClientNamenodeProtocol {

......

rpc checkPermission(CheckPermissionRequestProto) return(CheckPermissionResponseProto);

}

Siguiente compilación, después de la compilación Puede agregar un método en la interfaz ClientNamenodeProtocol de la clase ClientNamenodeProtocolProtos (generada después de la compilación) y ahora puede ver el método recién agregado.

2.Archivo ClientNamenodeProtocolPB

Esta interfaz se utiliza para que el cliente interactúe con NameNode. Hereda la interfaz ClientNamenodeProtocol, es decir, también se incluye la interfaz recién generada. 3. Clase ClientNamenodeProtocolTranslatorPB

Esta clase se utiliza para convertir la llamada al método en ClientProtocol en una llamada RPC al servicio Namenode y convertir los parámetros de la llamada al tipo PB.

Por lo tanto, necesitamos agregar el método checkPermission en ClientProtocol y anular el método en la clase

En ClientProtocol

@Idempotent

public boolean checkPermission(String src )

lanza AccessControlException, FileNotFoundException,

UnresolvedPathException, IOException;

En la clase ClientNamenodeProtocolTranslatorPB

@Override

public boolean checkPermission(String src) lanza AccessControlException,

FileNotFoundException, UnresolvedPathException, IOException {

CheckPermissionRequestProto req = CheckPermissionRequestProto.newBuilder()

.setSrc(src). build();

prueba {

return rpcProxy.checkPermission(null,req).getRemoteException(e);

}

}

}

Nota: utilice CheckPermissionRequestProto para importar; de lo contrario, lo sabrá al compilar.

En consecuencia, también necesitamos anular este método en la clase NameNodeRpcServer, porque NamenodeProtocols hereda ClientProtocol, que es responsable de manejar todas las llamadas RPC que llegan a NN y es responsable de convertir la solicitud en una llamada al Método NNPor lo tanto, también se puede ver que la implementación en capas es clara.

@Override // ClientProtocol

checkPermission booleano público (String src)

lanza AccessControlException, FileNotFoundException, UnresolvedPathException, IOException {

return namesystem.checkPermission(src);

}

4.Clase ClientNamenodeProtocolServerSideTranslatorPB

Esta clase se utiliza en el lado del servidor para convertir los datos en formato PB generados por ClientNamenodeProtocolTranslatorPB. en el tipo de datos local llamado, checkPermission(req.getSrc());

return CheckPermissionResponseProto.newBuilder().setCheckPerm(result).build() // Devuelve resultado

} catch (IOException e) {

throw new ServiceException(e);

}

}

El servidor aquí es NameNodeRpcServer, que es equivalente a llamar al método checkPermission de NameNodeRpcServer y usar NameNodeRpcServer para llamar a FSNamesystem para completar la lógica final

método agregado de clase Namesystem

boolean checkPermission(String src) throws IOException {

readLock( );

prueba {

HdfsFileStatus fileStatus = getFileInfo(src,false); //este método lo he modificado, puede que seas diferente

FsPermission fsPermission = new FsPermission((short)0755);

if(fileStatus! = null && fsPermission.equals(fileStatus.getPermission())){

devuelve verdadero;

}

}

} finalmente {

readUnlock();

}

devuelve falso;

}

A continuación daré un ejemplo Explique cómo llamarlo, esto es solo una parte del código, verifique el código fuente usted mismo.

proxyInfo = NameNodeProxies.createProxy(conf, nameNodeUri,

ClientProtocol.class, nnFallbackToSimpleAuth);

namenode = proxyInfo.getProxy(); p>

namenode.checkPermission(src);

5. El último paso es la compilación

Espero que este ejemplo pueda profundizar la comprensión de la implementación de hadoop

.