日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

转:6.1海量数据处理

發(fā)布時間:2025/3/8 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 转:6.1海量数据处理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文轉(zhuǎn)自看云,原文地址請移步:https://www.kancloud.cn/kancloud/the-art-of-programming/41608

偶然閑游,偶遇某一站點,發(fā)現(xiàn)這里寫的關(guān)于海量數(shù)據(jù)處理相關(guān)的思路還挺不錯,所以在這里采摘收藏,如有侵權(quán)之處還請評論區(qū)或者站內(nèi)消息告知。


本文導讀:

所謂海量數(shù)據(jù)處理,是指基于海量數(shù)據(jù)的存儲、處理、和操作。正因為數(shù)據(jù)量太大,所以導致要么無法在較短時間內(nèi)迅速解決,要么無法一次性裝入內(nèi)存。

事實上,針對時間問題,可以采用巧妙的算法搭配合適的數(shù)據(jù)結(jié)構(gòu)(如布隆過濾器、哈希、位圖、堆、數(shù)據(jù)庫、倒排索引、Trie樹)來解決;而對于空間問題,可以采取分而治之(哈希映射)的方法,也就是說,把規(guī)模大的數(shù)據(jù)轉(zhuǎn)化為規(guī)模小的,從而各個擊破。

此外,針對常說的單機及集群問題,通俗來講,單機就是指處理裝載數(shù)據(jù)的機器有限(只要考慮CPU、內(nèi)存、和硬盤之間的數(shù)據(jù)交互),而集群的意思是指機器有多臺,適合分布式處理或并行計算,更多考慮節(jié)點與節(jié)點之間的數(shù)據(jù)交互。

一般說來,處理海量數(shù)據(jù)問題,有以下十種典型方法:

  • 1.哈希分治;
  • 2.simhash算法;
  • 3.外排序;
  • 4.MapReduce;
  • 5.多層劃分;
  • 6.位圖;
  • 7.布隆過濾器;
  • 8.Trie樹;
  • 9.數(shù)據(jù)庫;
  • 10.倒排索引。

受理論之限,本章將摒棄絕大部分的細節(jié),只談方法和模式論,注重用最通俗、最直白的語言闡述相關(guān)問題。最后,有一點必須強調(diào)的是,全章行文是基于面試題的分析基礎(chǔ)之上的,具體實踐過程中,還得視具體情況具體分析,且各個場景下需要考慮的細節(jié)也遠比本章所描述的任何一種解決方案復(fù)雜得多。


?6.1 關(guān)聯(lián)式容器

一般來說,STL容器分為:

  • 序列式容器(vector/list/deque/stack/queue/heap),和關(guān)聯(lián)式容器。
    • 其中,關(guān)聯(lián)式容器又分為set(集合)和map(映射表)兩大類,以及這兩大類的衍生體multiset(多鍵集合)和multimap(多鍵映射表),這些容器均以RB-tree(red-black tree, 紅黑樹)完成。
    • 此外,還有第3類關(guān)聯(lián)式容器,如hashtable(散列表),以及以hashtable為底層機制完成的hash_set(散列集合)/hash_map(散列映射表)/hash_multiset(散列多鍵集合)/hash_multimap(散列多鍵映射表)。也就是說,set/map/multiset/multimap都內(nèi)含一個RB-tree,而hash_set/hash_map/hash_multiset/hash_multimap都內(nèi)含一個hashtable。

所謂關(guān)聯(lián)式容器,類似關(guān)聯(lián)式數(shù)據(jù)庫,每筆數(shù)據(jù)或每個元素都有一個鍵值(key)和一個實值(value),即所謂的Key-Value(鍵-值對)。當元素被插入到關(guān)聯(lián)式容器中時,容器內(nèi)部結(jié)構(gòu)(RB-tree/hashtable)便依照其鍵值大小,以某種特定規(guī)則將這個元素放置于適當位置。

包括在非關(guān)聯(lián)式數(shù)據(jù)庫中,比如,在MongoDB內(nèi),文檔(document)是最基本的數(shù)據(jù)組織形式,每個文檔也是以Key-Value(鍵-值對)的方式組織起來。一個文檔可以有多個Key-Value組合,每個Value可以是不同的類型,比如String、Integer、List等等。

{ "name" : "July", "sex" : "male", "age" : 23 }

set/map/multiset/multimap

set,同map一樣,所有元素都會根據(jù)元素的鍵值自動被排序,因為set/map兩者的所有各種操作,都只是轉(zhuǎn)而調(diào)用RB-tree的操作行為,不過,值得注意的是,兩者都不允許兩個元素有相同的鍵值。

不同的是:set的元素不像map那樣可以同時擁有實值(value)和鍵值(key),set元素的鍵值就是實值,實值就是鍵值,而map的所有元素都是pair,同時擁有實值(value)和鍵值(key),pair的第一個元素被視為鍵值,第二個元素被視為實值。

至于multiset/multimap,他們的特性及用法和set/map完全相同,唯一的差別就在于它們允許鍵值重復(fù),即所有的插入操作基于RB-tree的insert_equal()而非insert_unique()。

hash_set/hash_map/hash_multiset/hash_multimap

hash_set/hash_map,兩者的一切操作都是基于hashtable之上。不同的是,hash_set同set一樣,同時擁有實值和鍵值,且實質(zhì)就是鍵值,鍵值就是實值,而hash_map同map一樣,每一個元素同時擁有一個實值(value)和一個鍵值(key),所以其使用方式,和上面的map基本相同。但由于hash_set/hash_map都是基于hashtable之上,所以不具備自動排序功能。為什么?因為hashtable沒有自動排序功能。

至于hash_multiset/hash_multimap的特性與上面的multiset/multimap完全相同,唯一的差別就是它們hash_multiset/hash_multimap的底層實現(xiàn)機制是hashtable(而multiset/multimap,上面說了,底層實現(xiàn)機制是RB-tree),所以它們的元素都不會被自動排序,不過也都允許鍵值重復(fù)。

所以,綜上,說白了,什么樣的結(jié)構(gòu)決定其什么樣的性質(zhì),因為set/map/multiset/multimap都是基于RB-tree之上,所以有自動排序功能,而hash_set/hash_map/hash_multiset/hash_multimap都是基于hashtable之上,所以不含有自動排序功能,至于加個前綴multi_無非就是允許鍵值重復(fù)而已。


?

?6.2 分而治之

方法介紹

對于海量數(shù)據(jù)而言,由于無法一次性裝進內(nèi)存處理,導致我們不得不把海量的數(shù)據(jù)通過hash映射分割成相應(yīng)的小塊數(shù)據(jù),然后再針對各個小塊數(shù)據(jù)通過hash_map進行統(tǒng)計或其它操作。

那什么是hash映射呢?簡單來說,就是為了便于計算機在有限的內(nèi)存中處理big數(shù)據(jù),我們通過一種映射散列的方式讓數(shù)據(jù)均勻分布在對應(yīng)的內(nèi)存位置(如大數(shù)據(jù)通過取余的方式映射成小數(shù)存放在內(nèi)存中,或大文件映射成多個小文件),而這個映射散列方式便是我們通常所說的hash函數(shù),設(shè)計的好的hash函數(shù)能讓數(shù)據(jù)均勻分布而減少沖突。

問題實例

1、海量日志數(shù)據(jù),提取出某日訪問百度次數(shù)最多的那個IP

分析:百度作為國內(nèi)第一大搜索引擎,每天訪問它的IP數(shù)量巨大,如果想一次性把所有IP數(shù)據(jù)裝進內(nèi)存處理,則內(nèi)存容量明顯不夠,故針對數(shù)據(jù)太大,內(nèi)存受限的情況,可以把大文件轉(zhuǎn)化成(取模映射)小文件,從而大而化小,逐個處理。

換言之,先映射,而后統(tǒng)計,最后排序。

解法:具體分為以下3個步驟

  • 1.分而治之/hash映射
    • 首先把這一天訪問百度日志的所有IP提取出來,然后逐個寫入到一個大文件中,接著采用映射的方法,比如%1000,把整個大文件映射為1000個小文件。
  • 2.hash_map統(tǒng)計
    • 當大文件轉(zhuǎn)化成了小文件,那么我們便可以采用hash_map(ip, value)來分別對1000個小文件中的IP進行頻率統(tǒng)計,再找出每個小文件中出現(xiàn)頻率最大的IP。
  • 3.堆/快速排序
    • 統(tǒng)計出1000個頻率最大的IP后,依據(jù)各自頻率的大小進行排序(可采取堆排序),找出那個頻率最大的IP,即為所求。

注:Hash取模是一種等價映射,不會存在同一個元素分散到不同小文件中去的情況,即這里采用的是%1000算法,那么同一個IP在hash后,只可能落在同一個文件中,不可能被分散的。

2、尋找熱門查詢,300萬個查詢字符串中統(tǒng)計最熱門的10個查詢

原題:搜索引擎會通過日志文件把用戶每次檢索使用的所有檢索串都記錄下來,每個查詢串的長度為1-255字節(jié)。假設(shè)目前有一千萬個記錄,請你統(tǒng)計最熱門的10個查詢串,要求使用的內(nèi)存不能超過1G。

分析:這些查詢串的重復(fù)度比較高,雖然總數(shù)是1千萬,但如果除去重復(fù)后,不超過3百萬個。一個查詢串的重復(fù)度越高,說明查詢它的用戶越多,也就是越熱門。

由上面第1題,我們知道,數(shù)據(jù)大則劃為小的,例如一億個ip求Top 10,可先%1000將ip分到1000個小文件中去,并保證一種ip只出現(xiàn)在一個文件中,再對每個小文件中的ip進行hash_map統(tǒng)計并按數(shù)量排序,最后歸并或者最小堆依次處理每個小文件的top10以得到最后的結(jié)果。

但對于本題,數(shù)據(jù)規(guī)模比較小,能一次性裝入內(nèi)存。因為根據(jù)題目描述,雖然有一千萬個Query,但是由于重復(fù)度比較高,故去除重復(fù)后,事實上只有300萬的Query,每個Query255Byte,因此我們可以考慮把他們都放進內(nèi)存中去(300萬個字符串假設(shè)沒有重復(fù),都是最大長度,那么最多占用內(nèi)存3M*1K/4=0.75G。所以可以將所有字符串都存放在內(nèi)存中進行處理)。

所以我們放棄分而治之/hash映射的步驟,直接上hash_map統(tǒng)計,然后排序。So,針對此類典型的TOP K問題,采取的對策往往是:hash_map + 堆。

解法:

  • 1.hash_map統(tǒng)計
    • 先對這批海量數(shù)據(jù)預(yù)處理。具體方法是:維護一個Key為Query字串,Value為該Query出現(xiàn)次數(shù)的hash_map,即hash_map(Query, Value),每次讀取一個Query,如果該字串不在Table中,那么加入該字串,并將Value值設(shè)為1;如果該字串在Table中,那么將該字串的計數(shù)加1 即可。最終我們在O(N)的時間復(fù)雜度內(nèi)用hash_map完成了統(tǒng)計;
  • 2.堆排序
    • 借助堆這個數(shù)據(jù)結(jié)構(gòu),找出Top K,時間復(fù)雜度為N‘logK。即借助堆結(jié)構(gòu),我們可以在log量級的時間內(nèi)查找和調(diào)整/移動。因此,維護一個K(該題目中是10)大小的小根堆,然后遍歷300萬的Query,分別和根元素進行對比。所以,我們最終的時間復(fù)雜度是:O(n) + N' * O(logk),其中,N為1000萬,N’為300萬。

關(guān)于第2步堆排序,可以維護k個元素的最小堆,即用容量為k的最小堆存儲最先遍歷到的k個數(shù),并假設(shè)它們即是最大的k個數(shù),建堆費時O(k),并調(diào)整堆(費時O(logk))后,有k1>k2>...kmin(kmin設(shè)為小頂堆中最小元素)。繼續(xù)遍歷數(shù)列,每次遍歷一個元素x,與堆頂元素比較,若x>kmin,則更新堆(x入堆,用時logk),否則不更新堆。這樣下來,總費時O(k_logk+(n-k)_logk)=O(n*logk)。此方法得益于在堆中,查找等各項操作時間復(fù)雜度均為logk。

當然,你也可以采用trie樹,關(guān)鍵字域存該查詢串出現(xiàn)的次數(shù),沒有出現(xiàn)為0。最后用10個元素的最小推來對出現(xiàn)頻率進行排序。

