大數據去重方案


數據庫中有有一張表專門存儲用戶的維度數據,由於隨着時間的推移,用戶的維度數據也可能發生變化,故每一次查看都會保存一次記錄。
現在需要對數據按用戶分析,但當中有大量的重復數據,僅用數據庫的等值去重明顯不可行。

對數據內容求MD5值

    MD5值的特點:
    1.壓縮性:任意長度的數據,算出的MD5值長度都是固定的。
    2.容易計算:從原數據計算出MD5值很容易。
    3.抗修改性:對原數據進行任何改動,哪怕只修改1個字節,所得到的MD5值都有很大區別。
    4.強抗碰撞:已知原數據和其MD5值,想找到一個具有相同MD5值的數據(即偽造數據)是非常困難的。

根據MD5值的特點,對每條記錄的維度數據內容計算MD5值,然后根據MD5值判斷重復記錄。

對數據入庫之后利用sql直接查出重復數據,然后將重復數據移除或者標記。

至少在現階段內存和CPU的執行效率在固定時間內是有限的,大量的數據的查重和去重處理不可能同時在內存中進行。就像外部排序算法和內部排序算法差別很大,遇到此類大量數據查重問題對算法進行設計是有必要的。

布隆過濾器

布隆過濾器是一種采用hash法進行查重的工具。它將每一條數據進行n次獨立的hash處理,每次處理得到一個整數,總共得到n個整數。使用一個很長的數組表示不同的整數,每一次插入操作把這n個整數對應的位置的0設置為1(如果已經被設置為1則不變)。下次查找的時候經過同樣的計算,如果這幾個位置都是1則說明已經存在。

布隆過濾器的優點是使用方便,因為並不將key存放進內存所以十分節省空間,多個hash算法無關,可以並發執行效率高。缺點也是顯而易見的,這種算法是可能出現錯誤,有誤判率這種概念。通過hash的次數我們可以降低誤判率,但是不能保證沒有誤判的情況。

BitMap

比如有2.5億個整數中找出不重復的整數的個數,內存空間不足以容納這2.5億個整數。

一個數字的狀態只有三種,分別為不存在,只有一個,有重復。因此,我們只需要2bits就可以對一個數字的狀態進行存儲了,假設我們設定一個數字不存在為00,存在一次01,存在兩次及其以上為11。那我們大概需要存儲空間幾十兆左右。接下來的任務就是遍歷一次這2.5億個數字,如果對應的狀態位為00,則將其變為01;如果對應的狀態位為01,則將其變為11;如果為11,,對應的轉態位保持不變。

最后,我們將狀態位為01的進行統計,就得到了不重復的數字個數,時間復雜度為O(n)。

hash分組

如果有兩份50G的數據,要查重,內存4G,怎么查?

想法是先將50G的數據分別做hash%1000,分成1000個文件,理論上hash做得好那么這1000個文件的大小是差不多接近的。如果有重復,那么A和B的重復數據一定在相對同一個文件內,因為hash結果是一樣的。將1000個文件分別加載進來,一一比對是否有hash重復。這種想法是先把所有數據按照相關性進行分組,相關的數據會處於同樣或者接近的位置中,再將小文件進行對比。

有1千萬條短信,找出重復出現最多的前10條?

可以用哈希表的方法對1千萬條分成若干組進行邊掃描邊建散列表。第一次掃描,取首字節,尾字節,中間隨便兩字節作為Hash Code,插入到hash table中。並記錄其地址和信息長度和重復次數,1千萬條信息,記錄這幾個信息還放得下。同Hash Code且等長就疑似相同,比較一下。相同記錄只加1次進hash table,但將重復次數加1。一次掃描以后,已經記錄各自的重復次數,進行第二次hash table的處理。用線性時間選擇可在O(n)的級別上完成前10條的尋找。分組后每份中的top10必須保證各不相同,可hash來保證,也可直接按hash值的大小來分類。

使用數據庫建立關鍵字段(一個或者多個)建立索引進行去重

根據url地址進行去重:

使用場景:url地址對應的數據不會變的情況,url地址能夠唯一判別一條數據的情況

思路:

  url存在Redis中

  拿到url地址,判斷url在Redis的集合中是否存在

    存在:說明url地址已經被請求過了,不在請求

    不存在:說明url地址沒有被請求過,請求,把該url地址存入Redis的集合中

布隆過濾器:

  使用多個加密算法加密url地址,得到多個值

  往對應值的位置把結果設置為1

  新來的一個url地址,一樣通過加密算法生成多個值

    如果對應位置的值全為1,說明這個url地址已經被抓取過了

    否則沒有被抓取過,就把對應的位置的值設置為1

根據數據本身進行去重:

  選擇特定的字段(能夠唯一標識數據的字段),使用加密算法(MD5,sha1)將字段進行加密,生成字符串,存入Redis的集合中

  后續新來一條數據,同樣的方式進行加密,

    如果得到的字符串在Redis中存在,說明數據存在,對數據進行更新,

    否則說明數據不存在,對數據進行插入。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM