海量處理 — bitmap及區段劃分

來源:互聯網
上載者:User

還有一種經常使用的策略是bitmap.
Bitmap本身也是一種hash-table, 只不過hash的結果恰好落在[0, sizeof_bitmap_in_bits]內. 因為hash到的每個slot只有一個bit,所以通常用作判斷是否存在等bool型的問題.

例子, 已知40億個不重複的unsigned int, 如何判斷一個整數在不在這40億個整數裡面?

給定說unsigned int,其實是指定了元素的可能範圍, [0, 2^32 – 1]中, 注意2^32=42,9496,7296, 大約是42億.

判斷存在與否, 一個bit就夠了,而記錄所有的uint32_t, 4GB/8=512MB的bitmap也就夠了, 這年頭,512記憶體的需求是很正常的.

和這個問題類似的一個問題:

已知一個web server的客戶ip地址日誌, 大約有40億條記錄, 如何判斷某個ip地址是否在這個日誌中?

這個問題由於有了上下文, 就要具體分析. 具體來說, 一個web server的訪問記錄不大可能是不重複的, 我們有理由假定許多記錄都是重複的, 所以一個較小的hash-table就可以了. 當然,hash-table小了, 會導致準確度的下降, 因為這時候的hash函數不是單射了.
為了保證成功, 512MB的bitmap還是可以考慮的.

這個問題的一個變種:

2.5億個uint32_t整數中, 尋找不重複的整數的個數.

1bit資訊只能判斷存在與否, 那麼是否可以附加1bit的資訊, 每個元素映射到2bit, 00表示不存在, 01表示出現1次, 10表示出現2次, 11表示更多, 則很容易就實現了.

這種做法可以換個思路來理解, 用兩個bitmap來判斷, 當bm1裡面沒有置位的時候,將bm1中對應的位置位; 當bm1中對應位置已經置位的時候, 就將bm2裡面的對應位置置位. 最後, 只要找到在bm1而不在bm2的那些bit位就可以了.

 

這種問題也可以產生一些變種, 譬如在64bit已經普及的今天:

已知40億個不重複的uint64_t, 如何判斷一個uint64_t在不在這個集合裡面?

在看這個問題之前, 先看一個更一般性的問題:

有一個proxy server的url訪問記錄, 大約有40億條記錄, 如何快速確定某個url是否在這個日誌中?

url不好處理,可以先用cryptographic hash function做一個hash(注意這種hash與通常所說的hash-table的hash的區別, 由於cryptographic
hash function的性質, 我們認為這種hash是抗碰撞的). MD5已經不行了, 目前我們可以假設160bit的SHA-1是抗碰撞的.

這就轉化成了: 已知40億個不重複的uint160_t, 如何判斷一個uint160_t在不在這個集合裡面?
 

對於以上問題, 由於可能的取值空間太大(2^64或者2^160),
直接bitmap記憶體肯定放不下了. 但是可以利用前面hash的思想, 將40億個元素通過hash拆分到多個小檔案(子集)中, 也即桶劃分(區段劃分). 具體拆分規則是這樣的, 假設我們的hash規則是選取前k位, 那麼將最多拆分成2^k個檔案, 而每個檔案至多有2^(64-k)個元素. ---- 事實上, 這種拆分還可以繼續細化為多級的拆分, 譬如前3bit用作第一級目錄名, 4-6bit用作第二級目錄名, 7-10bit用作檔案名稱…
 

當我們走了一遍拆分成2^k個小檔案以後, 每個小檔案都可以放到記憶體了, 剩下的就好辦了. 每個小檔案可以自身就是一個bitmap, 這樣對於給定的元素, 找到它應該在哪個子集(小檔案)裡面, 然後把那個檔案的內容拉到記憶體, whatever後續處理.
 

類似的思想也可以用於解決下面的這些相關問題.

已知有40億個不重複的uint32_t整數, 如何快速找到一個整數, 不在這40億個整數內?

已知有40億個不重複的uint32_t整數, 如何找到它們的中位元?

第一個問題, 拆分以後, 必定有若干個子集中元素個數小於2^(64-k), 表明這個子集的區段裡面, 是有不存在的元素的, 讀入這個檔案, 隨便搞就行了.

第二個問題, 拆分以後, 可以統計各個區段的元素個數, 立刻可以知道中位元位於哪個子集, 搞到記憶體裡, 很快就能找到了. 注: 讀入該子集以後, 由於子集中元素個數已知, 轉化為求一個n元素序列中第k大元素的問題, 這個問題可以用類似於qsort中partition的辦法, 線上性時間內解決, 參見http://www.cnblogs.com/qsort/archive/2011/05/09/2041653.html

 

這裡桶劃分(區段劃分)的思想並不新鮮, 譬如上面"判斷一個uint64_t是否在某集合裡面", 其實就是一個作業系統中線性地址是否已經映射的判斷, 而作業系統中關於地址空間頁表的分段管理(兩級或三級頁表), 就是上面的按區段劃分的典型例子.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.