3、有一個1G大小的一個文件,里面每一行是一個詞,詞的大小不超過16字節(jié),內(nèi)存限制大小是1M。返回頻數(shù)最高的100個詞

解法:

  • 1.分而治之/hash映射
    • 順序讀取文件,對于每個詞x,取hash(x)%5000,然后把該值存到5000個小文件(記為x0,x1,...x4999)中。這樣每個文件大概是200k左右。當然,如果其中有的小文件超過了1M大小,還可以按照類似的方法繼續(xù)往下分,直到分解得到的小文件的大小都不超過1M。
  • 2.hash_map統(tǒng)計
    • 對每個小文件,采用trie樹/hash_map等統(tǒng)計每個文件中出現(xiàn)的詞以及相應(yīng)的頻率。
  • 3.堆/歸并排序
    • 取出出現(xiàn)頻率最大的100個詞(可以用含100個結(jié)點的最小堆)后,再把100個詞及相應(yīng)的頻率存入文件,這樣又得到了5000個文件。最后就是把這5000個文件進行歸并(類似于歸并排序)的過程了。

4、海量數(shù)據(jù)分布在100臺電腦中,想個辦法高效統(tǒng)計出這批數(shù)據(jù)的TOP10

解法一:

如果同一個數(shù)據(jù)元素只出現(xiàn)在某一臺機器中,那么可以采取以下步驟統(tǒng)計出現(xiàn)次數(shù)TOP10的數(shù)據(jù)元素:

  • 1.堆排序
    • 在每臺電腦上求出TOP 10,可以采用包含10個元素的堆完成(TOP 10小,用最大堆,TOP 10大,用最小堆,比如求TOP10大,我們首先取前10個元素調(diào)整成最小堆,如果發(fā)現(xiàn),然后掃描后面的數(shù)據(jù),并與堆頂元素比較,如果比堆頂元素大,那么用該元素替換堆頂,然后再調(diào)整為最小堆。最后堆中的元素就是TOP 10大)。
  • 2.組合歸并
    • 求出每臺電腦上的TOP 10后,然后把這100臺電腦上的TOP 10組合起來,共1000個數(shù)據(jù),再利用上面類似的方法求出TOP 10就可以了。

解法二:

但如果同一個元素重復(fù)出現(xiàn)在不同的電腦中呢,比如拿兩臺機器求top 2的情況來說:

  • 第一臺的數(shù)據(jù)分布及各自出現(xiàn)頻率為:a(50),b(50),c(49),d(49) ,e(0),f(0)
    • 其中,括號里的數(shù)字代表某個數(shù)據(jù)出現(xiàn)的頻率,如a(50)表示a出現(xiàn)了50次。
  • 第二臺的數(shù)據(jù)分布及各自出現(xiàn)頻率為:a(0),b(0),c(49),d(49),e(50),f(50)

這個時候,你可以有兩種方法:

  • 遍歷一遍所有數(shù)據(jù),重新hash取摸,如此使得同一個元素只出現(xiàn)在單獨的一臺電腦中,然后采用上面所說的方法,統(tǒng)計每臺電腦中各個元素的出現(xiàn)次數(shù)找出TOP 10,繼而組合100臺電腦上的TOP 10,找出最終的TOP 10。
  • 或者,暴力求解:直接統(tǒng)計統(tǒng)計每臺電腦中各個元素的出現(xiàn)次數(shù),然后把同一個元素在不同機器中的出現(xiàn)次數(shù)相加,最終從所有數(shù)據(jù)中找出TOP 10。

5、有10個文件,每個文件1G,每個文件的每一行存放的都是用戶的query,每個文件的query都可能重復(fù)。要求你按照query的頻度排序

解法一:

  • 1.hash映射
    • 順序讀取10個文件,按照hash(query)%10的結(jié)果將query寫入到另外10個文件(記為a0,a1,..a9)中。這樣新生成的文件每個的大小大約也1G(假設(shè)hash函數(shù)是隨機的)。
  • 2.hash_map統(tǒng)計
    • 找一臺內(nèi)存在2G左右的機器,依次對用hash_map(query, query_count)來統(tǒng)計每個query出現(xiàn)的次數(shù)。注:hash_map(query, query_count)是用來統(tǒng)計每個query的出現(xiàn)次數(shù),不是存儲他們的值,出現(xiàn)一次,則count+1。
  • 3.堆/快速/歸并排序
    • 利用快速/堆/歸并排序按照出現(xiàn)次數(shù)進行排序,將排序好的query和對應(yīng)的query_cout輸出到文件中,這樣得到了10個排好序的文件(記為)。最后,對這10個文件進行歸并排序(內(nèi)排序與外排序相結(jié)合)。

解法二:

一般query的總量是有限的,只是重復(fù)的次數(shù)比較多而已,可能對于所有的query,一次性就可以加入到內(nèi)存了。這樣,我們就可以采用trie樹/hash_map等直接來統(tǒng)計每個query出現(xiàn)的次數(shù),然后按出現(xiàn)次數(shù)做快速/堆/歸并排序就可以了。

解法三:

與解法1類似,但在做完hash,分成多個文件后,可以交給多個文件來處理,采用分布式的架構(gòu)來處理(比如MapReduce),最后再進行合并。

6、給定a、b兩個文件,各存放50億個url,每個url各占64字節(jié),內(nèi)存限制是4G,讓你找出a、b文件共同的url?

解法:

可以估計每個文件安的大小為5G×64=320G,遠遠大于內(nèi)存限制的4G。所以不可能將其完全加載到內(nèi)存中處理??紤]采取分而治之的方法。

  • 1.分而治之/hash映射
    • 遍歷文件a,對每個url求取,然后根據(jù)所取得的值將url分別存儲到1000個小文件(記為,這里漏寫個了a1)中。這樣每個小文件的大約為300M。遍歷文件b,采取和a相同的方式將url分別存儲到1000小文件中(記為)。這樣處理后,所有可能相同的url都在對應(yīng)的小文件()中,不對應(yīng)的小文件不可能有相同的url。然后我們只要求出1000對小文件中相同的url即可。
  • 2.hash_set統(tǒng)計
    • 求每對小文件中相同的url時,可以把其中一個小文件的url存儲到hash_set中。然后遍歷另一個小文件的每個url,看其是否在剛才構(gòu)建的hash_set中,如果是,那么就是共同的url,存到文件里面就可以了。

7、100萬個數(shù)中找出最大的100個數(shù)

解法一:采用局部淘汰法。選取前100個元素,并排序,記為序列L。然后一次掃描剩余的元素x,與排好序的100個元素中最小的元素比,如果比這個最小的要大,那么把這個最小的元素刪除,并把x利用插入排序的思想,插入到序列L中。依次循環(huán),知道掃描了所有的元素。復(fù)雜度為O(100萬*100)。

解法二:采用快速排序的思想,每次分割之后只考慮比軸大的一部分,知道比軸大的一部分在比100多的時候,采用傳統(tǒng)排序算法排序,取前100個。復(fù)雜度為O(100萬*100)。

解法三:在前面的題中,我們已經(jīng)提到了,用一個含100個元素的最小堆完成。復(fù)雜度為O(100萬*lg100)。

舉一反三

1、怎么在海量數(shù)據(jù)中找出重復(fù)次數(shù)最多的一個?

提示:先做hash,然后求模映射為小文件,求出每個小文件中重復(fù)次數(shù)最多的一個,并記錄重復(fù)次數(shù)。然后找出上一步求出的數(shù)據(jù)中重復(fù)次數(shù)最多的一個就是所求(具體參考前面的題)。

2、上千萬或上億數(shù)據(jù)(有重復(fù)),統(tǒng)計其中出現(xiàn)次數(shù)最多的前N個數(shù)據(jù)。

提示:上千萬或上億的數(shù)據(jù),現(xiàn)在的機器的內(nèi)存應(yīng)該能存下。所以考慮采用hash_map/搜索二叉樹/紅黑樹等來進行統(tǒng)計次數(shù)。然后就是取出前N個出現(xiàn)次數(shù)最多的數(shù)據(jù)了,可以用第2題提到的堆機制完成。

3、一個文本文件,大約有一萬行,每行一個詞,要求統(tǒng)計出其中最頻繁出現(xiàn)的前10個詞,請給出思想,給出時間復(fù)雜度分析。

提示:這題是考慮時間效率。用trie樹統(tǒng)計每個詞出現(xiàn)的次數(shù),時間復(fù)雜度是O(nle)(le表示單詞的平準長度)。然后是找出出現(xiàn)最頻繁的前10個詞,可以用堆來實現(xiàn),前面的題中已經(jīng)講到了,時間復(fù)雜度是O(nlg10)。所以總的時間復(fù)雜度,是O(nle)與O(nlg10)中較大的哪一個。

4、1000萬字符串,其中有些是重復(fù)的,需要把重復(fù)的全部去掉,保留沒有重復(fù)的字符串。請怎么設(shè)計和實現(xiàn)?

提示:這題用trie樹比較合適,hash_map也行。當然,也可以先hash成小文件分開處理再綜合。

5、一個文本文件,找出前10個經(jīng)常出現(xiàn)的詞,但這次文件比較長,說是上億行或十億行,總之無法一次讀入內(nèi)存,問最優(yōu)解。

提示:首先根據(jù)用hash并求模,將文件分解為多個小文件,對于單個文件利用上題的方法求出每個文件件中10個最常出現(xiàn)的詞。然后再進行歸并處理,找出最終的10個最常出現(xiàn)的詞。


6.3 simhash算法

方法介紹

背景

如果某一天,面試官問你如何設(shè)計一個比較兩篇文章相似度的算法?可能你會回答幾個比較傳統(tǒng)點的思路:

  • 一種方案是先將兩篇文章分別進行分詞,得到一系列特征向量,然后計算特征向量之間的距離(可以計算它們之間的歐氏距離、海明距離或者夾角余弦等等),從而通過距離的大小來判斷兩篇文章的相似度。
  • 另外一種方案是傳統(tǒng)hash,我們考慮為每一個web文檔通過hash的方式生成一個指紋(finger print)。

下面,我們來分析下這兩種方法。

  • 采取第一種方法,若是只比較兩篇文章的相似性還好,但如果是海量數(shù)據(jù)呢,有著數(shù)以百萬甚至億萬的網(wǎng)頁,要求你計算這些網(wǎng)頁的相似度。你還會去計算任意兩個網(wǎng)頁之間的距離或夾角余弦么?想必你不會了。
  • 而第二種方案中所說的傳統(tǒng)加密方式md5,其設(shè)計的目的是為了讓整個分布盡可能地均勻,但如果輸入內(nèi)容一旦出現(xiàn)哪怕輕微的變化,hash值就會發(fā)生很大的變化。

舉個例子,我們假設(shè)有以下三段文本:

  • the cat sat on the mat
  • the cat sat on a mat
  • we all scream for ice cream

使用傳統(tǒng)hash可能會得到如下的結(jié)果:

  • irb(main):006:0> p1 = 'the cat sat on the mat'
    • irb(main):007:0> p1.hash => 415542861
  • irb(main):005:0> p2 = 'the cat sat on a mat'
    • irb(main):007:0> p2.hash => 668720516
  • irb(main):007:0> p3 = 'we all scream for ice cream'
    • irb(main):007:0> p3.hash => 767429688 "

可理想當中的hash函數(shù),需要對幾乎相同的輸入內(nèi)容,產(chǎn)生相同或者相近的hash值,換言之,hash值的相似程度要能直接反映輸入內(nèi)容的相似程度,故md5等傳統(tǒng)hash方法也無法滿足我們的需求。

出世

車到山前必有路,來自于GoogleMoses Charikar發(fā)表的一篇論文“detecting near-duplicates for web crawling”中提出了simhash算法,專門用來解決億萬級別的網(wǎng)頁的去重任務(wù)。

simhash作為locality sensitive hash(局部敏感哈希)的一種:

  • 其主要思想是降維,將高維的特征向量映射成低維的特征向量,通過兩個向量的Hamming Distance來確定文章是否重復(fù)或者高度近似。
    • 其中,Hamming Distance,又稱漢明距離,在信息論中,兩個等長字符串之間的漢明距離是兩個字符串對應(yīng)位置的不同字符的個數(shù)。也就是說,它就是將一個字符串變換成另外一個字符串所需要替換的字符個數(shù)。例如:1011101 與 1001001 之間的漢明距離是 2。至于我們常說的字符串編輯距離則是一般形式的漢明距離。

