數據庫存儲大致分爲如下幾類,有關係型(事務型)的數據庫,以oracle、mysql爲表明,有keyvalue數據庫,以redis和memcached db爲表明,有文檔型數據庫如mongodb,有列式分佈式數據庫以HBase,cassandra,dynamo爲表明,還有其餘的圖形數據庫、對象數據 庫、xml數據庫等。每種類型的數據庫應用的業務領域是不同的,下面從內存型、關係型、分佈式三個維度針對相關的產品作性能可用性等方面的考量分析。node
內存型的數據庫,以高併發高性能爲目標,在事務性方面沒那麼嚴格,以開源nosql數據庫mongodb、redis爲例mysql
Ø Mongodbreact
通訊方式web
多線程方式,主線程監聽新的鏈接,鏈接後,啓動新的線程作數據的操做(IO切換)。redis
數據結構算法
數據庫-->collection-->recordsql
MongoDB在數據存儲上按命名空間來劃分,一個collection是一個命名空間,一個索引也是一個命名空間。mongodb
同一個命名空間的數據被分紅不少個Extent,Extent之間使用雙向鏈表鏈接。數據庫
在每個Extent中,保存了具體每一行的數據,這些數據也是經過雙向連接鏈接的。瀏覽器
每一行數據存儲空間不只包括數據佔用空間,還可能包含一部分附加空間,這使得在數據update變大後能夠不移動位置。
索引以BTree結構實現。
若是你開啓了jorunaling日誌,那麼還會有一些文件存儲着你全部的操做記錄。
持久化存儲
MMap方式把文件地址映射到內存的地址空間,直接操做內存地址空間就能夠操做文件,不用再調用write,read操做,性能比較高。
mongodb調用mmap把磁盤中的數據映射到內存中的,因此必須有一個機制時刻的刷數據到硬盤才能保證可靠性,多久刷一次是與syncdelay參數相關的。
journal(進行恢復用)是Mongodb中的redo log,而Oplog則是負責複製的binlog。若是打開journal,那麼即便斷電也只會丟失100ms的數據,這對大多數應用來講均可以容忍了。從1.9.2+,mongodb都會默認打開journal功能,以確保數據安全。並且journal的刷新時間是能夠改變的,2-300ms的範圍,使用 --journalCommitInterval 命令。Oplog和數據刷新到磁盤的時間是60s,對於複製來講,不用等到oplog刷新磁盤,在內存中就能夠直接複製到Sencondary節點。
事務支持
Mongodb只支持對單行記錄的原子操做
HA集羣
用的比較多的是Replica Sets,採用選舉算法,自動進行leader選舉,在保證可用性的同時,能夠作到強一致性要求。
固然對於大量的數據,mongodb也提供了數據的切分架構Sharding。
Ø Redis
豐富的數據結構,高速的響應速度,內存操做
通訊方式
因都在內存操做,因此邏輯的操做很是快,減小了CPU的切換開銷,因此爲單線程的模式(邏輯處理線程和主線程是一個)。
reactor模式,實現本身的多路複用NIO機制(epoll,select,kqueue等)
單線程處理多任務
數據結構
hash+bucket結構,當鏈表的長度過長時,會採起遷移的措施(擴展原來兩倍的hash表,把數據遷移過去,expand+rehash)
持久化存儲
a、全量持久化RDB(遍歷redisDB,讀取bucket中的key,value),save命令阻塞主線程,bgsave開啓子進程進行snapshot持久化操做,生成rdb文件。
在shutdown時,會調用save操做
數據發生變化,在多少秒內觸發一次bgsave
sync,master接受slave發出來的命令
b、增量持久化(aof相似redolog),先寫到日誌buffer,再flush到日誌文件中(flush的策略能夠配置的,而已單條,也能夠批量),只有flush到文件上的,才真正返回客戶端。
要定時對aof文件和rdb文件作合併操做(在快照過程當中,變化的數據先寫到aof buf中等子進程完成快照<內存snapshot>後,再進行合併aofbuf變化的部分以及全鏡像數據)。
在高併發訪問模式下,RDB模式使服務的性能指標出現明顯的抖動,aof在性能開銷上比RDB好,可是恢復時從新加載到內存的時間和數據量成正比。
集羣HA
通用的解決方案是主從備份切換,採用HA軟件,使得失效的主redis能夠快速的切換到從redis上。主從數據的同步採用複製機制,該場景能夠作讀寫分離。
目前在複製方面,存在的一個問題是在遇到網絡不穩定的狀況下,Slave和Master斷開(包括閃斷)會致使Master須要將內存中的數據所有從新生成rdb文件(快照文件),而後傳輸給Slave。Slave接收完Master傳遞過來的rdb文件之後會將自身的內存清空,把rdb文件從新加載到內存中。這種方式效率比較低下,在後面的將來版本Redis2.8做者已經實現了部分複製的功能。
關係型數據庫在知足併發性能的同時,也須要知足事務性,以mysql數據庫爲例,講述架構設計原理,在性能方面的考慮,以及如何知足可用性的需求。
Ø mysql的架構原理(innodb)
在架構上,mysql分爲server層和存儲引擎層。
Server層的架構對於不一樣的存儲引擎來說都是同樣的,包括鏈接/線程處理、查詢處理(parser、optimizer)以及其餘系統任務。存儲引擎層有不少種,mysql提供了存儲引擎的插件式結構,支持多種存儲引擎,用的最普遍的是innodb和myisamin;inodb主要面向OLTP方面的應用,支持事務處理,myisam不支持事務,表鎖,對OLAP操做速度快。
如下主要針對innodb存儲引擎作相關介紹。
在線程處理方面,Mysql是多線程的架構,由一個master線程,一個鎖監控線程,一個錯誤監控線程,和多個IO線程組成。而且對一個鏈接會開啓一個線程進行服務。io線程又分爲節省隨機IO的insert buffer,用於事務控制的相似於oracle的redo log,以及多個write,多個read的硬盤和內存交換的IO線程。
在內存分配方面,包括innodb buffer pool ,以及log buffer。其中innodb buffer pool包括insert buffer、datapage、index page、數據字典、自適應hash。Log buffer用於緩存事務日誌,提供性能。
在數據結構方面,innodb包括表空間、段、區、頁/塊,行。索引結構是B+tree結構,包括二級索引和主鍵索引,二級索引的葉子節點是主鍵PK,根據主鍵索引的葉子節點指向存儲的數據塊。這種B+樹存儲結構能夠更好的知足隨機查詢操做IO要求,分爲數據頁和二級索引頁,修改二級索引頁面涉及到隨機操做,爲了提升寫入時的性能,採用insert buffer作順序的寫入,再由後臺線程以必定頻率將多個插入合併到二級索引頁面。爲了保證數據庫的一致性(內存和硬盤數據文件),以及縮短實例恢復的時間,關係型數據庫還有一個checkpoint的功能,用於把內存buffer中以前的髒頁按照比例(老的LSN)寫入磁盤,這樣redolog文件的LSN之前的日誌就能夠被覆蓋了,進行循環使用;在失效恢復時,只須要從日誌中LSN點進行恢復便可。
在事務特性支持上,關係型數據庫須要知足ACID四個特性,須要根據不一樣的事務併發和數據可見性要求,定義了不一樣的事務隔離級別,而且離不開對資源爭用的鎖機制,要避免產生死鎖,mysql在Server層和存儲引擎層作併發控制,主要體如今讀寫鎖,根據鎖粒度不一樣,有各個級別的鎖(表鎖、行鎖、頁鎖、MVCC);基於提升併發性能的考慮,使用多版本併發控制MVCC來支持事務的隔離,並基於undo來實現,在作事務回滾時,也會用到undo段。mysql 用redolog來保證數據的寫入的性能和失效恢復,在修改數據時只須要修改內存,再把修改行爲記錄到事務日誌中(順序IO),不用每次將數據修改自己持久化到硬盤(隨機IO),大大提升性能。
在可靠性方面,innodb存儲引擎提供了兩次寫機制double writer用於防止在flush頁面到存儲上出現的錯誤,解決磁盤half-writern的問題。
Ø 對於高併發高性能的mysql來說,能夠在多個維度進行性能方面的調優。
a、硬件級別,
日誌和數據的存儲,須要分開,日誌是順序的寫,須要作raid1+0,而且用buffer-IO;數據是離散的讀寫,走direct IO便可,避免走文件系統cache帶來的開銷。
存儲能力,SAS盤raid操做(raid卡緩存,關閉讀cache,關閉磁盤cache,關閉預讀,只用writeback buffer,不過須要考慮充放電的問題),固然若是數據規模不大,數據的存儲能夠用高速的設備,Fusion IO、SSD。
對於數據的寫入,控制髒頁刷新的頻率,對於數據的讀取,控制cache hit率;所以而估算系統須要的IOPS,評估須要的硬盤數量(fusion io上到IOPS 在10w以上,普通的硬盤150)。
Cpu方面,單實例關閉NUMA,mysql對多核的支持不是太好,能夠對多實例進行CPU綁定。
b、操做系統級別,
內核以及socket的優化,網絡優化bond、文件系統、IO調度
innodb主要用在OLTP類應用,通常都是IO密集型的應用,在提升IO能力的基礎上,充分利用cache機制。須要考慮的內容有,
在保證系統可用內存的基礎上,儘量的擴大innodb buffer pool,通常設置爲物理內存的3/4
文件系統的使用,只在記錄事務日誌的時候用文件系統的cache;儘可能避免mysql用到swap(能夠將vm.swappiness=0,內存緊張時,釋放文件系統cache)
IO調度優化,減小沒必要要的阻塞,下降隨機IO訪問的延時(CFQ、Deadline、NOOP)
c、server以及存儲引擎級別(鏈接管理、網絡管理、table管理、日誌)
包括cache/buffer、Connection、IO
d、應用級別(好比索引的考慮,schema的優化適當冗餘;優化sql查詢致使的CPU問題和內存問題,減小鎖的範圍,減小回表掃描,覆蓋索引)
Ø 在高可用實踐方面,
支持master-master、master-slave模式,master-master模式是一個做爲主負責讀寫,另一個做爲standby提供災備,maser-slave是一個做爲主提供寫操做,其餘幾個節點做爲讀操做,支持讀寫分離。
對於節點主備失效檢測和切換,能夠採用HA軟件,固然也能夠從更細粒度定製的角度,採用zookeeper做爲集羣的協調服務。
對於分佈式的系統來說,數據庫主備切換的一致性始終是一個問題,能夠有如下幾種方式:
a、集羣方式,如oracle的rack,缺點是比較複雜
b、共享SAN存儲方式,相關的數據文件和日誌文件都放在共享存儲上,優勢是主備切換時數據保持一致,不會丟失,但因爲備機有一段時間的拉起,會有短暫的不可用狀態
c、主備進行數據同步的方式,常見的是日誌的同步,能夠保障熱備,實時性好,可是切換時,可能有部分數據沒有同步過來,帶來了數據的一致性問題。能夠在操做主數據庫的同時,記錄操做日誌,切換到備時,會和操做日誌作個check,補齊未同步過來的數據;
d、還有一種作法是備庫切換到主庫的regolog的存儲上,保證數據不丟失。
數據庫主從複製的效率在mysql上不是過高,主要緣由是事務是嚴格保持順序的,索引mysql在複製方面包括日誌IO和relog log兩個過程都是單線程的串行操做,在數據複製優化方面,儘可能減小IO的影響。不過到了Mysql5.6版本,能夠支持在不一樣的庫上的並行複製。
Ø 基於不一樣業務要求的存取方式
平臺業務中,不一樣的業務有不一樣的存取要求,好比典型的兩大業務用戶和訂單,用戶通常來說總量是可控的,而訂單是不斷地遞增的,對於用戶表首先採起分庫切分,每一個sharding作一主多讀,一樣對於訂單因更多需求的是用戶查詢本身的訂單,也須要按照用戶進行切分訂單庫,而且支持一主多讀。
在硬件存儲方面,對於事務日誌因是順序寫,閃存的優點比硬盤高不了多少,因此採起電池保護的寫緩存的raid卡存儲;對於數據文件,不管是對用戶或者訂單都會存在大量的隨機讀寫操做,固然加大內存是一個方面,另外能夠採用高速的IO設備閃存,好比PCIe卡 fusion-io。使用閃存也適合在單線程的負載中,好比主從複製,能夠對從節點配置fusion-IO卡,下降複製的延遲。
對於訂單業務來說,量是不斷遞增的,PCIe卡存儲容量比較有限,而且訂單業務的熱數據只有最近一段時間的(好比近3個月的),對此這裏列兩種解決方案,一種是flashcache方式,採用基於閃存和硬盤存儲的開源混合存儲方式,在閃存中存儲熱點的數據。另一種是能夠按期把老的數據導出到分佈式數據庫HBase中,用戶在查詢訂單列表是近期的數據從mysql中獲取,老的數據能夠從HBase中查詢,固然須要HBase良好的rowkey設計以適應查詢需求。
對 於數據的高併發的訪問,傳統的關係型數據庫提供讀寫分離的方案,可是帶來的確實數據的一致性問題提供的數據切分的方案;對於愈來愈多的海量數據,傳統的數 據庫採用的是分庫分表,實現起來比較複雜,後期要不斷的進行遷移維護;對於高可用和伸縮方面,傳統數據採用的是主備、主從、多主的方案,可是自己擴展性比 較差,增長節點和宕機須要進行數據的遷移。對於以上提出的這些問題,分佈式數據庫HBase有一套完善的解決方案,適用於高併發海量數據存取的要求。
Ø HBase
基於列式的高效存儲下降IO
一般的查詢不須要一行的所有字段,大多數只須要幾個字段
對與面向行的存儲系統,每次查詢都會所有數據取出,而後再從中選出須要的字段
面向列的存儲系統能夠單獨查詢某一列,從而大大下降IO
提升壓縮效率
同列數據具備很高的類似性,會增長壓縮效率
Hbase的不少特性,都是由列存儲決定的
高性能
LSM Tree
適合高速寫的場景
強一致的數據訪問
MVCC
HBase的一致性數據訪問是經過MVCC來實現的。
HBase在寫數據的過程當中,須要通過好幾個階段,寫HLog,寫memstore,更新MVCC;
只有更新了MVCC,纔算真正memstore寫成功,其中事務的隔離須要有mvcc的來控制,好比讀數據不能夠獲取別的線程還未提交的數據。
高可靠
HBase的數據存儲基於HDFS,提供了冗餘機制。
Region節點的宕機,對於內存中的數據還未flush到文件中,提供了可靠的恢復機制。
可伸縮,自動切分,遷移
經過Zookeeper定位目標Region Server,最後定位Region。
Region Server擴容,經過將自身發佈到Master,Master均勻分佈。
可用性
存在單點故障,Region Server宕機後,短期內該server維護的region沒法訪問,等待failover生效。
經過Master維護各Region Server健康情況和Region分佈。
多個Master,Master宕機有zookeeper的paxos投票機制選取下一任Master。Master就算全宕機,也不影響Region讀寫。Master僅充當一個自動運維角色。
HDFS爲分佈式存儲引擎,一備三,高可靠,0數據丟失。
HDFS的namenode是一個SPOF。
爲避免單個region訪問過於頻繁,單機壓力過大,提供了split機制
HBase的寫入是LSM-TREE的架構方式,隨着數據的append,HFile愈來愈多,HBase提供了HFile文件進行compact,對過時數據進行清除,提升查詢的性能。
Schema free
HBase沒有像關係型數據庫那樣的嚴格的schema,能夠自由的增長和刪除schema中的字段。
HBase分佈式數據庫,對於二級索引支持的不太好,目前只支持在rowkey上的索引,因此rowkey的設計對於查詢的性能來說很是關鍵。
統一的配置庫
部署平臺
大型分佈式系統涉及各類設備,好比網絡交換機,普通PC機, 各類型號的網卡,硬盤,內存等等,還有應用業務層次的監控,數量很是多的時候,出現錯誤的機率也會變大,而且有些監控的時效性要求比較高,有些達到秒級 別;在大量的數據流中須要過濾異常的數據,有時候也對數據會進行上下文相關的複雜計算,進而決定是否須要告警。所以監控平臺的性能、吞吐量、已經可用性就 比較重要,須要規劃統一的一體化的監控平臺對系統進行各個層次的監控。
平臺的數據分類
應用業務級別:應用事件、業務日誌、審計日誌、請求日誌、異常、請求業務metrics、性能度量
系統級別:CPU、內存、網絡、IO
時效性要求
閥值,告警:
實時計算:
近實時分鐘計算
按小時、天的離線分析
實時查詢
架構
節點中Agent代理能夠接收日誌、應用的事件以及經過探針的方式採集數據,agent採集數據的一個原則是和業務應用的流程是異步隔離的,不影響交易流程。
數據統一經過collector集羣進行收集,按照數據的不一樣類型分發到不一樣的計算集羣進行處理;有些數據時效性不是那麼高,好比按小時進行統計,放入hadoop集羣;有些數據是請求流轉的跟蹤數據,須要能夠查詢的,那麼就能夠放入solr集羣進行索引;有些數據須要進行實時計算的進而告警的,須要放到storm集羣中進行處理。
數據通過計算集羣處理後,結果存儲到Mysql或者HBase中。
監控的web應用能夠把監控的實時結果推送到瀏覽器中,也能夠提供API供結果的展示和搜索。