摘要:博客原文這篇文章主要介紹如何在已有的框架上,自定義新的方法實(shí)現(xiàn)和的交互。在此之前,我們需要準(zhǔn)備的源碼版本版本中采用了簡(jiǎn)稱作為序列化和反序列化的工具,所以我們?cè)谛薷脑创a時(shí)需要按照相應(yīng)規(guī)則編寫來實(shí)現(xiàn)數(shù)據(jù)的傳輸。
博客原文:hackershell
這篇文章主要介紹如何在已有的Hadoop RPC框架上,自定義新的方法實(shí)現(xiàn)和NameNode的交互。
在此之前,我們需要準(zhǔn)備:
hadoop的源碼
protobuf 2.5版本
JDK
hadoop 2.x版本中采用了Protocol Buffer (簡(jiǎn)稱protobuf)作為序列化和反序列化的工具,所以我們?cè)谛薷脑创a時(shí)需要按照相應(yīng)規(guī)則編寫message來實(shí)現(xiàn)數(shù)據(jù)的傳輸。
什么是protobuf?protobuf是Google 公司內(nèi)部的混合語(yǔ)言數(shù)據(jù)標(biāo)準(zhǔn),它很適合做數(shù)據(jù)存儲(chǔ)或 RPC 數(shù)據(jù)交換格式。是一種可用于通訊協(xié)議、數(shù)據(jù)存儲(chǔ)等領(lǐng)域,并且和語(yǔ)言無關(guān)、平臺(tái)無關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)格式。 簡(jiǎn)單說來 Protobuf 的主要優(yōu)點(diǎn)就是:簡(jiǎn)單,快。
安裝protobuf和編譯hadoop的過程網(wǎng)上的資料很多,我就直接跳過了,我們可以通過Idea導(dǎo)入hadoop的Maven項(xiàng)目,方便對(duì)源碼的修改
1. 修改proto文件,定義message和service假設(shè)我們現(xiàn)在要實(shí)現(xiàn)的是一個(gè)檢查某個(gè)文件或文件夾權(quán)限是否符合755,并對(duì)客戶端返回boolean值。 這是一個(gè)屬于Client和NameNode交互的一個(gè)方法,所以我們?cè)贗dea中ctrl+shift+N快速的找到ClientNamenodeProtocol.proto,添加對(duì)應(yīng)的message(結(jié)構(gòu)化數(shù)據(jù)被稱為message)
message CheckPermissionRequestProto { required string src = 1; } message CheckPermissionResponseProto { required bool checkPerm = 1; }
我們?cè)谶@個(gè)文件中會(huì)看到除了string、bool類型的前面會(huì)有三種消息成員的規(guī)則,他們的含義分別是:
required:這個(gè)域在消息中必須剛好有1個(gè)
optional:這個(gè)域在消息中可以有0或1個(gè)
repeated:這個(gè)域在消息中可以有從多個(gè),包括0個(gè)
在文件中找到service,并添加方法checkPermission方法
service ClientNamenodeProtocol { ...... rpc checkPermission(CheckPermissionRequestProto) returns(CheckPermissionResponseProto); }
接下來編譯,編譯之后你可以在ClientNamenodeProtocolProtos類(編譯后生成)的接口ClientNamenodeProtocol,看到新增加的方法了。
2. ClientNamenodeProtocolPB文件這個(gè)接口是client用來和NameNode進(jìn)行交互的,它繼承了ClientNamenodeProtocol接口,即新生成的接口也在其中,這里不用做修改
3. ClientNamenodeProtocolTranslatorPB類這個(gè)類是將對(duì)ClientProtocol中方法的調(diào)用轉(zhuǎn)化為RPC調(diào)用Namenode的服務(wù),并將調(diào)用參數(shù)轉(zhuǎn)化為PB的類型。 所以,我們需要在ClientProtocol增加checkPermission方法,并在這個(gè)類中進(jìn)行Override
在ClientProtocol中增加
@Idempotent public boolean checkPermission(String src) throws AccessControlException, FileNotFoundException, UnresolvedPathException, IOException;
在ClientNamenodeProtocolTranslatorPB類中
@Override public boolean checkPermission(String src) throws AccessControlException, FileNotFoundException, UnresolvedPathException, IOException { CheckPermissionRequestProto req = CheckPermissionRequestProto.newBuilder() .setSrc(src).build(); try { return rpcProxy.checkPermission(null,req).getCheckPerm(); } catch (ServiceException e) { throw ProtobufHelper.getRemoteException(e); } }
注意:要把CheckPermissionRequestProto進(jìn)行import,否則編譯你懂的。
相應(yīng)的我們也需要在NameNodeRpcServer類中Override該方法,因?yàn)镹amenodeProtocols繼承了ClientProtocol,這類負(fù)責(zé)處理所有到達(dá)NN的RPC call,他負(fù)責(zé)將請(qǐng)求轉(zhuǎn)化為NN的方法的調(diào)用,因此也可以看出它們的實(shí)現(xiàn)分層是很清晰的。
@Override // ClientProtocol public boolean checkPermission(String src) throws AccessControlException, FileNotFoundException, UnresolvedPathException, IOException { return namesystem.checkPermission(src); }4. ClientNamenodeProtocolServerSideTranslatorPB類
該類是server端用來將ClientNamenodeProtocolTranslatorPB生成的PB格式的數(shù)據(jù)轉(zhuǎn)化為本地調(diào)用的數(shù)據(jù)類型,所以增加改方法
@Override public CheckPermissionResponseProto checkPermission(RpcController controller, CheckPermissionRequestProto req) throws ServiceException { try { boolean result = server.checkPermission(req.getSrc()); return CheckPermissionResponseProto.newBuilder().setCheckPerm(result).build(); //將結(jié)果返回 } catch (IOException e) { throw new ServiceException(e); } }
這里的server就是NameNodeRpcServer,相當(dāng)于調(diào)用NameNodeRpcServer的checkPermission方法,并在NameNodeRpcServer中調(diào)用FSNamesystem完成最后的邏輯
Namesystem類增加方法
boolean checkPermission(String src) throws IOException { readLock(); try { HdfsFileStatus fileStatus = getFileInfo(src,false); //這個(gè)方法我有做過修改,你們可能不一樣 FsPermission fsPermission = new FsPermission((short)0755); if(fileStatus != null && fsPermission.equals(fileStatus.getPermission())) { return true; } } finally { readUnlock(); } return false; }
接下來我就舉個(gè)例子怎么調(diào)用,這只是部分代碼,詳細(xì)的自己看看源碼吧。
proxyInfo = NameNodeProxies.createProxy(conf, nameNodeUri, ClientProtocol.class, nnFallbackToSimpleAuth); this.namenode = proxyInfo.getProxy(); namenode.checkPermission(src);5. 最后一步就是編譯了
希望通過這個(gè)例子能夠加深對(duì)hadoop實(shí)現(xiàn)的理解
參考資料
Google Protocol Buffer 的使用和原理
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/64267.html
閱讀 1868·2023-04-25 19:51
閱讀 1168·2021-11-15 11:43
閱讀 4529·2021-11-02 14:40
閱讀 1999·2021-10-11 10:59
閱讀 1339·2021-09-22 15:05
閱讀 1027·2021-09-09 09:32
閱讀 648·2019-08-30 15:56
閱讀 549·2019-08-30 15:52