天天看點

大資料系統建構:可擴充實時資料系統建構原理與最佳實踐》一3.2 Apache Thrift

我們對apache thrift的使用:thrift最初由facebook開發,用來建構跨語言服務。它可以用于諸多目的,但我們将縮小讨論範圍,隻關注它作為一個序列化架構的使用。

其他序列化架構

還有其他類似于apache thrift的工具,如protocol buffers和avro。記住,本書不是對每種情況的所有可能的工具提供調研,而是選用适當的工具來說明基本概念。作為一種序列化架構,thrift已經經過了生産環境的完全測試并得到了廣泛使用。

thrift的核心是結構體(struct)和聯合體(union)的類型定義。它們是由其他字段組成的,如:

原始資料類型(string,integer,long與double)

其他類型的集合(list,map與set)

其他結構體和聯合體

一般來說,用聯合體來表示節點是很有用的,結構體是邊的自然表示,屬性則将聯合體和結構體結合起來使用。這對于需要表示superwebanalytics.com模式元件的類型定義來說是有效的。

對于superwebanalytics.com使用者節點,通過使用者id或浏覽器cookie辨別某個人,而不會同時用這兩個元素辨別他。這種模式對于節點是常見的,且完全比對聯合體資料類型—單個值可能有幾種表示方式。

在thrift中,聯合體通過羅列出所有可能的表示來定義。下面的代碼使用thrift聯合體定義superwebanalytics.com節點:

大資料系統建構:可擴充實時資料系統建構原理與最佳實踐》一3.2 Apache Thrift

注意:聯合體還可用于單一表現形式的節點。聯合體允許模式随着資料的演變而演變—我們稍後将在本節中進一步讨論這個問題。

每條邊都可以表示為包含兩個節點的結構體。邊結構體的名稱表明了它所代表的關系,邊結構體中的字段包含了參與該關系的實體。

該模式定義非常簡單:

大資料系統建構:可擴充實時資料系統建構原理與最佳實踐》一3.2 Apache Thrift

thrift結構體的字段可以表示為required或optional。如果一個字段被定義為required,那麼必須為該字段提供一個值,否則thrift會在序列化或反序列化時給出一個錯誤。因為圖模式中的每條邊都必須有兩個節點,是以在這個例子中它們是必需的字段。

最後讓我們來定義屬性。屬性包含一個節點和屬性的值。因為值可以是諸多類型中的一種,是以最好使用聯合體結構來表示。

首先定義頁面屬性的模式。頁面隻有一個屬性,是以很簡單:

大資料系統建構:可擴充實時資料系統建構原理與最佳實踐》一3.2 Apache Thrift

接下來定義人的屬性。正如你看到的,位置屬性更為複雜,需要另一個結構體來定義:

大資料系統建構:可擴充實時資料系統建構原理與最佳實踐》一3.2 Apache Thrift

位置結構體是很有意思的,因為city、state和country字段可能被存儲為單獨的資料片。在這種情況下,它們是密切相關的,是以把它們都放在一個結構體作為可選字段是講得通的。當使用位置資訊時,你可能會希望得到所有字段。

此時,邊和屬性被定義為不同的類型。在理想情況下,你想将所有資料存儲在一起,為通路你的資訊隻提供一個接口。此外,如果存儲在單個資料集中,還能使得資料更容易管理。這可以通過将每個屬性和邊的類型封裝到dataunit聯合體來實作—如代碼清單3-1。

代碼清單3-1 完成superwebanalytics.com模式

大資料系統建構:可擴充實時資料系統建構原理與最佳實踐》一3.2 Apache Thrift

每個dataunit與其中繼資料成對儲存在一個pedigree結構體中。pedigree包含了資訊的時間戳,但也可能包含調試資訊或資料源。最後的data結構體對應了基于行為模型中的一個行為。

thrift的設計使得模式可以随時間而演變。這是一個至關重要的屬性,因為随着業務需求的改變,你将需要添加新類型的資料,并且想盡可能輕松地這樣做。

演變thrift模式的關鍵是與每個字段相關聯的數值辨別符。把這些序列化形式的id用于辨別字段。當想要改變模式但仍要向下相容現有的資料時,你必須遵守以下規則:

字段可能被重新命名。這是因為對象的序列化形式使用字段id而不是名稱來辨別字段。

一個字段可能被删除,但你絕不能重用那個字段id。當反序列化現有資料時,thrift将忽略字段id沒有包含在模式中的所有字段。如果你重用之前删除的字段id,thrift會嘗試反序列化舊資料到新的字段,這将導緻無效或不正确的資料。

隻有可選的字段可以被添加到現有的結構體。你不能添加必需的字段,因為現有的資料不會有這些字段,是以不能被反序列化。(注意:這并不适用于聯合體,因為聯合體沒有必需和可選字段的概念)

作為一個例子,如果想要改變superwebanalytics.com模式來存儲一個人的年齡和網頁之間的連結,那麼應對thrift定義檔案做出以下改變(變化的用粗體表示)。

代碼清單3-2 擴充superwebanalytics.com

大資料系統建構:可擴充實時資料系統建構原理與最佳實踐》一3.2 Apache Thrift

注意:添加新的年齡屬性是通過添加到相應的聯合體結構完成的,并且新的邊可以通過将它添加到dataunit聯合體來實作内嵌。