簡體   English   中英

內存高效的分布式方法來確定唯一值?

[英]Memory-efficient distributed approach to determining unique values?

問題

我正在嘗試在非常大的原始非規范化CSV表中規范化列。 列值是短字符串(10-100字節)。 我正試圖找到一種比我目前的方法更快的解決方案。

input.csv

john,london
jean,paris
bill,london

轉換為以下文件:

input.normalized.csv

1,1
2,2
3,1

input.col1.csv

1,john
2,jean
3,bill

input.col2.csv

1,london
2,paris

我目前有兩種方法來規范化這些數據集。

目前的方法

單通內存

單通道方法,在關聯數組中存儲列values -> normalized_id值(在我的例子中是Java HashMap)。 這會在某些時候耗盡內存,但是當它可以將所有內容存儲在內存中時它會很快。 降低內存使用量的一種簡單方法是每列執行一次傳遞。

多通道排序

基於排序的多通道方法。 列值附加其行號,然后進行排序(以內存高效的合並排序方式)。 例如,列值london,paris,london附有行號,然后進行排序: london;1,london;3,paris;2

我現在可以擁有一個“唯一值計數器”,只需將每個值與之前的值進行比較(例如倫敦==倫敦,所以不要增加唯一值計數器)。 最后,我有一對unique_id,linenum對,我可以按行號排序以重建規范化列。 然后可以在一次通過中合並列。

這種方法可以在非常有限的內存中完成,具體取決於所應用的排序算法的內存使用情況。 好消息是,這種方法很容易在像hadoop這樣的方法中實現,利用它的分布式排序步驟。

我的問題

與單通道方法(或單通道每列方法)相比,多通道方法非常緩慢。 所以我想知道優化這種方法的最佳方法是什么,或者是否有人可以建議其他方法?

我估計我正在尋找某種類型的(分布式)鍵值存儲,它具有盡可能低的內存使用率。

在我看來,使用Trove將是使用Java HashMaps的一個好的,簡單的替代方案,但我想要一些可以為我處理密鑰分發的東西。

Redis可能是一個不錯的選擇,但我並沒有對每個鍵值對的內存使用情況印象深刻。

你知道輸入列的粗略數量級嗎? 如果是這樣,您不需要保留原始輸入文件順序? 然后,您可以使用足夠大的哈希函數來避免輸入鍵的沖突。

如果你堅持擁有密集的連續密鑰空間,那么你已經涵蓋了兩個主要選擇。 你當然可以嘗試redis,我已經看到它用於數百萬的鍵值對,但它可能不會擴展到那個以上。 你也可以試試memcached。 它的內存開銷可能略低於redis,但我肯定會嘗試兩者,因為它們對於這種特殊用法非常相似。 您實際上並不需要Redis的高級數據結構。

如果你需要更多的鍵值而不是你可以在一台機器上存儲在內存中,那么你可能會回歸到像BDB或Kyoto cabinet這樣的東西,但最終這一步將成為你處理的瓶頸。 另一個紅旗是,如果你可以在一台機器的內存中安裝整列,那你為什么要使用Hadoop?

老實說,依賴密集有序的主鍵是NoSQL DB中首先拋出的東西之一,因為它假定一個單獨的協調主。 如果你可以允許甚至一些間隙,那么你可以做類似於矢量時鍾的事情。

最后一種選擇是使用map-reduce作業按鍵收集所有重復值,然后使用某個外部事務DB計數器分配唯一值。 但是,map-reduce工作本質上是一種多遍方法,因此可能更糟。 主要優點是你將獲得一些IO並行性。 (雖然id賦值仍然是一個串行事務。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM