2013-08-01 74 views
1

我們正在評估avro v/s節儉存儲。在這一點上Avro似乎是我們的選擇,但是文檔聲明模式在序列化時與數據一起存儲,是否有辦法避免這種情況,因爲我們既生產又消費數據,我們想看看是否我們可以避免序列化模式,並且序列化數據與模式的大小差異遠大於沒有模式的數據?Avro模式存儲

回答

0

我敢肯定,您將始終需要架構與數據一起存儲。這是因爲Avro會在讀取和寫入.avro文件時使用它。

根據http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuide/avroschemas.html

您應用一個模式來使用的Avro綁定的Oracle NoSQL數據庫記錄的值部分。這些綁定用於在寫入值之前序列化值,並在讀取值後對值進行反序列化。這些綁定的使用要求您的應用程序使用Avro數據格式,這意味着每個存儲值都與一個模式關聯。

就尺寸差異而言,您只需存儲一次模式,因此在大型計劃中,它並沒有太大的區別。我的模式佔用了105.5KB(這是一個非常大的模式,你不應該那麼大),每個序列化的值需要3.3KB。我不知道的區別是什麼不僅僅是數據的原始JSON,但根據該鏈接我張貼:

每個值存儲不超過一個小型的內部架構的標識符之外的任何元數據,1間和4個字節大小。

但我相信可能只是單一的簡單值。

這是在HDFS爲我順便說一句。

0

感謝JGibel,我們的數據最終最終會以HDFS結尾,並且對象容器文件格式確保模式僅作爲文件頭被寫入。

對於HDFS以外的用途,我錯誤地認爲該架構將附加到每個編碼數據,但並非如此,這意味着您需要該架構對其進行反序列化,但是序列化數據不必將模式字符串附加到它。

E.g.

DatumWriter<TransactionInfo> eventDatumWriter = new SpecificDatumWriter<TransactionInfo>(TransactionInfo.class); 

TransactionInfo t1 = getTransaction(); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
BinaryEncoder becoder = EncoderFactory.get().binaryEncoder(baos, null); 
eventDatumWriter.setSchema(t1.getSchema()); 
eventDatumWriter.write(t1, becoder); 
becoder.flush(); 
+0

很高興,如果我能夠幫助清理任何東西。如果你發現其他東西,請更新! – JGibbers

0

對派對稍遲,但實際上並不需要將實際模式存儲在每條記錄中。但是,您需要從每個記錄的序列化格式中返回原始模式。

因此,您可以使用模式存儲+自定義序列化器來編寫avro記錄內容和模式標識。讀取後,您可以讀回該架構ID,從架構存儲中檢索該架構,然後使用該架構來重新水化記錄內容。如果模式存儲是遠程的,則使用本地高速緩存的獎勵點。

這正是Oracle's NoSQL DB以存儲高效方式管理模式(它也可以在AGPL許可下使用)的方法。

完全披露:目前和以前從未受僱於Oracle或Sun,或曾在上述商店工作。剛剛碰到它最近:)