親,轉載請保留以下信息
@from : http://blog.csdn.net/larrylgq/article/details/7851207
@author :呂桂強
@email; [email protected]
存儲
從理論角度
CAP:(Consistency-Availability-Partition Tolerance
數據一致性(C): 等同於所有節點訪問同一份最新的數據副本;
對數據更新具備高可用性(A): 在可寫的時候可讀, 可讀的時候可寫,最少的停工時間
能容忍網絡分區(P)
eg:
傳統數據庫一般採用CA即強一致性和高可用性
nosql,雲存儲等一般採用降低一致性的代價來獲得另外2個因素
ACID:按照CAP分法ACID是許多CA型關係數據庫多采用的原則:
A:Atomicity原子性,事務作爲最小單位,要麼不執行要麼完全執行
C:Consistency一致性,一個事務把一個對象從一個合法狀態轉到另一個合法狀態,如果交易失敗,把對象恢復到前一個合法狀態。即在事務開始之前和事務結束以後,數據庫的完整性約束沒有被破壞
I:Isolation獨立性(隔離性),事務的執行是互不干擾的,一個事務不可能看到其他事務運行時,中間某一時刻的數據。
D:Durability:事務完成以後,該事務所對數據庫所作的更改便持久的保存在數據庫之中,並不會被回滾
BASE:一般是通過犧牲強一致性,來換取可用性和分佈式
BA:Basically Aavilable基本可用:允許偶爾的失敗,只要保證絕大多數情況下系統可用
S:Soft State軟狀態:無連接?無狀態?
E:Eventual Consistency最終一致性:要求數據在一定的時間內達到一致性
以雲存儲爲例:目前的雲存儲多以整體上採用BASE局部採用ACID,由於使用分佈式使用多備份所以多采用最終一致性
Nosql常見的數據模型有key/value和Schema Free(自由列表模式)兩種,
key/value,每條記錄由2個域組成,一個作爲主鍵,一個存儲記錄的數據(mongodb)
Schema Free, 每條記錄有一個主鍵,若干條列組成,有點類似關係型數據庫(hbase)
在實現這些模型的時候基本使用2種實現方式:哈希加鏈表,或者B+樹的方式
哈希加鏈表:通過將key進行哈希來確定存儲位置,相同哈希值的數據存儲成鏈表
基本的hash尋址算法有除法散列法,平方散列法,斐波那契(Fibonacci)散列法等,但是java是這樣做的
static int indexFor(int h, int length) {
return h & (length-1);
}
java會用key的hashcode值與數組的槽數-1進行與運算
這裏會有一個問題只有當數組的槽數爲2的n次方-1,其二進制全是1的(如2的2次方-1=11)的時候哈希值產生碰撞的概率是最小的
所以在java中hashmap的數組的初始大小是16(2的4次方)
hashmap的問題
hashmap的resize:
當不斷put數據使數據慢慢變大的時候,剛開始的數組已經不能滿足需求了,我們需要擴大數組的槽數
hashmap中有loadFactor屬性,該屬性默認爲0.75,即元素個數達到數組的百分之七十五的時候,數組槽數會進行翻倍,並且之前已存入的數據會重新進行計算。
so:如果我們可以預估我們會在hashmap中存放1000個數據,那麼我們就要確保數組的槽數乘上0.75大於1000,我們得到1366,如果我們這樣寫new HashMap(1366),java會自動幫我們轉換成new HashMap(2048)(2的n次方)
B+樹:B+樹的特點
1.節點中關鍵字數量與字節點數相同。
2.所有葉子結點中包含全部指向記錄的指針
3.葉子結點按照自小而大順序鏈接
5通常在B+樹上有兩個頭指針,一個指向根結點,一個指向關鍵字最小的葉子結點
(爬蟲會有深度優先,廣度優先的算法)
來自百度的圖
so:hash查找單條非常快
b+樹,範圍查找很快(深度優先,廣度優先的遍歷等)
需要一個可以排序的hash結構
空間換時間:跳錶+hashtable實現可排序的hash
跳錶結構
so:增,刪,改(通過跳錶)的複雜度爲o(log(n))
查(通過hashtable)的複雜度爲O(1)
當然我們不知道有結構化的數據,特別我們存儲的數據是需要拿來進行復雜的數據挖掘算法,所以有的時候nosql並不能滿足我們的需要
實際的數據
結構化
半結構化(我們的數據)
非結構化
海量(百T級別)
數據偶爾丟掉幾條沒關係
數據質量差
選擇hdfs的原因
hdfs在設計之初考慮到了以下幾個方面:
1,hdfs將採用大量穩定性差的廉價pc來做爲文件存儲設備,所以pc發生死機或硬盤故障的機率極高,應看作是常態,所以hdfs應該提供數據多備份,自動檢測節點存活,和故障機器的自動修復
2,hdfs存儲的大多是大文件,所以針對大文件的讀寫會作出優化
3,對於寫入數據來說,系統會有很多追加操作,而很少會有隨機讀寫
4,對於讀取數據來說,大多數的操作是順序讀,很少有隨機讀
計算
從理論角度
離線計算 :針對海量的,對實時性要求不是很高的數據
實時流計算 :數據清洗,topn等應用場景
列存儲 :大表jion,海量數據實時查找
key-value :對半結構化,非結構化數據的實時查找(結構靈活,適合項目初期的試錯階段)
內存和磁盤計算的區別
尋址
內存是通過電子工作的,所以搜索速度和物理結構無關,進行尋址時只需要微秒級別既可以
磁盤在尋址時需要1,移動磁頭2,旋轉磁盤 因爲磁盤旋轉的速度有限,所以尋址消耗毫秒別時間
*操作系統會將一個連續的數據存放在一起(win一般是4KB),這樣磁盤旋轉一週讀取的數據就會多些,從而提高效率
傳輸速度
內存和硬盤的數據都會被讀到cpu的緩存中,但是從內存到緩存和從硬盤到緩存的傳輸速度是差別很大的
內存到緩存的速度大概有7-8GB/秒,而磁盤到緩存的速度大概只有60MB/秒
so:因此內存計算和磁盤計算的速度差可以達到百萬倍以上
離線計算
hadoop現了mapreduce的思想,將數據切片計算來處理大量的離線數據數據。
hadoop處理的數據必須是已經存放在支持的分佈式文件系統上或者類似hbase的數據庫中,所以hadoop實現的時候是通過移動計算到這些存放數據的機器上來提高效率
ps:針對hadoop我們的使用是開發一個類似pig的mdx框架,與pig的區別是我們的框架會更加的針對業務友好,業務人員只需要瞭解維度信息和需要的度量即可
實時流計算
storm是一個流計算框架,處理的數據是實時消息隊列中的,所以需要我們寫好一個topology邏輯放在那,接收進來的數據來處理,所以是通過移動數據平均分配到機器資源來獲得高效率
列存儲
提出region和Xfile概念(如hbase的HFILE和hive的rcfile以及yuntable的YFile)
根據key將數據分到不同的region,保存log,數據壓縮並行列轉置後存到Xfile,定期或使用內存到了一定闕值flash到硬盤
列存優點舉例-
eg1:通過region和XFile過濾掉大量數據,如果對100g的數據做分析
通過region會過濾掉一大批數據
對於數值類型,每個xfile會有一個預統計(最大最小值)又會過濾掉一部分數據
假設還剩下2.5g的數據
對於頻繁使用的數據會在內存中有緩存
假設命中2g
剩下的0.5g會已壓縮的方式存放在硬盤(定長字段壓縮比更大,當然數字的壓縮比最大)
so-100g的查詢=》2g的內存查找+0.5g的硬盤查找(內存尋址是硬盤尋址的幾百萬倍)
eg2:通過動態擴展列來進行大表的jion
google的bigtable進行cookie的join,是將一個幾千萬的用戶行爲的表jion到一張100億行的cookie大表,它只需要將新的表根據cookie重新做一下索引即可,因爲數據是列存儲所以具體的數據存儲不需要實際的硬盤移動,大大減少了jion的時間,儘管這個表有幾十萬的列但對查找幾乎是沒有影響的
key-value
存儲非結構化數據
-eg:評論,問答
再看下數據
結構化
半結構化(我們的數據)
非結構化
海量(百T級別)
數據偶爾丟掉幾條沒關係
數據質量差
到目前爲止我們的處理方案是:
離線分析(對實時性要求不高-hadoop)-結構化,半結構化,非結構化
實時分析(對實時性要求極高-storm)-結構化,半結構化,非結構化
實時查找(經常性對大量數據進行count等操作-infobright,hbase)-結構化,部分支持半結構化
有時我們需要對非結構化的數據做一些實時搜索的功能keyvalue搞不定怎麼辦--實時搜索(巧妙設計數據結構)
我們的做法是:
倒排索引
+關鍵字的前綴冗餘
具體關鍵字的前綴冗餘使用redis的zset完成,其本質也是一個hashtable+跳錶的所以結構
這樣存的時候需要切詞,存儲,key和關鍵字映射的存儲,前綴和關鍵字映射的存儲
但是讀的時候是非常迅速的,如下圖當用戶輸入J 就可以很快的找到關於java等的信息(當然還需要一些評分,權重算法)
服務架構需要考慮的問題:
CPU負載和I/O負載(計算密集型和io密集型)
CPU負載-計算密集型
所謂CPU負載就是通常的web服務等,這些服務基本上只消耗cpu,所以只要增加安裝相同服務的服務器,然後就可已通過負載均衡器工作了
I/O負載-io密集型
1.數據的切割和在機器間的分配策略(原則是儘量移動計算而不是移動數據)
2.如何通過多備份來確保數據的可用性(確保多備份的一致性)
3.如何使集羣針對性強的響應客戶端的讀寫請求
4.如何實現集羣中單臺機器的熱拔插
5.好的負載均衡策略
6.網絡通信延遲,因爲計算機運行的速度是微秒甚至納秒,所以毫秒級別的延遲對程序來說性能損害是極大的
ps:我們平常使用的路由器一般pps(每秒轉發數爲幾十萬左右),所以一般的千兆以太網的極限就在幾十萬/秒
除此之外由於正常的路由器的ARP表上限爲900左右
兩個原因導致一個子網中機器不能過多,當集羣中機器過多時就需要進行網絡的層次話
虛擬化優點
1,擴展性-可以動態的遷移和複製,使得服務器增加變得更簡單
2,提高資源利用率
3,降低運維成本(遠程管理,環境更單一
異常行爲局部化,使得主機控制更簡單)
4,提高可用性(抽象硬件差異)
5, 調整負載(軟件層面對負載進行控制,當監測到負載消耗異常可重啓進程或者虛擬機)
缺點
1,虛擬機本身的損耗(cpu,內存)
2,網絡性能損耗近一半
3,I/O性能略微降低0.5%左右