如此,通過比較多個文檔的simHash值的海明距離,可以獲取它們的相似度。

流程

simhash算法分為5個步驟:分詞、hash、加權(quán)、合并、降維,具體過程如下所述:

  • 分詞
    • 給定一段語句,進行分詞,得到有效的特征向量,然后為每一個特征向量設(shè)置1-5等5個級別的權(quán)重(如果是給定一個文本,那么特征向量可以是文本中的詞,其權(quán)重可以是這個詞出現(xiàn)的次數(shù))。例如給定一段語句:“CSDN博客結(jié)構(gòu)之法算法之道的作者July”,分詞后為:“CSDN 博客 結(jié)構(gòu) 之 法 算法 之 道 的 作者 July”,然后為每個特征向量賦予權(quán)值:CSDN(4) 博客(5) 結(jié)構(gòu)(3) 之(1) 法(2) 算法(3) 之(1) 道(2) 的(1) 作者(5) July(5),其中括號里的數(shù)字代表這個單詞在整條語句中的重要程度,數(shù)字越大代表越重要。
  • hash
    • 通過hash函數(shù)計算各個特征向量的hash值,hash值為二進制數(shù)01組成的n-bit簽名。比如“CSDN”的hash值Hash(CSDN)為100101,“博客”的hash值Hash(博客)為“101011”。就這樣,字符串就變成了一系列數(shù)字。
  • 加權(quán)
    • 在hash值的基礎(chǔ)上,給所有特征向量進行加權(quán),即W = Hash * weight,且遇到1則hash值和權(quán)值正相乘,遇到0則hash值和權(quán)值負相乘。例如給“CSDN”的hash值“100101”加權(quán)得到:W(CSDN) = 100101_4 = 4 -4 -4 4 -4 4,給“博客”的hash值“101011”加權(quán)得到:W(博客)=101011_5 = 5 -5 5 -5 5 5,其余特征向量類似此般操作。
  • 合并
    • 將上述各個特征向量的加權(quán)結(jié)果累加,變成只有一個序列串。拿前兩個特征向量舉例,例如“CSDN”的“4 -4 -4 4 -4 4”和“博客”的“5 -5 5 -5 5 5”進行累加,得到“4+5 -4+-5 -4+5 4+-5 -4+5 4+5”,得到“9 -9 1 -1 1”。
  • 降維
    • 對于n-bit簽名的累加結(jié)果,如果大于0則置1,否則置0,從而得到該語句的simhash值,最后我們便可以根據(jù)不同語句simhash的海明距離來判斷它們的相似度。例如把上面計算出來的“9 -9 1 -1 1 9”降維(某位大于0記為1,小于0記為0),得到的01串為:“1 0 1 0 1 1”,從而形成它們的simhash簽名。

其流程如下圖所示:?

應(yīng)用

  • 每篇文檔得到SimHash簽名值后,接著計算兩個簽名的海明距離即可。根據(jù)經(jīng)驗值,對64位的 SimHash值,海明距離在3以內(nèi)的可認為相似度比較高。
    • 海明距離的求法:異或時,只有在兩個比較的位不同時其結(jié)果是1 ,否則結(jié)果為0,兩個二進制“異或”后得到1的個數(shù)即為海明距離的大小。

舉個例子,上面我們計算到的“CSDN博客”的simhash簽名值為“1 0 1 0 1 1”,假定我們計算出另外一個短語的簽名值為“1 0 1 0 0 0”,那么根據(jù)異或規(guī)則,我們可以計算出這兩個簽名的海明距離為2,從而判定這兩個短語的相似度是比較高的。

換言之,現(xiàn)在問題轉(zhuǎn)換為:對于64位的SimHash值,我們只要找到海明距離在3以內(nèi)的所有簽名,即可找出所有相似的短語。

但關(guān)鍵是,如何將其擴展到海量數(shù)據(jù)呢?譬如如何在海量的樣本庫中查詢與其海明距離在3以內(nèi)的記錄呢?

  • 一種方案是查找待查詢文本的64位simhash code的所有3位以內(nèi)變化的組合
    • 大約需要四萬多次的查詢。
  • 另一種方案是預(yù)生成庫中所有樣本simhash code的3位變化以內(nèi)的組合
    • 大約需要占據(jù)4萬多倍的原始空間。

這兩種方案,要么時間復(fù)雜度高,要么空間復(fù)雜度復(fù)雜,能否有一種方案可以達到時空復(fù)雜度的絕佳平衡呢?答案是肯定的:

  • 我們可以把 64 位的二進制simhash簽名均分成4塊,每塊16位。根據(jù)鴿巢原理(也稱抽屜原理),如果兩個簽名的海明距離在 3 以內(nèi),它們必有一塊完全相同。如下圖所示:?
  • 然后把分成的4 塊中的每一個塊分別作為前16位來進行查找,建倒排索引。

具體如下圖所示:

如此,如果樣本庫中存有2^34(差不多10億)的simhash簽名,則每個table返回2^(34-16)=262144個候選結(jié)果,大大減少了海明距離的計算成本。

  • 假設(shè)數(shù)據(jù)是均勻分布,16位的數(shù)據(jù),產(chǎn)生的像限為2^16個,則平均每個像限分布的文檔數(shù)則為2^34/2^16 = 2^(34-16)) ,四個塊返回的總結(jié)果數(shù)為 4* 262144 (大概 100 萬)。
    • 這樣,原本需要比較10億次,經(jīng)過索引后,大概只需要處理100萬次。

