一、概述
Avro是一種遠程過程調用和數據序列化框架,是在Apache的Hadoop項目之內開發的。它使用JSON來定義數據類
型和通訊協議,使用壓縮二進制格式來序列化數據。它主要用於Hadoop,它可以爲持久化數據提供一種序列化格
式,併爲Hadoop節點間及從客戶端程序到Hadoop服務的通訊提供一種電報格式
二、序列化和反序列化
數據序列化就是將對象或者數據結構轉化成特定的格式,使其可在網絡中傳輸,或者可存儲在內存或者文件中。反
序列化則是相反的操作,將對象從序列化數據中還原出來。
數據序列化的重點在於數據的交換和傳輸 。
衡量標準
- 序列化之後的數據大小
因爲序列化的數據要通過網絡進行傳輸或者是存儲在內存或者文件中,所以數據量越小,則存儲或者傳輸所
用的時間就越少 - 序列化以及反序列化的耗時及佔用的CPU
- 是否能夠跨語言或者平臺
因爲現在的企業開發中,一個項目往往會使用到不同的語言來進行架構和實現。那麼在異構的網絡系統中,
網絡雙方可能使用的是不同的語言或者是不同的操作系統,例如一端使用的是Java而另一端使用的C++;或者
一端使用的是Windows系統而另一端使用的是Linux系統,那麼這個時候就要求序列化的數據能夠在不同的語
言以及不同的平臺之間進行解析傳輸
Java原生序列化/反序列化機制的問題
- Java的原生序列化不能做到對象結構的服用,就導致序列化多個對象的時候數據量較大
- Java的原生序列化在使用的時候,是按照Java指定的格式將對象進行解析,解析爲字節碼格式,那麼此時其他
的語言在接收到這個對象的時候,是無法解析或者解析較爲困難。即Java的原生序列化機制是沒有做到跨語言
或者跨平臺傳遞使用
三、常見序列化框架
Protobuf
Protobuf是Google公司提供的序列化/反序列化框架,特點如下:
- 平臺無關、語言無關。
- 二進制、數據自描述。
- 提供了完整詳細的操作API。
- 高性能,比xml要快20-100倍
- 尺寸小,比xml要小3-10倍,高可擴展性
- 數據自描述、前後兼容
Thrift
Thrift是Facebook公司提供的序列化/反序列化的框架,2007年貢獻給了Apache。特點如下:
- 支持非常多的語言綁定
- thrift文件生成目標代碼,簡單易用、
- 消息定義文件支持註釋
- 數據結構與傳輸表現的分離,支持多種消息格式
- 包含完整的客戶端/服務端堆棧,可快速實現RPC
- 支持同步和異步通信
Avro
- 豐富的數據結構類型,8種基本數據類型以及6種複雜類型
- 快速可壓縮的二進制形式
- 提供容器文件用於持久化數據
- 遠程過程調用RPC框架
- 簡單的動態語言結合功能,Avro 和動態語言結合後,讀寫數據文件和使用 RPC協議都不需要生成代碼,而代
碼生成作爲一種可選的優化只值得在靜態類型語言中實現。而代碼生成作爲一種可選的優化只值得在靜態類
型語言中實現。
通過avro,每次進行序列化,根據模式(schema)文件來序列化,可以提高性能。
Avro是依賴於模式(schema),模式文件是用json格式來表示的。如果是想利用avro實現序列化或rpc通信,需要
遵守schema的格式要求。基於模式的好處是使得序列化快速而又輕巧
四、Avro的格式說明
簡單類型
Avro定義了8種簡單數據類型,下表是其簡單說明
Avro類型 | 說明 |
---|---|
null 沒有值 | |
boolean | 一個二級制布爾值 |
int | 32位有符號整數 |
long | 64位有符號整數 |
float | 32位單精度浮點數 |
double | 64位雙精度浮點數 |
bytes | 8位無符號字節序列 |
string | 字符序列 |
複雜格式
Avro定義了六種複雜數據類型,每一種複雜數據類型都具有獨特的屬性,下表就每一種複雜數據類型進行說明。
每一種複雜數據類型都含有各自的一些屬性,其中部分屬性是必需的,部分是可選的。
這裏需要說明Record類型中field屬性的默認值,當Record Schema實例數據中某個field屬性沒有提供實例數據
時,則由默認值提供,具體值見下表。Union的field默認值由Union定義中的第一個Schema決定。
五、RPC
概述
RPC 的全稱是 Remote Procedure Call(遠程過程調用) 是一種進程間通信方式。它允許程序調用另一個地址空
間(通常是共享網絡的另一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。 即程序員無論
是調用本地的還是遠程的,本質上編寫的調用代碼基本相同。
起源
布魯斯·納爾遜1974年畢業於哈維·穆德學院,1976年在斯坦福大學獲得計算機科學碩士學位,1982年在卡內基梅
隆大學獲得計算機科學博士學位。在追求博士學位時,他開發了遠程過程調用(RPC)的概念。他和他的合作者安
德魯·伯雷爾因在RPC方面的工作而獲得了1994年ACM軟件系統獎。1996他加入思科系統擔任首席科學官。
特點
- 簡單:RPC 概念的語義十分清晰和簡單,這樣建立分佈式計算就更容易。
- 高效:過程調用看起來十分簡單而且高效。
- 通用:在單機計算中過程往往是不同算法部分間最重要的通信機制。 通俗一點說,就是一般程序員對於本地
的過程調用很熟悉,那麼我們在通過網絡做遠程通信時,通過RPC 把遠程調用做得和本地調用完全類似,那
麼就更容易被接受,使用起來也就毫無障礙。
過程
- 服務消費方(User)調用以本地調用方式調用服務
- User-stub(存根)接收到調用後負責將方法、參數等組裝成能夠進行網絡傳輸的消息體,並交給
RPCRuntime模塊 - RPCRuntime找到服務地址,並將消息發送到服務端
- 服務端的RPCRuntime收到消息後,傳給Server-stub
- Server-stub根據解碼結果調用本地的服務
- 本地服務執行並將結果返回給Server-stub
- server stub將返回結果打包成消息併發送至消費方
- client stub接收到消息,並進行解碼
- 服務消費方得到最終結果
RPC調用細節
- 接口方式的調用
RPC設計的目的在於可以讓調用者可以像以本地調用方式一樣調用遠程服務。具體實現的方式是調用接口的方
式來調用。在java中,底層通過Java動態代理方式生成接口的代理類,代理類中封裝了與遠程服務通信的細
節。這些細節包括:
客戶端的請求消息: - 接口名稱
- 方法名
- 參數類型以及相應的參數值
- requestID,標識唯一請求id
服務器端的返回消息: - 返回值
- requestID
- 序列化
- 通信
一般RPC通信都是基於NIO進行通信
RPC框架的特點
- 基於RPC的進程通信方式
- 有自定義的一套序列化和反序列的機制
- 客戶端通過代理機制調用遠程方法
- 服務端通過回調機制執行方法及返回結果