2016-11-29 119 views
1

我正在將Spark 1.6.2的應用程序升級到Spark 2.0.2。這個問題並不嚴格與Spark有關。 Spark 1.6.2包含Kryo 2.21。 Spark 2.0.2包含Kryo 3.0.3。升級到Spark 2.0時出現Kryo註冊問題

應用程序存儲一些使用Kryo在HDFS上序列化的數據。爲了節省空間,Kryo註冊被強制執行。當一個類在Kryo上註冊時,它會得到一個連續的ID,這個ID用來表示類的格式而不是完整的類名。當我們註冊一個新類時,我們總是把它放在最後,所以它會得到一個未使用的ID。我們也永遠不會從註冊中刪除一個班級。 (如果一個類被刪除了,我們在它的位置註冊一個佔位符來保留這個ID。)這樣這些ID是穩定的,一個版本的應用程序可以讀取以前版本寫的數據。

事實證明,Kryo使用相同的註冊機制在其構造函數中註冊基本類。在Kryo 2.21中,它註冊了9個基本類,所以第一個用戶註冊的類獲得了ID 9.但是Kryo 2.22和更高版本註冊了10個基本類。 (void was added.)這意味着用戶註冊的類從ID 10開始。

升級到Spark 2.0.2後,我們仍然可以加載舊數據嗎?

(這將是巨大的,如果我們的第一個用戶註冊類是一個過時的類,但事實並非如此。這是scala.Tuple2[_, _]。)

+0

Kryo怎麼可能做出這樣一個突破性變化,從2.21變爲2.22?爲了增加傷害,他們的更新日誌列出了每個發行版的序列化兼容性爲「是」。但更新日誌開始於2.22。 –

+0

好的,解決方法不是太糟糕。我認爲我在那裏過於戲劇化。 –

回答

1

其實是有一個Kryo.register(Class type, int id)方法,其可用於明確指定的ID 。對於id參數評論說:

ID:必須> = 0較小ID被更有效地序列化。默認情況下,基元類型和String使用ID 0-8,但可以重新使用這些ID。

從2.22開始的評論是錯誤的:ID 9現在也被默認使用。但事實上它可以重新使用!

kryo.register(classOf[Tuple2[_, _]], 9) 

正常的順序註冊適用於其餘類。顯式ID只對第一類是必需的。

相關問題