(部分內(nèi)容及圖片參考自:http://grunt1223.iteye.com/blog/964564?,后續(xù)圖片會全部重畫)

問題實例

待續(xù)。

@復(fù)旦李斌:simhash不是google發(fā)明的,是princeton的人早在stoc02上發(fā)表的。google在www07上的那篇論文只是在網(wǎng)頁查重上應(yīng)用了下。事實上www07中的算法是stoc02中隨機超平面的一個極其巧妙的實現(xiàn),bit差異的期望正好等于原姶向量的余弦。


6.4 外排序

方法介紹

所謂外排序,顧名思義,即是在內(nèi)存外面的排序,因為當要處理的數(shù)據(jù)量很大,而不能一次裝入內(nèi)存時,此時只能放在讀寫較慢的外存儲器(通常是硬盤)上。

外排序通常采用的是一種“排序-歸并”的策略。

  • 在排序階段,先讀入能放在內(nèi)存中的數(shù)據(jù)量,將其排序輸出到一個臨時文件,依此進行,將待排序數(shù)據(jù)組織為多個有序的臨時文件;
  • 爾后在歸并階段將這些臨時文件組合為一個大的有序文件,也即排序結(jié)果。

假定現(xiàn)在有20個數(shù)據(jù)的文件A:{5 11 0 18 4 14 9 7 6 8 12 17 16 13 19 10 2 1 3 15},但一次只能使用僅裝4個數(shù)據(jù)的內(nèi)容,所以,我們可以每趟對4個數(shù)據(jù)進行排序,即5路歸并,具體方法如下述步驟:

  • 我們先把“大”文件A,分割為a1,a2,a3,a4,a5等5個小文件,每個小文件4個數(shù)據(jù)

    • a1文件為:5 11 0 18
    • a2文件為:4 14 9 7
    • a3文件為:6 8 12 17
    • a4文件為:16 13 19 10
    • a5文件為:2 1 3 15
  • 然后依次對5個小文件分別進行排序

    • a1文件完成排序后:0 5 11 18
    • a2文件完成排序后:4 7 9 14
    • a3文件完成排序后:6 8 12 17
    • a4文件完成排序后:10 13 16 19
    • a5文件完成排序后:1 2 3 15
  • 最終多路歸并,完成整個排序

    • 整個大文件A文件完成排序后:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

問題實例

1、給10^7個數(shù)據(jù)量的磁盤文件排序

輸入:給定一個文件,里面最多含有n個不重復(fù)的正整數(shù)(也就是說可能含有少于n個不重復(fù)正整數(shù)),且其中每個數(shù)都小于等于n,n=10^7。 輸出:得到按從小到大升序排列的包含所有輸入的整數(shù)的列表。 條件:最多有大約1MB的內(nèi)存空間可用,但磁盤空間足夠。且要求運行時間在5分鐘以下,10秒為最佳結(jié)果。

解法一:位圖方案

你可能會想到把磁盤文件進行歸并排序,但題目要求你只有1MB的內(nèi)存空間可用,所以,歸并排序這個方法不行。

熟悉位圖的朋友可能會想到用位圖來表示這個文件集合。例如正如編程珠璣一書上所述,用一個20位長的字符串來表示一個所有元素都小于20的簡單的非負整數(shù)集合,邊框用如下字符串來表示集合{1,2,3,5,8,13}:

0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0

上述集合中各數(shù)對應(yīng)的位置則置1,沒有對應(yīng)的數(shù)的位置則置0。

參考編程珠璣一書上的位圖方案,針對我們的10^7個數(shù)據(jù)量的磁盤文件排序問題,我們可以這么考慮,由于每個7位十進制整數(shù)表示一個小于1000萬的整數(shù)。我們可以使用一個具有1000萬個位的字符串來表示這個文件,其中,當且僅當整數(shù)i在文件中存在時,第i位為1。采取這個位圖的方案是因為我們面對的這個問題的特殊性:

  • 輸入數(shù)據(jù)限制在相對較小的范圍內(nèi),
  • 數(shù)據(jù)沒有重復(fù),
  • 其中的每條記錄都是單一的整數(shù),沒有任何其它與之關(guān)聯(lián)的數(shù)據(jù)。
  • 所以,此問題用位圖的方案分為以下三步進行解決:

    • 第一步,將所有的位都置為0,從而將集合初始化為空。
    • 第二步,通過讀入文件中的每個整數(shù)來建立集合,將每個對應(yīng)的位都置為1。
    • 第三步,檢驗每一位,如果該位為1,就輸出對應(yīng)的整數(shù)。

    經(jīng)過以上三步后,產(chǎn)生有序的輸出文件。令n為位圖向量中的位數(shù)(本例中為1000 0000),程序可以用偽代碼表示如下:

    //磁盤文件排序位圖方案的偽代碼 //copyright@ Jon Bentley //July、updated,2011.05.29。 //第一步,將所有的位都初始化為0 for i ={0,....n} bit[i]=0; //第二步,通過讀入文件中的每個整數(shù)來建立集合,將每個對應(yīng)的位都置為1。 for each i in the input file bit[i]=1; //第三步,檢驗每一位,如果該位為1,就輸出對應(yīng)的整數(shù)。 for i={0...n} if bit[i]==1 write i on the output file

    上述的位圖方案,共需要掃描輸入數(shù)據(jù)兩次,具體執(zhí)行步驟如下:

    第一次,只處理1—4999999之間的數(shù)據(jù),這些數(shù)都是小于5000000的,對這些數(shù)進行位圖排序,只需要約5000000/8=625000Byte,也就是0.625M,排序后輸出。 第二次,掃描輸入文件時,只處理4999999-10000000的數(shù)據(jù)項,也只需要0.625M(可以使用第一次處理申請的內(nèi)存)。 因此,總共也只需要0.625M 位圖的的方法有必要強調(diào)一下,就是位圖的適用范圍為針對不重復(fù)的數(shù)據(jù)進行排序,若數(shù)據(jù)有重復(fù),位圖方案就不適用了。

    不過很快,我們就將意識到,用此位圖方法,嚴格說來還是不太行,空間消耗10^7/8還是大于1M(1M=1024*1024空間,小于10^7/8)。

    既然如果用位圖方案的話,我們需要約1.25MB(若每條記錄是8位的正整數(shù)的話,則10000000/(1024_1024_8) ~= 1.2M)的空間,而現(xiàn)在只有1MB的可用存儲空間,那么究竟該作何處理呢?

    解法二:多路歸并

    誠然,在面對本題時,還可以通過計算分析出可以用如2的位圖法解決,但實際上,很多的時候,我們都面臨著這樣一個問題,文件太大,無法一次性放入內(nèi)存中計算處理,那這個時候咋辦呢?分而治之,大而化小,也就是把整個大文件分為若干大小的幾塊,然后分別對每一塊進行排序,最后完成整個過程的排序。k趟算法可以在kn的時間開銷內(nèi)和n/k的空間開銷內(nèi)完成對最多n個小于n的無重復(fù)正整數(shù)的排序。

    比如可分為2塊(k=2,1趟反正占用的內(nèi)存只有1.25/2M),1~4999999,和5000000~9999999。先遍歷一趟,首先排序處理1~4999999之間的整數(shù)(用5000000/8=625000個字的存儲空間來排序0~4999999之間的整數(shù)),然后再第二趟,對5000001~1000000之間的整數(shù)進行排序處理。

    解法總結(jié)

    1、關(guān)于本章中位圖和多路歸并兩種方案的時間復(fù)雜度及空間復(fù)雜度的比較,如下:

    時間復(fù)雜度 空間復(fù)雜度位圖 O(N) 0.625M多位歸并 O(Nlogn) 1M

    (多路歸并,時間復(fù)雜度為O(k_n/k_logn/k ),嚴格來說,還要加上讀寫磁盤的時間,而此算法絕大部分時間也是浪費在這上面)

    2、bit-map

    適用范圍:可進行數(shù)據(jù)的快速查找,判重,刪除,一般來說數(shù)據(jù)范圍是int的10倍以下

    基本原理及要點:使用bit數(shù)組來表示某些元素是否存在,比如8位電話號碼

    擴展:bloom filter可以看做是對bit-map的擴展

    舉一反三

    1、已知某個文件內(nèi)包含一些電話號碼,每個號碼為8位數(shù)字,統(tǒng)計不同號碼的個數(shù)。 8位最多99 999 999,大概需要99m個bit,大概10幾m字節(jié)的內(nèi)存即可。


    6.5 MapReduce

    方法介紹

    MapReduce是一種計算模型,簡單的說就是將大批量的工作(數(shù)據(jù))分解(MAP)執(zhí)行,然后再將結(jié)果合并成最終結(jié)果(REDUCE)。這樣做的好處是可以在任務(wù)被分解后,可以通過大量機器進行并行計算,減少整個操作的時間。但如果你要我再通俗點介紹,那么,說白了,Mapreduce的原理就是一個歸并排序。

    適用范圍:數(shù)據(jù)量大,但是數(shù)據(jù)種類小可以放入內(nèi)存

    基本原理及要點:將數(shù)據(jù)交給不同的機器去處理,數(shù)據(jù)劃分,結(jié)果歸約。

    基礎(chǔ)架構(gòu)

    想讀懂此文,讀者必須先要明確以下幾點,以作為閱讀后續(xù)內(nèi)容的基礎(chǔ)知識儲備:

  • MapReduce是一種模式。
  • Hadoop是一種框架。
  • Hadoop是一個實現(xiàn)了MapReduce模式的開源的分布式并行編程框架。
  • 所以,你現(xiàn)在,知道了什么是MapReduce,什么是hadoop,以及這兩者之間最簡單的聯(lián)系,而本文的主旨即是,一句話概括:在hadoop的框架上采取MapReduce的模式處理海量數(shù)據(jù)。下面,咱們可以依次深入學習和了解MapReduce和hadoop這兩個東西了。

    MapReduce模式

    前面說了,MapReduce是一種模式,一種什么模式呢?一種云計算的核心計算模式,一種分布式運算技術(shù),也是簡化的分布式編程模式,它主要用于解決問題的程序開發(fā)模型,也是開發(fā)人員拆解問題的方法。

    Ok,光說不上圖,沒用。如下圖所示,MapReduce模式的主要思想是將自動分割要執(zhí)行的問題(例如程序)拆解成Map(映射)和Reduce(化簡)的方式,流程圖如下圖1所示:

    在數(shù)據(jù)被分割后通過Map函數(shù)的程序?qū)?shù)據(jù)映射成不同的區(qū)塊,分配給計算機機群處理達到分布式運算的效果,在通過Reduce 函數(shù)的程序?qū)⒔Y(jié)果匯整,從而輸出開發(fā)者需要的結(jié)果。

    MapReduce借鑒了函數(shù)式程序設(shè)計語言的設(shè)計思想,其軟件實現(xiàn)是指定一個Map函數(shù),把鍵值對(key/value)映射成新的鍵值對(key/value),形成一系列中間結(jié)果形式的key/value 對,然后把它們傳給Reduce(規(guī)約)函數(shù),把具有相同中間形式key的value合并在一起。Map和Reduce函數(shù)具有一定的關(guān)聯(lián)性。函數(shù)描述如表1 所示:

    MapReduce致力于解決大規(guī)模數(shù)據(jù)處理的問題,因此在設(shè)計之初就考慮了數(shù)據(jù)的局部性原理,利用局部性原理將整個問題分而治之。MapReduce集群由普通PC機構(gòu)成,為無共享式架構(gòu)。在處理之前,將數(shù)據(jù)集分布至各個節(jié)點。處理時,每個節(jié)點就近讀取本地存儲的數(shù)據(jù)處理(map),將處理后的數(shù)據(jù)進行合并(combine)、排序(shuffle and sort)后再分發(fā)(至reduce節(jié)點),避免了大量數(shù)據(jù)的傳輸,提高了處理效率。無共享式架構(gòu)的另一個好處是配合復(fù)制(replication)策略,集群可以具有良好的容錯性,一部分節(jié)點的down機對集群的正常工作不會造成影響。

    ok,你可以再簡單看看下副圖,整幅圖是有關(guān)hadoop的作業(yè)調(diào)優(yōu)參數(shù)及原理,圖的左邊是MapTask運行示意圖,右邊是ReduceTask運行示意圖:

    如上圖所示,其中map階段,當map task開始運算,并產(chǎn)生中間數(shù)據(jù)后并非直接而簡單的寫入磁盤,它首先利用內(nèi)存buffer來對已經(jīng)產(chǎn)生的buffer進行緩存,并在內(nèi)存buffer中進行一些預(yù)排序來優(yōu)化整個map的性能。而上圖右邊的reduce階段則經(jīng)歷了三個階段,分別Copy->Sort->reduce。我們能明顯的看出,其中的Sort是采用的歸并排序,即merge sort。

    問題實例

  • The canonical example application of MapReduce is a process to count the appearances of each different word in a set of documents:
  • 海量數(shù)據(jù)分布在100臺電腦中,想個辦法高效統(tǒng)計出這批數(shù)據(jù)的TOP10。
  • 一共有N個機器,每個機器上有N個數(shù)。每個機器最多存O(N)個數(shù)并對它們操作。如何找到N^2個數(shù)的中數(shù)(median)?

  • 6.6 多層劃分

    方法介紹

    多層劃分法,本質(zhì)上還是分而治之的思想,因為元素范圍很大,不能利用直接尋址表,所以通過多次劃分,逐步確定范圍,然后最后在一個可以接受的范圍內(nèi)進行。

    問題實例

    1、2.5億個整數(shù)中找出不重復(fù)的整數(shù)的個數(shù),內(nèi)存空間不足以容納這2.5億個整數(shù)

    分析:有點像鴿巢原理,整數(shù)個數(shù)為2^32,也就是,我們可以將這2^32個數(shù),劃分為2^8個區(qū)域(比如用單個文件代表一個區(qū)域),然后將數(shù)據(jù)分離到不同的區(qū)域,然后不同的區(qū)域在利用bitmap就可以直接解決了。也就是說只要有足夠的磁盤空間,就可以很方便的解決。

    2、5億個int找它們的中位數(shù)

    分析:首先我們將int劃分為2^16個區(qū)域,然后讀取數(shù)據(jù)統(tǒng)計落到各個區(qū)域里的數(shù)的個數(shù),之后我們根據(jù)統(tǒng)計結(jié)果就可以判斷中位數(shù)落到那個區(qū)域,同時知道這個區(qū)域中的第幾大數(shù)剛好是中位數(shù)。然后第二次掃描我們只統(tǒng)計落在這個區(qū)域中的那些數(shù)就可以了。

    實際上,如果不是int是int64,我們可以經(jīng)過3次這樣的劃分即可降低到可以接受的程度。即可以先將int64分成2^24個區(qū)域,然后確定區(qū)域的第幾大數(shù),在將該區(qū)域分成2^20個子區(qū)域,然后確定是子區(qū)域的第幾大數(shù),然后子區(qū)域里的數(shù)的個數(shù)只有2^20,就可以直接利用direct addr table進行統(tǒng)計了。


    方法介紹

    什么是Bit-map

    所謂的Bit-map就是用一個bit位來標記某個元素對應(yīng)的Value, 而Key即是該元素。由于采用了Bit為單位來存儲數(shù)據(jù),因此在存儲空間方面,可以大大節(jié)省。

    來看一個具體的例子,假設(shè)我們要對0-7內(nèi)的5個元素(4,7,2,5,3)排序(這里假設(shè)這些元素沒有重復(fù))。那么我們就可以采用Bit-map的方法來達到排序的目的。要表示8個數(shù),我們就只需要8個Bit(1Bytes),首先我們開辟1Byte的空間,將這些空間的所有Bit位都置為0(如下圖:)

    然后遍歷這5個元素,首先第一個元素是4,那么就把4對應(yīng)的位置為1(可以這樣操作 p+(i/8)|(0×01

    ?


    ?

    ?

    6.8 Bloom filter

    方法介紹

    一、什么是Bloom Filter

    Bloom Filter,被譯作稱布隆過濾器,是一種空間效率很高的隨機數(shù)據(jù)結(jié)構(gòu),Bloom filter可以看做是對bit-map的擴展,它的原理是:

    • 當一個元素被加入集合時,通過K個Hash函數(shù)將這個元素映射成一個位陣列(Bit array)中的K個點,把它們置為1**。檢索時,我們只要看看這些點是不是都是1就(大約)知道集合中有沒有它了:
      • 如果這些點有任何一個0,則被檢索元素一定不在;
      • 如果都是1,則被檢索元素很可能在。

    其可以用來實現(xiàn)數(shù)據(jù)字典,進行數(shù)據(jù)的判重,或者集合求交集。

    但Bloom Filter的這種高效是有一定代價的:在判斷一個元素是否屬于某個集合時,有可能會把不屬于這個集合的元素誤認為屬于這個集合(false positive)。因此,Bloom Filter不適合那些“零錯誤”的應(yīng)用場合。而在能容忍低錯誤率的應(yīng)用場合下,Bloom Filter通過極少的錯誤換取了存儲空間的極大節(jié)省。

    1.1、集合表示和元素查詢

    下面我們具體來看Bloom Filter是如何用位數(shù)組表示集合的。初始狀態(tài)時,Bloom Filter是一個包含m位的位數(shù)組,每一位都置為0。

    為了表達S={x1, x2,…,xn}這樣一個n個元素的集合,Bloom Filter使用k個相互獨立的哈希函數(shù)(Hash Function),它們分別將集合中的每個元素映射到{1,…,m}的范圍中。對任意一個元素x,第i個哈希函數(shù)映射的位置hi(x)就會被置為1(1≤i≤k)。注意,如果一個位置多次被置為1,那么只有第一次會起作用,后面幾次將沒有任何效果。在下圖中,k=3,且有兩個哈希函數(shù)選中同一個位置(從左邊數(shù)第五位,即第二個“1“處)。

    在判斷y是否屬于這個集合時,我們對y應(yīng)用k次哈希函數(shù),如果所有hi(y)的位置都是1(1≤i≤k),那么我們就認為y是集合中的元素,否則就認為y不是集合中的元素。下圖中y1就不是集合中的元素(因為y1有一處指向了“0”位)。y2或者屬于這個集合,或者剛好是一個false positive。

    1.2、錯誤率估計

    前面我們已經(jīng)提到了,Bloom Filter在判斷一個元素是否屬于它表示的集合時會有一定的錯誤率(false positive rate),下面我們就來估計錯誤率的大小。在估計之前為了簡化模型,我們假設(shè)kn1, x2,…,xn}的所有元素都被k個哈希函數(shù)映射到m位的位數(shù)組中時,這個位數(shù)組中某一位還是0的概率是:

    其中1/m表示任意一個哈希函數(shù)選中這一位的概率(前提是哈希函數(shù)是完全隨機的),(1-1/m)表示哈希一次沒有選中這一位的概率。要把S完全映射到位數(shù)組中,需要做kn次哈希。某一位還是0意味著kn次哈希都沒有選中它,因此這個概率就是(1-1/m)的kn次方。令p = e-kn/m是為了簡化運算,這里用到了計算e時常用的近似:

    令ρ為位數(shù)組中0的比例,則ρ的數(shù)學期望E(ρ)= p’。在ρ已知的情況下,要求的錯誤率(false positive rate)為:

    (1-ρ)為位數(shù)組中1的比例,(1-ρ)k就表示k次哈希都剛好選中1的區(qū)域,即false positive rate。上式中第二步近似在前面已經(jīng)提到了,現(xiàn)在來看第一步近似。p’只是ρ的數(shù)學期望,在實際中ρ的值有可能偏離它的數(shù)學期望值。M. Mitzenmacher已經(jīng)證明[2]?,位數(shù)組中0的比例非常集中地分布在它的數(shù)學期望值的附近。因此,第一步的近似得以成立。分別將p和p’代入上式中,得:

    相比p’和f’,使用p和f通常在分析中更為方便。

    1.3、最優(yōu)的哈希函數(shù)個數(shù)

    既然Bloom Filter要靠多個哈希函數(shù)將集合映射到位數(shù)組中,那么應(yīng)該選擇幾個哈希函數(shù)才能使元素查詢時的錯誤率降到最低呢?這里有兩個互斥的理由:如果哈希函數(shù)的個數(shù)多,那么在對一個不屬于集合的元素進行查詢時得到0的概率就大;但另一方面,如果哈希函數(shù)的個數(shù)少,那么位數(shù)組中的0就多。為了得到最優(yōu)的哈希函數(shù)個數(shù),我們需要根據(jù)上一小節(jié)中的錯誤率公式進行計算。

    先用p和f進行計算。注意到f = exp(k ln(1 ? e?kn/m)),我們令g = k ln(1 ? e?kn/m),只要讓g取到最小,f自然也取到最小。由于p = e-kn/m,我們可以將g寫成

    根據(jù)對稱性法則可以很容易看出當p = 1/2,也就是k = ln2· (m/n)時,g取得最小值。在這種情況下,最小錯誤率f等于(1/2)k≈ (0.6185)m/n。另外,注意到p是位數(shù)組中某一位仍是0的概率,所以p = 1/2對應(yīng)著位數(shù)組中0和1各一半。換句話說,要想保持錯誤率低,最好讓位數(shù)組有一半還空著。

    需要強調(diào)的一點是,p = 1/2時錯誤率最小這個結(jié)果并不依賴于近似值p和f。同樣對于f’ = exp(k ln(1 ? (1 ? 1/m)kn)),g’ = k ln(1 ? (1 ? 1/m)kn),p’ = (1 ? 1/m)kn,我們可以將g’寫成

    同樣根據(jù)對稱性法則可以得到當p’ = 1/2時,g’取得最小值。

    1.4、位數(shù)組的大小

    下面我們來看看,在不超過一定錯誤率的情況下,Bloom Filter至少需要多少位才能表示全集中任意n個元素的集合。假設(shè)全集中共有u個元素,允許的最大錯誤率為?,下面我們來求位數(shù)組的位數(shù)m。

    假設(shè)X為全集中任取n個元素的集合,F(X)是表示X的位數(shù)組。那么對于集合X中任意一個元素x,在s = F(X)中查詢x都能得到肯定的結(jié)果,即s能夠接受x。顯然,由于Bloom Filter引入了錯誤,s能夠接受的不僅僅是X中的元素,它還能夠? (u - n)個false positive。因此,對于一個確定的位數(shù)組來說,它能夠接受總共n + ? (u - n)個元素。在n + ? (u - n)個元素中,s真正表示的只有其中n個,所以一個確定的位數(shù)組可以表示

    個集合。m位的位數(shù)組共有2m個不同的組合,進而可以推出,m位的位數(shù)組可以表示

    個集合。全集中n個元素的集合總共有

    個,因此要讓m位的位數(shù)組能夠表示所有n個元素的集合,必須有

    即:

    上式中的近似前提是n和?u相比很小,這也是實際情況中常常發(fā)生的。根據(jù)上式,我們得出結(jié)論:在錯誤率不大于?的情況下,m至少要等于n log2(1/?)才能表示任意n個元素的集合。

    上一小節(jié)中我們曾算出當k = ln2· (m/n)時錯誤率f最小,這時f = (1/2)k= (1/2)mln2 / n。現(xiàn)在令f≤?,可以推出

    這個結(jié)果比前面我們算得的下界n log2(1/?)大了log2e≈ 1.44倍。這說明在哈希函數(shù)的個數(shù)取到最優(yōu)時,要讓錯誤率不超過?,m至少需要取到最小值的1.44倍。

    問題實例

    1、給你A,B兩個文件,各存放50億條URL,每條URL占用64字節(jié),內(nèi)存限制是4G,讓你找出A,B文件共同的URL。如果是三個乃至n個文件呢?

    分析:如果允許有一定的錯誤率,可以使用Bloom filter,4G內(nèi)存大概可以表示340億bit。將其中一個文件中的url使用Bloom filter映射為這340億bit,然后挨個讀取另外一個文件的url,檢查是否與Bloom filter,如果是,那么該url應(yīng)該是共同的url(注意會有一定的錯誤率)。”


    6.9 Trie樹

    方法介紹

    1.1、什么是Trie樹

    Trie樹,即字典樹,又稱單詞查找樹或鍵樹,是一種樹形結(jié)構(gòu)。典型應(yīng)用是用于統(tǒng)計和排序大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計。它的優(yōu)點是最大限度地減少無謂的字符串比較,查詢效率比較高。

    Trie的核心思想是空間換時間,利用字符串的公共前綴來降低查詢時間的開銷以達到提高效率的目的。

    它有3個基本性質(zhì):

  • 根節(jié)點不包含字符,除根節(jié)點外每一個節(jié)點都只包含一個字符。
  • 從根節(jié)點到某一節(jié)點,路徑上經(jīng)過的字符連接起來,為該節(jié)點對應(yīng)的字符串。
  • 每個節(jié)點的所有子節(jié)點包含的字符都不相同。
  • 1.2、樹的構(gòu)建

    咱們先來看一個問題:假如現(xiàn)在給你10萬個長度不超過10的單詞,對于每一個單詞,我們要判斷它出沒出現(xiàn)過,如果出現(xiàn)了,求第一次出現(xiàn)在第幾個位置。對于這個問題,我們該怎么解決呢?

    如果我們用最傻的方法,對于每一個單詞,我們都要去查找它前面的單詞中是否有它。那么這個算法的復(fù)雜度就是O(n^2)。顯然對于10萬的范圍難以接受。

    換個思路想:

    • 假設(shè)我要查詢的單詞是abcd,那么在它前面的單詞中,以b,c,d,f之類開頭的顯然不必考慮,而只要找以a開頭的中是否存在abcd就可以了。
      • 同樣的,在以a開頭中的單詞中,我們只要考慮以b作為第二個字母的,一次次縮小范圍和提高針對性,這樣一個樹的模型就漸漸清晰了。

    即如果現(xiàn)在有b,abc,abd,bcd,abcd,efg,hii 這6個單詞,我們可以構(gòu)建一棵如下圖所示的樹:

    如上圖所示,對于每一個節(jié)點,從根遍歷到他的過程就是一個單詞,如果這個節(jié)點被標記為紅色,就表示這個單詞存在,否則不存在。

    那么,對于一個單詞,只要順著他從根走到對應(yīng)的節(jié)點,再看這個節(jié)點是否被標記為紅色就可以知道它是否出現(xiàn)過了。把這個節(jié)點標記為紅色,就相當于插入了這個單詞。

    這樣一來我們查詢和插入可以一起完成,所用時間僅僅為單詞長度(在這個例子中,便是10)。這就是一棵trie樹。

    我們可以看到,trie樹每一層的節(jié)點數(shù)是26^i級別的。所以為了節(jié)省空間,我們還可以用動態(tài)鏈表,或者用數(shù)組來模擬動態(tài)。而空間的花費,不會超過單詞數(shù)×單詞長度。

    1.3、查詢

    Trie樹是簡單但實用的數(shù)據(jù)結(jié)構(gòu),通常用于實現(xiàn)字典查詢。我們做即時響應(yīng)用戶輸入的AJAX搜索框時,就是Trie開始。本質(zhì)上,Trie是一顆存儲多個字符串的樹。相鄰節(jié)點間的邊代表一個字符,這樣樹的每條分支代表一則子串,而樹的葉節(jié)點則代表完整的字符串。和普通樹不同的地方是,相同的字符串前綴共享同一條分支。

    下面,再舉一個例子。給出一組單詞,inn, int, at, age, adv, ant, 我們可以得到下面的Trie:

    可以看出:

    • 每條邊對應(yīng)一個字母。
    • 每個節(jié)點對應(yīng)一項前綴。葉節(jié)點對應(yīng)最長前綴,即單詞本身。
    • 單詞inn與單詞int有共同的前綴“in”, 因此他們共享左邊的一條分支,root->i->in。同理,ate, age, adv, 和ant共享前綴"a",所以他們共享從根節(jié)點到節(jié)點"a"的邊。

    查詢操縱非常簡單。比如要查找int,順著路徑i -> in -> int就找到了。

    搭建Trie的基本算法也很簡單,無非是逐一把每則單詞的每個字母插入Trie。插入前先看前綴是否存在。如果存在,就共享,否則創(chuàng)建對應(yīng)的節(jié)點和邊。比如要插入單詞add,就有下面幾步:

  • 考察前綴"a",發(fā)現(xiàn)邊a已經(jīng)存在。于是順著邊a走到節(jié)點a。
  • 考察剩下的字符串"dd"的前綴"d",發(fā)現(xiàn)從節(jié)點a出發(fā),已經(jīng)有邊d存在。于是順著邊d走到節(jié)點ad
  • 考察最后一個字符"d",這下從節(jié)點ad出發(fā)沒有邊d了,于是創(chuàng)建節(jié)點ad的子節(jié)點add,并把邊ad->add標記為d。
  • 問題實例

    1、一個文本文件,大約有一萬行,每行一個詞,要求統(tǒng)計出其中最頻繁出現(xiàn)的前10個詞,請給出思想,給出時間復(fù)雜度分析

    提示:用trie樹統(tǒng)計每個詞出現(xiàn)的次數(shù),時間復(fù)雜度是O(nle)(le表示單詞的平均長度),然后是找出出現(xiàn)最頻繁的前10個詞。當然,也可以用堆來實現(xiàn),時間復(fù)雜度是O(nlg10)。所以總的時間復(fù)雜度,是O(nle)與O(nlg10)中較大的哪一個。

    2、尋找熱門查詢

    原題:搜索引擎會通過日志文件把用戶每次檢索使用的所有檢索串都記錄下來,每個查詢串的長度為1-255字節(jié)。假設(shè)目前有一千萬個記錄,這些查詢串的重復(fù)讀比較高,雖然總數(shù)是1千萬,但是如果去除重復(fù)和,不超過3百萬個。一個查詢串的重復(fù)度越高,說明查詢它的用戶越多,也就越熱門。請你統(tǒng)計最熱門的10個查詢串,要求使用的內(nèi)存不能超過1G。

    提示:利用trie樹,關(guān)鍵字域存該查詢串出現(xiàn)的次數(shù),沒有出現(xiàn)為0。最后用10個元素的最小推來對出現(xiàn)頻率進行排序。


    6.10 數(shù)據(jù)庫

    方法介紹

    當遇到大數(shù)據(jù)量的增刪改查時,一般把數(shù)據(jù)裝進數(shù)據(jù)庫中,從而利用數(shù)據(jù)的設(shè)計實現(xiàn)方法,對海量數(shù)據(jù)的增刪改查進行處理。


    ?

    6.11 倒排索引

    方法介紹

    倒排索引是一種索引方法,被用來存儲在全文搜索下某個單詞在一個文檔或者一組文檔中的存儲位置的映射,常被應(yīng)用于搜索引擎和關(guān)鍵字查詢的問題中。

    以英文為例,下面是要被索引的文本:

    T0 = "it is what it is" T1 = "what is it" T2 = "it is a banana"

    我們就能得到下面的反向文件索引:

    "a": {2} "banana": {2} "is": {0, 1, 2} "it": {0, 1, 2} "what": {0, 1}

    檢索的條件"what","is"和"it"將對應(yīng)集合的交集。

    正向索引開發(fā)出來用來存儲每個文檔的單詞的列表。正向索引的查詢往往滿足每個文檔有序頻繁的全文查詢和每個單詞在校驗文檔中的驗證這樣的查詢。在正向索引中,文檔占據(jù)了中心的位置,每個文檔指向了一個它所包含的索引項的序列。也就是說文檔指向了它包含的那些單詞,而反向索引則是單詞指向了包含它的文檔,很容易看到這個反向的關(guān)系。

    問題實例

    1、文檔檢索系統(tǒng),查詢那些文件包含了某單詞,比如常見的學術(shù)論文的關(guān)鍵字搜索

    提示:建倒排索引。


    6.15 本章習題

    本章海量數(shù)據(jù)的習題

    1?有100W個關(guān)鍵字,長度小于等于50字節(jié)。用高效的算法找出top10的熱詞,并對內(nèi)存的占用不超過1MB。

    提示:老題,與caopengcs討論后,得出具體思路為:

    • 先把100W個關(guān)鍵字hash映射到小文件,根據(jù)題意,100W_50B = 50_10^6B = 50M,而內(nèi)存只有1M,故干脆搞一個hash函數(shù) % 50,分解成50個小文件;
    • 針對對每個小文件依次運用hashmap(key,value)完成每個key的value次數(shù)統(tǒng)計,后用堆找出每個小文件中value次數(shù)最大的top 10; -最后依次對每兩小文件的top 10歸并,得到最終的top 10。

    此外,很多細節(jié)需要注意下,舉個例子,如若hash映射后導致分布不均的話,有的小文件可能會超過1M,故為保險起見,你可能會說根據(jù)數(shù)據(jù)范圍分解成50~500或更多的小文件,但到底是多少呢?我覺得這不重要,勿糾結(jié)答案,雖準備在平時,但關(guān)鍵還是看臨場發(fā)揮,保持思路清晰關(guān)注細節(jié)即可。

    2

    單機5G內(nèi)存,磁盤200T的數(shù)據(jù),分別為字符串,然后給定一個字符串,判斷這200T數(shù)據(jù)里面有沒有這個字符串,怎么做? 如果查詢次數(shù)會非常的多, 怎么預(yù)處理?

    提示:如果數(shù)據(jù)是200g且允許少許誤差的話,可以考慮用布隆過濾器Bloom Filter。但本題是200T,得另尋良策,具體解法請讀者繼續(xù)思考。

    3

    現(xiàn)在有一個大文件,文件里面的每一行都有一個group標識(group很多,但是每個group的數(shù)據(jù)量很小),現(xiàn)在要求把這個大文件分成十個小文件,要求:

    • 1、同一個group的必須在一個文件里面;
    • 2、切分之后,要求十個小文件的數(shù)據(jù)量盡可能均衡。

    7

    服務(wù)器內(nèi)存1G,有一個2G的文件,里面每行存著一個QQ號(5-10位數(shù)),怎么最快找出出現(xiàn)過最多次的QQ號。

    8

    盡量高效的統(tǒng)計一片英文文章(總單詞數(shù)目)里出現(xiàn)的所有英文單詞,按照在文章中首次出現(xiàn)的順序打印輸出該單詞和它的出現(xiàn)次數(shù)。

    9

    在人人好友里,A和B是好友,B和C是好友,如果A 和C不是好友,那么C是A的二度好友,在一個有10萬人的數(shù)據(jù)庫里,如何在時間0(n)里,找到某個人的十度好友。

    12

    海量記錄,記錄形式如下: TERMID URLNOCOUNT urlno1 urlno2 ..., urlnon,請問怎么考慮資源和時間這兩個因素,實現(xiàn)快速查詢?nèi)我鈨蓚€記錄的交集,并集等,設(shè)計相關(guān)的數(shù)據(jù)結(jié)構(gòu)和算法。

    14

    有一億個整數(shù),請找出最大的1000個,要求時間越短越好,空間占用越少越好。

    18

    10億個int型整數(shù),如何找出重復(fù)出現(xiàn)的數(shù)字。

    19

    有2G的一個文本文檔,文件每行存儲的是一個句子,每個單詞是用空格隔開的。問:輸入一個句子,如何找到和它最相似的前10個句子。

    提示:可用倒排文檔。

    20

    某家視頻網(wǎng)站,每天有上億的視頻被觀看,現(xiàn)在公司要請研發(fā)人員找出最熱門的視頻。 該問題的輸入可以簡化為一個字符串文件,每一行都表示一個視頻id,然后要找出出現(xiàn)次數(shù)最多的前100個視頻id,將其輸出,同時輸出該視頻的出現(xiàn)次數(shù)。

    • 1.假設(shè)每天的視頻播放次數(shù)為3億次,被觀看的視頻數(shù)量為一百萬個,每個視頻ID的長度為20字節(jié),限定使用的內(nèi)存為1G。請簡述做法,再寫代碼。
    • 2.假設(shè)每個月的視頻播放次數(shù)為100億次,被觀看的視頻數(shù)量為1億,每個視頻ID的長度為20字節(jié),一臺機器被限定使用的內(nèi)存為1G。

    提示:萬變不離其宗,分而治之/Hash映射 + Hash統(tǒng)計 + 堆/快速/歸并排序。

    21

    有一個log文件,里面記錄的格式為:

    QQ號 時間 flag123456 14:00:00 0 123457 14:00:01 1

    其中flag=0表示登錄 flag=1表示退出

    問:統(tǒng)計一天平均在線的QQ數(shù)。

    22

    一個文本,一萬行,每行一個詞,統(tǒng)計出現(xiàn)頻率最高的前10個詞(詞的平均長度為Len)。并分析時間復(fù)雜度。

    23

    在一個文件中有 10G 個整數(shù),亂序排列,要求找出中位數(shù)。內(nèi)存限制為 2G。只寫出思路即可。

    24

    一個url指向的頁面里面有另一個url,最終有一個url指向之前出現(xiàn)過的url或空,這兩種情形都定義為null。這樣構(gòu)成一個單鏈表。給兩條這樣單鏈表,判斷里面是否存在同樣的url。url以億級計,資源不足以hash。

    25

    一個1G大小的一個文件,里面每一行是一個詞,詞的大小不超過16字節(jié),內(nèi)存限制大小是1M。返回頻數(shù)最高的100個詞。

    26

    1000萬字符串,其中有些是重復(fù)的,需要把重復(fù)的全部去掉,保留沒有重復(fù)的字符串。請怎么設(shè)計和實現(xiàn)?

    27?有10個文件,每個文件1G,每個文件的每一行都存放的是用戶的query,每個文件的query都可能重復(fù)。要你按照query的頻度排序。

    28

    現(xiàn)有一200M的文本文件,里面記錄著IP地址和對應(yīng)地域信息,如

    202.100.83.56 北京 北京大學202.100.83.120 北京 人民大學 202.100.83.134 北京 中國青年政治學院 211.93.120.45 長春市 長春大學 211.93.120.129 吉林市 吉林大學 211.93.120.200 長春 長春KTV

    現(xiàn)有6億個IP地址,請編寫程序,讀取IP地址便轉(zhuǎn)換成IP地址相對應(yīng)的城市,要求有較好的時間復(fù)雜度和空間復(fù)雜度。

    (本篇完~)

    ?

    總結(jié)

    以上是生活随笔為你收集整理的转:6.1海量数据处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    亚洲成年人在线播放 | 激情综合五月天 | 777视频在线观看 | 美女精品在线观看 | 美女黄网站视频免费 | 狠狠操精品 | 国产亚洲欧洲 | 国产你懂的在线 | 国产美女免费视频 | 亚洲三级黄色 | 毛片在线网 | 国产一区电影在线观看 | 亚洲精品五月 | av丁香 | 亚洲精品一区二区三区在线观看 | 极品国产91在线网站 | 欧美性一级观看 | 少妇bbb | 国产成人精品999 | www.99在线观看 | 亚洲第一av在线 | 毛片激情永久免费 | 五月婷婷综合久久 | 最新中文字幕在线资源 | 久久不卡免费视频 | 久久久久久久久久久久国产精品 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 狠狠亚洲 | 中国成人一区 | 日韩av片无码一区二区不卡电影 | 国产精品久久久久久久久久久久午夜 | 亚洲国产精品一区二区久久,亚洲午夜 | 手机在线观看国产精品 | 久久69精品久久久久久久电影好 | 久久成人一区 | 免费视频二区 | 91久久精品一区二区三区 | 蜜桃av观看| 亚洲a色| 成人av网站在线播放 | 欧美成人性网 | 色吧久久 | 色在线网站 | 98涩涩国产露脸精品国产网 | 波多野结衣日韩 | 九色91在线 | 久草爱视频 | 国产精品美女毛片真酒店 | 亚州欧美视频 | 91网在线看 | 五月综合网 | 久久精品网站视频 | 欧美日韩综合在线 | 人人爱人人舔 | 午夜久久久精品 | 国产精品一区二区三区免费视频 | 在线视频观看成人 | 亚洲精品国产精品久久99热 | 亚洲欧美偷拍另类 | 日韩欧美aaa | 一区二区视频在线免费观看 | 日韩在线视频一区 | av一级在线 | 人人插人人插 | 国产精品美女久久久网av | 成人国产精品av | 亚洲干| 国产精品久久久久久久婷婷 | 国产高清 不卡 | 久久一区二区三区超碰国产精品 | 色婷婷电影 | 日韩大片在线免费观看 | 日韩中文三级 | 狠狠色丁香婷综合久久 | 99热最新精品 | 精品国产乱码久久久久 | 国产黄a三级三级三级三级三级 | 婷婷深爱激情 | 国内少妇自拍视频一区 | 欧美二区在线播放 | 国产一级性生活 | 中文字幕在线字幕中文 | 亚洲精品国产片 | 久久久久久高潮国产精品视 | 粉嫩av一区二区三区四区 | 人人草在线视频 | 六月丁香激情综合 | 最近免费观看的电影完整版 | 超级碰碰碰免费视频 | 丁香婷婷在线 | 91av官网 | 69av视频在线观看 | 国产精品一区二区免费视频 | 狠狠色噜噜狠狠 | 狠狠色噜噜狠狠狠狠2021天天 | 蜜臀91丨九色丨蝌蚪老版 | 久久激情五月丁香伊人 | 国产精品正在播放 | 日日夜夜天天综合 | 五月婷婷丁香 | 国产欧美最新羞羞视频在线观看 | 国产精品美女久久 | 黄色大片免费播放 | 日本在线视频一区二区三区 | 色www永久免费 | 99久久国产免费,99久久国产免费大片 | 人人舔人人干 | 一级黄色片在线免费看 | 久久精品视频在线免费观看 | 亚洲va欧美va人人爽 | 国产在线a免费观看 | 伊人色综合久久天天网 | 成人在线播放av | 国产中文 | 国产午夜精品久久 | 国产电影黄色av | 一个色综合网站 | 久久国产精品99精国产 | 国产一卡二卡在线 | 人人射人人爽 | 日韩精品免费专区 | 国产丝袜制服在线 | 午夜在线免费视频 | www日韩| 精品久久久久久综合日本 | 日韩免费在线观看网站 | 欧美激情视频免费看 | 99福利片 | 国产精品videossex国产高清 | 精品专区一区二区 | 国产999视频 | 精品亚洲免费视频 | 色狠狠婷婷| av资源免费在线观看 | 久久亚洲私人国产精品va | 中文字幕在线国产精品 | 亚洲成年片 | 久久成人在线 | 中文字幕在线观看的网站 | 欧美色图88 | 草久在线视频 | 少妇做爰k8经典 | 在线精品观看国产 | x99av成人免费| 亚洲国产中文字幕在线观看 | 激情五月网站 | 天天干天天弄 | 最新国产视频 | 黄色三级av| 成人在线小视频 | 国产色a在线观看 | 黄色一级大片在线免费看产 | 欧美国产日韩中文 | 精品在线一区二区 | 天天做综合网 | 亚洲成人网在线 | av资源在线看 | 国产精品中文在线 | 日本中文字幕网 | 一区二区欧美日韩 | 国产在线a免费观看 | 国产99区 | 国产一区二区在线播放视频 | 最近最新mv字幕免费观看 | 天天插天天操天天干 | 国产一区二区高清视频 | 久久美女免费视频 | 福利视频一区二区 | 成人h动漫精品一区二 | 99re在线视频观看 | 四虎免费av | 91av大全 | 99久久久久久久 | 欧美福利视频一区 | 国内小视频 | 92国产精品久久久久首页 | 精品久久久久久久久中文字幕 | 亚洲精品国偷拍自产在线观看 | 国产成人高清在线 | 激情网婷婷| 亚洲日本黄色 | 中文字幕在线播放一区二区 | 九九有精品 | 久久首页 | 成人在线观看网址 | 亚洲成人精品在线观看 | 久久久国产一区 | 97超碰在线播放 | 超碰免费在线公开 | 91视频 - 88av | 中文久久精品 | 午夜久久福利 | 国产一级视频 | 黄色av三级在线 | 99久久er热在这里只有精品15 | 亚洲一区美女视频在线观看免费 | av在线播放快速免费阴 | h视频在线看 | 国产精品一区在线 | 国产精品乱码久久久 | 国产中文欧美日韩在线 | 久久99国产精品免费 | 久久精品视频在线观看 | 久久久久久国产精品久久 | 国产精品毛片久久久久久久 | 久久 国产一区 | 欧美日韩在线视频一区 | 日日夜夜天天干 | 国产精品网红直播 | 日韩免费在线观看网站 | 久久免费视频5 | av片子在线观看 | 18国产精品白浆在线观看免费 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | 久久99精品国产 | 91激情视频在线观看 | 五月婷综合网 | 久久av免费观看 | 欧美日韩精品影院 | 中文字幕91在线 | 久久免费av | 国产色拍拍拍拍在线精品 | 中文字幕2021 | 91精品国产乱码 | 免费av一级电影 | 九七视频在线观看 | 久久久久久久久久久免费视频 | 国产中文字幕视频在线观看 | 国产一级片一区二区三区 | 日韩在线观看电影 | 免费看av片网站 | 日日夜夜中文字幕 | 久久在线精品视频 | 91在线产啪 | 日韩亚洲国产中文字幕 | 免费观看一级一片 | 国产一二区免费视频 | 91精品国自产在线 | 国产精品18久久久久久不卡孕妇 | 欧美天天干| 久久久免费电影 | 国产成人一区二区三区影院在线 | 五月激情姐姐 | 欧美在线不卡一区 | se婷婷 | 国产精品久久久久久影院 | 懂色av懂色av粉嫩av分享吧 | 黄色三级免费网址 | 97精品国产91久久久久久 | 日韩av片无码一区二区不卡电影 | 婷婷在线精品视频 | 久久久久久国产精品 | 福利视频精品 | 在线观看理论 | 伊人天堂av | 99精品免费久久久久久日本 | 久久久免费网站 | 五月天色中色 | 中文字幕丝袜一区二区 | 国产在线视频一区二区三区 | 五月婷婷在线播放 | 精品国偷自产在线 | 成人久久久久久久久 | 久久99深爱久久99精品 | 国产精品乱码一区二三区 | 一本之道乱码区 | 国产流白浆高潮在线观看 | 日日夜精品 | 美女网站久久 | 国产成人精品电影久久久 | 国产福利91精品一区 | 日韩免费看的电影 | 99精品欧美一区二区三区黑人哦 | 欧美亚洲国产一卡 | www.一区二区三区 | 国产破处在线视频 | 国产亚洲观看 | 亚洲激情免费 | 三级黄色理论片 | 亚洲第一区精品 | 久久久麻豆精品一区二区 | 激情婷婷 | 国产在线视频不卡 | 精品视频中文字幕 | 成年人精品 | 久久精品香蕉视频 | 国产精品一区二区久久 | 日韩高清网站 | 又黄又刺激又爽的视频 | 香蕉久久久久久久 | 九九色综合| 日韩在线在线 | 狠狠色伊人亚洲综合网站野外 | 亚洲人视频在线 | 91原创在线观看 | 天堂在线免费视频 | 91视视频在线直接观看在线看网页在线看 | 日韩精品2区 | 日韩网页| 91成人精品一区在线播放69 | 国产三级av在线 | 亚洲精品免费观看 | 日韩精品视 | 国产精品手机在线 | 欧美国产视频在线 | 97精品久久 | 日韩高清av | 在线视频中文字幕一区 | 91精品国产综合久久久久久久 | 久久爱资源网 | 色网站在线 | 香蕉视频久久 | 久久精品99国产精品亚洲最刺激 | av在线电影免费观看 | 久久久久这里只有精品 | 亚洲国产精品成人av | 91精品老司机久久一区啪 | 99在线观看免费视频精品观看 | 久久精品国产免费观看 | 欧美性爽爽 | 欧美精品网站 | 777奇米四色| 在线午夜电影神马影院 | av免费网| 免费观看国产成人 | 特黄免费av | 国产成人一区二区在线观看 | 91精品久| 国产精品毛片一区二区三区 | 免费久久精品视频 | 日本不卡视频 | 超碰人人超| 天天干天天射天天爽 | av在线进入 | 色婷婷免费视频 | 黄色av免费看 | 美女视频黄免费 | 久久精品高清视频 | 天天草天天操 | av字幕在线 | 欧美资源| 国产黄色精品 | 国产在线永久 | 亚洲 欧洲 国产 日本 综合 | 99热网站| 国产一级视频在线免费观看 | 日韩欧美网址 | 中文字幕日韩一区二区三区不卡 | 亚洲成人精品在线观看 | 在线视频一二三 | 五月婷婷激情综合 | 久久亚洲成人网 | 国产福利一区在线观看 | 日韩av电影免费在线观看 | 国产一区在线精品 | 欧美成人a在线 | 在线观看日韩专区 | 九九免费在线视频 | 国产一级视频在线免费观看 | 国产成人一区二区三区免费看 | 国产在线视频不卡 | 日韩精品极品视频 | 国产中文 | 国产亚洲综合在线 | 一区免费在线 | 国产视频精品视频 | 九九涩涩av台湾日本热热 | 国产精品 中文在线 | 人人天天夜夜 | 日韩视频免费播放 | 91麻豆精品国产自产在线游戏 | 国产精品久久久久久吹潮天美传媒 | 区一区二区三在线观看 | 免费视频一二三区 | 娇妻呻吟一区二区三区 | 国产区免费 | 91免费在线视频 | 在线观看视频国产 | 亚洲专区一二三 | 波多野结衣亚洲一区二区 | 超碰.com| av线上免费观看 | 国产原创中文在线 | 操操操com| 成人免费在线播放视频 | 久久资源在线 | 深爱五月网| 亚洲高清国产视频 | 国产无遮挡又黄又爽在线观看 | 亚洲在线成人精品 | 天天操天天操天天爽 | 色综合亚洲精品激情狠狠 | 黄色软件网站在线观看 | 国产麻豆果冻传媒在线观看 | 国产96在线视频 | 麻花豆传媒mv在线观看网站 | 久操视频在线播放 | 一区二区国产精品 | 日韩精品观看 | 9在线观看免费高清完整版在线观看明 | 亚洲成人黄色av | 日韩乱码中文字幕 | 日本黄色免费网站 | 亚洲精品美女在线 | 国产麻豆精品久久 | 国内揄拍国内精品 | 激情婷婷在线 | 欧美精品国产综合久久 | www.国产在线观看 | 亚洲视频免费在线 | 日韩欧在线 | 国产精品久久三 | 欧美日bb| 国产黄a三级三级三级三级三级 | 国产爽视频 | 欧美日韩不卡一区 | 久久精品日产第一区二区三区乱码 | 久热色超碰| 人人澡人 | 亚洲禁18久人片 | 韩国精品福利一区二区三区 | 丁香电影小说免费视频观看 | 久久久久成人精品免费播放动漫 | 美女久久久 | 91麻豆精品 | 在线免费黄色av | 97在线观看免费视频 | 日韩av高潮 | 精品国产三级a∨在线欧美 免费一级片在线观看 | 久久不卡国产精品一区二区 | 免费看久久久 | 亚洲亚洲精品在线观看 | 日日夜夜网| 成人免费在线播放 | 日韩免费福利 | 伊人五月天.com | 免费裸体视频网 | 97超碰资源站 | 五月婷婷在线视频观看 | 久久99国产精品自在自在app | 久久人人插 | 免费视频一二三区 | www免费看片com | www久| 国产成人一区二区三区久久精品 | 国产午夜精品一区二区三区欧美 | 国产精品18久久久久白浆 | 亚洲免费在线观看视频 | 91麻豆精品国产91久久久更新时间 | 中文字幕在线不卡国产视频 | 探花在线观看 | 色网站在线看 | 国产亚洲精品久久久久久网站 | 激情五月婷婷综合网 | 99久久综合国产精品二区 | 国产精品久久久久久999 | 久久久久久高潮国产精品视 | 日日夜夜精品网站 | 日韩系列在线 | 97在线视频免费观看 | 免费在线播放黄色 | 国产欧美精品一区二区三区四区 | 国产美女视频一区 | 亚洲国产日韩欧美 | 亚洲成人免费在线观看 | 丁香九月婷婷综合 | 国产黄色大全 | 中文字幕在线资源 | 天天射天天舔天天干 | 久久精品国产亚洲精品 | 九九国产视频 | 丁香久久婷婷 | 天天综合天天综合 | 久久免费福利视频 | 国产亚洲欧美日韩高清 | 色噜噜日韩精品欧美一区二区 | 午夜av免费观看 | 98超碰在线观看 | 日韩欧美国产精品 | 乱男乱女www7788 | 91成人免费 | 99久久婷婷国产 | 亚洲人人射| 婷婷丁香久久五月婷婷 | 亚洲精品视频在线观看网站 | 免费欧美 | 911国产在线观看 | 婷婷久久一区 | 亚洲成av人影院 | 91视频一8mav | 日韩a在线| 不卡精品| 亚洲va韩国va欧美va精四季 | 日日干天天 | 国产精品一区二区久久久久 | 国产精品无 | 激情视频免费观看 | 欧美日韩在线免费观看 | 国产无限资源在线观看 | 91成人免费电影 | 99热精品在线观看 | 日韩在线视 | 99精品影视| 免费亚洲精品 | 黄色的网站在线 | 国产精品一区免费看8c0m | 在线看毛片网站 | av黄色在线播放 | 日本中文在线 | 亚洲国产精品小视频 | 久久国产精品一区二区三区 | 丁香六月av | 久久久激情网 | 婷婷在线不卡 | 亚洲精品乱码久久久久久 | 蜜臀久久99精品久久久无需会员 | 奇米四色影狠狠爱7777 | 美女一级毛片视频 | 一级欧美一级日韩 | 久久久久久国产精品999 | 亚洲综合视频在线播放 | h视频在线看 | 精品美女在线视频 | 欧美日韩视频免费 | 天堂在线一区二区 | 福利精品在线 | 亚洲日韩欧美一区二区在线 | 国产小视频免费在线网址 | 中文字幕在线播放一区 | 97超视频免费观看 | 中文字幕黄色av | 精品人人人 | www.久久久.cum | 中文字幕在线观看2018 | 亚洲三级视频 | 久久天天躁狠狠躁亚洲综合公司 | 精品视频免费在线 | 欧美午夜性生活 | 69国产精品视频免费观看 | 成 人 免费 黄 色 视频 | 最近中文字幕国语免费高清6 | 又污又黄网站 | 97精品国产97久久久久久免费 | 国产精品国产亚洲精品看不卡 | 亚洲成人精品久久 | 国产一区二区三区网站 | sesese图片 | 在线观看深夜福利 | 久久人人爽人人爽 | 91视频免费 | 91亚洲精品在线观看 | 97av.com| 亚洲人成人在线 | 蜜臀久久99静品久久久久久 | 伊人狠狠干 | 成人黄色av免费在线观看 | 中文字幕视频观看 | 香蕉精品视频在线观看 | av资源网在线播放 | 91精品国产综合久久久久久久 | 色香蕉在线 | 欧美做受69| 久久综合色一综合色88 | 九九免费观看全部免费视频 | 精品视频国产一区 | 亚洲女同ⅹxx女同tv | 日韩在线观看视频中文字幕 | 国产一二区免费视频 | 九九热在线免费观看 | 国产美女精品视频 | 97人人网| 天天干天天操天天搞 | 91精品秘密在线观看 | 欧美色图30p | 97人人爽 | 欧美经典久久 | 在线成人一区 | 久久久国产精品视频 | 亚洲专区在线播放 | 99精品一区 | 国产在线不卡 | 国产精品资源在线观看 | 国产精品视频永久免费播放 | 国产在线观看国语版免费 | 中文字幕中文字幕在线中文字幕三区 | 日韩久久精品一区二区 | 91亚洲国产成人久久精品网站 | 色搞搞| 色婷婷综合久久久中文字幕 | 超碰在线1 | 四虎国产精品永久在线国在线 | 在线观看91网站 | 久久久久久国产一区二区三区 | 亚州精品成人 | 精品黄色在线观看 | 国产.精品.日韩.另类.中文.在线.播放 | 狠狠操影视 | 911在线| 夜夜躁日日躁 | 日韩h在线观看 | 日批视频在线观看免费 | 91免费观看国产 | 黄色1级毛片 | 国产日韩视频在线 | 久久综合天天 | 久久久国产一区二区三区 | 97人人模人人爽人人喊网 | 日韩av片无码一区二区不卡电影 | 激情深爱五月 | 婷婷色伊人 | 国产成人精品国内自产拍免费看 | 国产玖玖在线 | 国产视频精品久久 | 天天色天天干天天色 | 亚洲精品久久在线 | 视频在线一区 | 综合激情 | 欧美性护士| 91网免费看| 国产精品久久久久久久久蜜臀 | 不卡国产视频 | 日日夜夜综合网 | 国产精品一区二区三区四 | 中文字幕免费久久 | 日韩欧美aaa | 亚洲综合色站 | 日韩免费三级 | 97操操操 | 精品国产一区二区三区久久久蜜月 | 亚洲国产视频直播 | а天堂中文最新一区二区三区 | 亚洲黄色av网址 | 亚洲aⅴ在线 | 女人魂免费观看 | 中文视频在线播放 | 奇米影视四色8888 | 日韩网 | 国产 一区二区三区 在线 | 麻豆视频免费在线观看 | 成人少妇影院yyyy | 999视频网 | 九九精品在线观看 | 黄网站免费久久 | 手机看片久久 | 久久久999免费视频 日韩网站在线 | 96亚洲精品久久 | 日韩在线观看一区二区 | 日韩四虎 | 久久99热这里只有精品 | 91精品久久久久久综合乱菊 | 国产成人精品区 | 欧美三级高清 | 免费看黄在线看 | 国产一区在线不卡 | 国产97在线播放 | www欧美日韩 | 99热在线网站 | 国产免费视频一区二区裸体 | 久久久国际精品 | 久久人人看 | 在线观看的av网站 | 久久爱综合 | 亚洲黄a | 亚洲在线成人精品 | 欧美日韩啪啪 | 欧美日韩国产精品一区二区 | 99精品视频精品精品视频 | 91.精品高清在线观看 | 国产成人久久精品77777综合 | 九色91在线| 夜夜操天天 | 久久久资源网 | 一区二区三区久久精品 | 亚洲精品视频 | 黄色国产在线 | 99精品国产兔费观看久久99 | 日日夜夜精品网站 | 五月天高清欧美mv | 日韩黄色大片在线观看 | 色狠狠综合天天综合综合 | 久久国产露脸精品国产 | 在线电影a | 一区 在线观看 | 九九久久婷婷 | 五月天婷亚洲天综合网精品偷 | 69亚洲乱 | 丁香六月婷婷综合 | 欧美一区三区四区 | a爱爱视频 | 99久久99久国产黄毛片 | ww视频在线观看 | 国产人成免费视频 | 天天操夜操视频 | 久久一精品 | 国产高清日韩 | 五月婷婷,六月丁香 | 五月婷亚洲 | 九九热视频在线免费观看 | 中中文字幕av在线 | 亚洲精品456在线播放乱码 | 成人黄色在线观看视频 | 国产麻豆视频网站 | 337p日本欧洲亚洲大胆裸体艺术 | 国产精品一区二区果冻传媒 | 中文字幕免费观看全部电影 | 欧美 亚洲 另类 激情 另类 | 91麻豆精品国产91久久久更新时间 | 在线导航av| 欧美另类一二三四区 | 欧美a在线看 | 91视频最新网址 | 中文字幕一区二区在线观看 | 久草久 | 91精彩视频 | 久久综合干 | 在线看一级片 | 又黄又色又爽 | 99久国产 | 欧美日韩久久不卡 | 奇米网网址 | 欧美小视频在线观看 | 奇米影视四色8888 | 亚洲成人资源在线 | 日韩精品国产一区 | 婷婷久月 | 激情综合亚洲精品 | 91日本在线播放 | 99热精品视| 91网址在线看 | 国产精品丝袜 | 日本精品视频免费观看 | 激情综合五月天 | 日日草天天草 | 91最新国产 | www.com.日本一级 | 国产三级精品三级在线观看 | 国产不卡一二三区 | 丰满少妇在线观看网站 | 91在线永久 | 成年人免费在线观看网站 | av中文字幕在线看 | 日韩视频免费在线观看 | 日韩精选在线 | 色网站在线免费 | 国产偷v国产偷∨精品视频 在线草 | 久久免费视频网站 | 欧美做受高潮电影o | 欧美激情视频一区二区三区免费 | 91在线免费公开视频 | 午夜视频在线观看一区二区三区 | 91精品国产一区二区在线观看 | 97在线视 | 午夜精品久久久久久久久久 | 欧美性护士| 国产中文字幕一区 | 91成品视频 | 欧美精品免费一区二区 | 黄污在线观看 | 99精品国产99久久久久久97 | www.伊人网 | 97精品国产 | 日韩欧美视频 | 欧美激情操 | 7777精品伊人久久久大香线蕉 | 九草视频在线 | 国产精品在线看 | 久久一久久 | 91免费观看 | 亚洲激精日韩激精欧美精品 | 狠狠色丁婷婷日日 | 成人久久久久久久久久 | 国产va精品免费观看 | 福利一区在线 | 国产日本亚洲高清 | 99久久婷婷国产一区二区三区 | ,午夜性刺激免费看视频 | 久久这里有精品 | 色婷婷综合视频在线观看 | 国产高清亚洲 | 中文字幕日本电影 | 亚洲视频在线观看 | 日韩毛片在线一区二区毛片 | 国产亚洲精品久久久久久久久久久久 | 日本黄色免费在线 | 成人香蕉视频 | 精品在线亚洲视频 | 国产在线观看91 | 中文在线字幕免费观看 | 色噜噜日韩精品欧美一区二区 | 日韩有码网站 | 免费日韩精品 | 亚洲欧美色婷婷 | 在线韩国电影免费观影完整版 | 免费福利影院 | 日韩有色| 亚洲视频h| 日韩欧美视频免费在线观看 | 激情偷乱人伦小说视频在线观看 | 成人黄色大片在线免费观看 | 婷婷亚洲最大 | 亚洲视频观看 | 国产成人精品国内自产拍免费看 | 国产一级h | 日日麻批40分钟视频免费观看 | 波多在线视频 | 色在线亚洲 | 免费中文字幕视频 | 美女一区网站 | 国产精品久久久久久久久婷婷 | 日韩在线观看中文字幕 | 91在线播放综合 | 久久精品99精品国产香蕉 | 国产精品久久久久影院日本 | 婷婷在线免费观看 | 99久国产 | 国产在线观看 | 免费电影一区二区三区 | 国产成人专区 | 99精品国产一区二区三区不卡 | 久草视频视频在线播放 | 在线国产视频一区 | 曰韩精品| 日韩欧美视频免费看 | 在线免费观看黄色av | 久久高清精品 | 欧美亚洲精品在线观看 | 91手机电视 | 免费成人结看片 | 六月丁香在线观看 | 久久久久国产成人精品亚洲午夜 | av中文字幕在线观看网站 | 四虎国产精品免费 | 99成人在线视频 | 国产专区一 | 狠狠五月天 | 在线激情网 | 色综合天天综合 | 亚洲激情综合 | 国产专区在线看 | 久久99视频 | japanesexxxxfreehd乱熟| 91中文字幕一区 | 九九在线高清精品视频 | 中文字幕日本特黄aa毛片 | 在线视频观看你懂的 | 96精品高清视频在线观看软件特色 | 精品 激情| 五月婷婷在线视频观看 | 18岁免费看片 | 色综合亚洲精品激情狠狠 | 久久综合九色综合欧美就去吻 | 精品一二三区 | 午夜av电影院 | 久久精品xxx | 免费视频 你懂的 | 国产精品欧美一区二区 | 综合天天| 夜夜操天天操 | 欧美日韩一区二区在线观看 | 日韩电影黄色 | 最近2019好看的中文字幕免费 | 亚洲日本激情 | 国产精品99在线播放 | 日韩av电影网站在线观看 | 97在线视频免费 | 91视频免费看 | 色综合天天视频在线观看 | 在线观看国产麻豆 | 超碰在线国产 | 亚洲高清不卡av | 国产免费叼嘿网站免费 | 免费网站观看www在线观看 | 日韩高清精品免费观看 | 国产精品18久久久久久首页狼 | 久久免费a | 久久免费视频1 | 日韩精品一区二区在线 | 夜夜骑天天操 | 天天干天天干天天色 | 欧美乱淫视频 | 午夜视频免费播放 | 国产精彩在线视频 | 毛片a级片 | 在线观看免费91 | 亚洲成av人片在线观看无 | 女人18毛片a级毛片一区二区 | 国产精品av久久久久久无 | 毛片无卡免费无播放器 | 久久久久成 | 久久精品久久99精品久久 | 国产黄色片在线免费观看 | 国产剧情在线一区 | 五月天亚洲婷婷 | 99久久久国产精品 | 婷婷综合电影 | 在线观看a视频 | 久久影视中文字幕 | 国内精品久久影院 | 久久国产99| 久久久久久久久网站 | 天天插天天 | 免费观看完整版无人区 | 中文字幕 成人 | 国产短视频在线播放 | 亚洲天堂va | 久久精品99视频 | 91探花在线| 麻豆免费视频网站 | 久久激情影院 | 久草久草视频 | 天天操夜夜看 | 欧美日韩中文国产一区发布 | 91c网站色版视频 | 国产视频首页 | 亚洲视频999 | 国产精品黄色在线观看 | 青青草国产精品视频 | 九月婷婷人人澡人人添人人爽 | 亚洲精品综合一区二区 | 国产区在线视频 | 人人草人| 久久久久影视 | 看黄色.com| 欧美一区二区在线看 | 久久国产综合视频 | 亚洲视频在线看 | 亚洲精品中文字幕在线 | 日日操夜夜操狠狠操 | av性在线| 99热精品国产一区二区在线观看 | 亚洲成人影音 | 韩国在线一区二区 | 国产精品久久久久久一区二区 | 97香蕉视频 | 成年人免费在线观看网站 | 欧洲精品视频一区二区 | 婷婷色站| 亚洲国产精品推荐 | 伊人超碰在线 | 国产精品黑丝在线观看 | 国产成人99av超碰超爽 | 国产又粗又硬又爽视频 | 精品一二 | 免费97视频| 国产xxxx性hd极品 | 色婷婷丁香 | 中文av资源站 | 99久久精品免费看国产 | 久久免费国产电影 | 成人免费看片网址 | 人人澡人人爽 | 久久精品国产亚洲a | 超碰国产在线播放 | 又爽又黄又无遮挡网站动态图 | 午夜丁香视频在线观看 | 日本一区二区高清不卡 | 国产麻豆剧传媒免费观看 | 在线播放 日韩专区 | 日韩美女免费线视频 | 人人干人人艹 | 日韩区欧美久久久无人区 | 69国产成人综合久久精品欧美 | 日韩精品在线免费播放 | 久草电影在线观看 | 91激情视频在线观看 | 亚洲欧美日本一区二区三区 | 黄色的网站在线 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 808电影 | 在线影视 一区 二区 三区 | 午夜在线观看影院 | 99国内精品久久久久久久 | 91在线在线观看 | 国产成人a亚洲精品v | 精品一区二区免费视频 | 国产亚洲欧美在线视频 | 国产正在播放 | 欧美日韩国内在线 | 97视频在线观看网址 | 精品一区二区精品 | 四虎欧美 | 欧美一区二区视频97 | 久久夜色精品国产欧美乱 | 久久99这里只有精品 | 日韩精品中文字幕有码 | 久久综合九色综合97_ 久久久 | 成人在线免费视频观看 | 婷婷丁香激情网 | 天天综合网天天 | 91麻豆精品国产自产在线游戏 | 99这里只有精品99 | 日韩av黄| 日韩免费在线播放 | 在线国产高清 | 亚洲在线国产 | 综合色狠狠| 国产福利一区二区三区在线观看 | 中文字幕一区二区三区乱码不卡 |