protobuf,hadoop中rpc的高階用法

protobuf,hadoop中rpc的高階用法

在看yarn的程式碼前,首先需要了解protobuf這個google開發的開源庫,因為yarn的rpc就是基於它來實現的。之前我們學習過hdfs的rpc不知道大家還記不記得,如果說hdfs的rpc是簡單難度的話,那麼yarn的rpc可以說是死而無憾難度了。而且配合protobuf的助攻,更是使程式碼如同雲裡霧裡更加分辨不清,所以今天我們先耐著性子看一下protobuf這個上古神器。

protobuf這個東西和json和thrift、avro甚至是之前的xml所實現的功能是類似的。在很多開原始碼中也經常看到,算是個常用的庫。但是不知道什麼原因,在國內並不流行,相關的材料也不多。我想主要原因還是json的光環太大了吧,就像二維碼一樣,明明是很沒技術含量的東西,但是卻能在現在的應用中異常火爆。

不展開了,書回正文,我們說說今天的主角protobuf。可能類比json更能說明白。在使用中它和json是完全一樣的。就是實現序列化的一種方式。那麼什麼是序列化呢,簡單說就是將java執行時記憶體中的物件可能儲存到檔案中,同時也可以從檔案中讀取物件到記憶體中。

那麼這麼幹是為什麼呢?這個功能可太有用了。首先,如果我們想寫一個基於網路的程式。那麼客戶端和伺服器端通訊是非常重要的。這種通訊如何來實現呢,之前最簡單的就是透過定義訊息包,然後一個屬性一個屬性的寫。這種方式是早年間遊戲開發的必備技能。有一套好用的網路層真的很值錢,記得以前同事給別人寫一個boost包裝的網路層就能賣不少錢。

這個東西為什麼那麼值錢?因為它重要而且麻煩,像什麼網路大端對齊還是小端對齊,結構體之間如何補位等等需要解決的問題很多。

為什麼會這樣呢?難道是程式設計師的小怪癖為了複雜而複雜?可能吧。但是更多的原因還是因為技術相對自由平等的原因,導致很難形成一家的標準。這真是一個無力吐槽的事情,看看html的標準就知道了。

但是好在很多大公司也面臨同樣的問題,所以在一家公司裡變得標準化就容易很多。所以像谷歌、阿里呀都做了自家的rpc。自己用著爽了以後也開源出來造福社會。

protobuf就是谷歌的。但是它不完全是一套rpc。而是其地層的序列化庫。透過它可能和現有的網路層很方便的結合。形成rpc。這也就是hadoop為什麼只用了protobuf而沒用grpc的原因。

protobuf用法很簡單可以分成三步:

1。 寫proto配置檔案;

2。 轉換proto配置檔案到對應的程式碼;

3。 實際使用。

首先寫proto是為什麼呢?因為第2步要轉化成對應的程式碼呀。為了公平起見只能用配置檔案來寫了。為什麼要自己定義格式?不用xml或json呢?這個。。。只能問村長了。。。

message Person {

required string name = 1;

required int32 id = 2

}

這是簡單的一個樣例,定義了一個Person實體類,有兩個屬性一個叫name,另一個叫id,這只是最簡單的哈。

第2步就是編譯了。這個針對不同的平臺有不同的轉換工具。我們寫java。所以用java的實現。命令如下所示:

protoc ——proto_path=src ——java_out=build/gen src/foo。proto

很清楚兩個主要引數,——proto_path是配置檔案所在的地方,java_out是生成原始碼的路徑。執行一下,就生成了我們想要的程式碼了。

第3步使用。如下所示:

Person person = Person。newBuilder()。setId(42)。setName(“john”)

。addPhones(Person。PhoneNumber。newBuilder()。setNumber(“555-231”)。build();

又分三步,第1步建立newBuilder用於構建物件,第2步設定屬性,第3步build方法,生成我們實際想要的物件。

好了是不是很簡單?好了今天就聊到這吧。下次我們再說說protobuf的高階用法也就是services是使用。