5.海量數(shù)據(jù)處理方法
- 1)Hash
- 2)Bit-Map
- 3)Bloom Filter
- 4)堆(Heap)
- 5)雙層桶劃分
- 6)數(shù)據(jù)庫索引
- 7)倒排索引(Inverted Index)
- 8)B+樹
- 9)Trie樹
- 10)MapReduce
Hash
??把任意長度的輸入(又叫預(yù)映射,pre-image),通過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉(zhuǎn)換是一種壓縮映射。
Bit-Map
??所謂的Bit-Map就是用一個bit位來標記某個元素對應(yīng)的value,而Key即是該元素。由于采用了bit為單位來存儲數(shù)據(jù),因此在存儲空間方面,可大大節(jié)省。
Bloom Filter
??就是帶隨機概率的bitmap,可以快速的告訴你,某一個小的有序結(jié)構(gòu)里有沒有指定的那個數(shù)據(jù)的。于是我就可以不用二分查找,而只需要簡單的計算幾次就能知道數(shù)據(jù)是否在某個小集合里了。效率得到了提升,但是付出的是空間代價。
Heap
??堆是一種特殊的二叉樹,具備以下兩種性質(zhì):
- 1)每個節(jié)點的值都大于(或者小于,稱為最小堆)其子節(jié)點的值
- 2)數(shù)是完全平衡的,并且最后一層的樹葉都在最左邊
這樣就定義了一個最大堆
適用范圍 韓相數(shù)據(jù)前n大,并且n比較小,堆可以放入內(nèi)存。
雙層桶
??算法設(shè)計思想。面對一堆大量的數(shù)據(jù)我們無法處理的時候,我們可以將其分成一個個小的單元,然后根據(jù)一定的策略來處理這些小單元,從而達到目的。
例子: 第K大,中位數(shù),不重復(fù)或重復(fù)的數(shù)字
因為元素范圍很大,不能利用直接尋址表,所以通過多次劃分,逐步確定范圍,然后最后在一個可以接受的范圍內(nèi)進行。可以通過多次縮小,雙層只是一個例子,分治才是其根本(只分不治)。
數(shù)據(jù)庫索引
??數(shù)據(jù)庫索引好比是一本書前面的目錄,能加快數(shù)據(jù)庫的查詢速度。
??例如這樣一個查詢,select * from table1 where id=44;如果沒有索引,必須遍歷整個表,直到id=44這一行被找到為止;有了索引之后(必須在id這一列上建立索引),直接在索引里面找44(也就是id這一列找),就可以得知這一行的位置,也就是找到了這一行。索引是用來定位的。
- 經(jīng)常變動的表,不適合建立索引,要經(jīng)常進行動態(tài)維護
- 索引要占用空間
倒排索引
??一種索引方法,被用來存儲在全文索索下某個單次在一個文檔或者一組文檔中的存儲位置的映射。
以英文為例,下面是要被索引的文本:
- 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)集合的交集。
外排序
??外排序的歸并方法,置換選擇敗者樹,最優(yōu)歸并數(shù)
B+樹
??B+樹,因為其構(gòu)建過程中引用了有序數(shù)組,從而有效的降低了樹的高度,一次取出一個連續(xù)的數(shù)組,這個操作在磁盤上比取出與數(shù)組相同數(shù)量的離散數(shù)據(jù),成本要低很多。因此磁盤上基本都是B數(shù)結(jié)構(gòu)。
Trie Tree
??Trie樹,又稱字典樹,單詞查找樹或者前綴樹,是一種用于快速檢索的多叉樹結(jié)構(gòu),如英文字母的字典樹是一個26叉樹,數(shù)字的字典樹是一個10叉樹。
適用范圍:數(shù)據(jù)量大,重復(fù)多,但是數(shù)據(jù)種類小可以放入內(nèi)存。
分布式MapReduce
??適用范圍:數(shù)據(jù)量大,但是數(shù)據(jù)種類小可以放入內(nèi)存
6.海量數(shù)據(jù)案例
綜合案例
上千萬or億數(shù)據(jù)(有重復(fù)),統(tǒng)計其中出現(xiàn)次數(shù)最多的前N個數(shù)據(jù),分兩種情況:可一次性讀入內(nèi)存,不可一次讀入。
可用思路:trie樹+堆,數(shù)據(jù)庫索引,劃分子集分別統(tǒng)計,hash,分布式計算,近似統(tǒng)計,外排序。
Look Up Connection
設(shè)計一個社交網(wǎng)絡(luò)系統(tǒng),支持查詢用戶之間的聯(lián)系。
Request Count
給定一個可以處理請求的服務(wù)器,設(shè)計一個數(shù)據(jù)結(jié)構(gòu)可以獲取在最后一秒,一分鐘或一小時的請求數(shù)量。
電商網(wǎng)站1.0
- Taobao,Amazon
-
single machine
30.png
技術(shù)選型
- Login: Session/Cookie
- Web Server: Apache/PHP/Ngix
- MVC: Templates, Spring
- DB: MySQL
電商網(wǎng)站2.0
SOA(Service Oriented Architecture)
電商網(wǎng)站3.0
電商網(wǎng)站4.0
聊天系統(tǒng)
- Facebook Message
功能
- 朋友關(guān)系
- 發(fā)消息
- 收消息
- 查看聊天記錄
工作流
- 選擇1:A send to B directly(瀏覽器to瀏覽器,手機to手機)
- 劣勢:瀏覽器不支持P2P,沒有云端歷史記錄,沒有多個服務(wù)器
- 選擇2:A send to server,B read from server or server Send to B
Q1: How to store messages?
Database: NoSQL vs. SQL
- SQL: message
- {sender, recipient, created_at, seen_status, text} 2 queries
- NoSQL:
- key:User
- Column key:{conversation_id, created_at} conversation_id = sort([sender, recipient])
- Value:{text, seen_status} 1 fast query
Q2: Get new message
Pull vs. Push
- Pull:
- Mobile/Web: HTTP request
- Pull every 3s?
Followup Q1: Multiple Devices
- Sync Content
- last read message
Followup Q2: Online Status
- 如何存儲這個狀態(tài)(最后上線時間)
- 如何獲取這個狀態(tài)
- 心跳
- 如何排序好友列表
Followup Q3: Conversation List
- Conversation Schema
- Ordered by last activity
Followup Q4: Group Chat
- Group Message
- key: User Id
- Column Key: (conversation_id, created_at, type)
- conversation_id = uuid()
- type: text or seen status
- value {someong, text} or {someont, seen}
- Where to store recipient list?
Top K
??搜索引擎會通過日志問價你把用戶每次檢索使用的所有檢索串都記錄下來,每個查詢串的長度為1-255字節(jié)。假設(shè)目前有1000萬個記錄,這些查詢串的重復(fù)度比較高,雖然總數(shù)是1000萬,但是如果去重后,不超過300萬個。一個查詢串的重復(fù)度越高,說明查詢它的用戶越多,也就是越熱門。請你統(tǒng)計最熱門的10個查詢串,要求使用的內(nèi)存不能超過1G。
- 排序(內(nèi)存使用較高)
- 部分排序
- 堆
從10億查詢詞中找出出現(xiàn)頻率最高的10個
- 單機+單核+足夠大內(nèi)存
- 單機+多核+足夠大內(nèi)存
- 單機+單核+受限內(nèi)存
- 多機+受限內(nèi)存
MapReduce
數(shù)據(jù)抽樣
??給你一個長度為N的鏈表。N很大,但是你不知道N有多大。你的任務(wù)是從這N個元素中隨機取出k個元素。你只能遍歷這個鏈表一次。你的算法必須保證取出的元素恰好有k個,且它們都是完全隨機的(出現(xiàn)概率均等)。