本文只是對所讀書籍做一些總結,不代表博主的實戰經驗,#_#(注:有時候中間件的可擴展性視爲可伸縮性,因爲可擴展性和高可用性通常是相關聯的)。
一、高性能
也叫高併發,主要指標有響應時間、併發數、吞吐量等。
1、Web前端方面
瀏覽器:緩存、壓縮、合併請求、減少Cookie傳輸、延遲加載JS
CDN、反向代理:緩存靜態資源
2、應用服務方面
使用緩存:本地緩存、分佈式緩存、多級緩存
儘量異步:消息隊列(MQ)、異步方法(@Async)
搭建集羣:橫向擴展
優化編碼:多線程、算法、數據結構、對象複用(池化)、GC
3、數據庫
字段優化:類型選擇、是否需要索引、冗餘
索引:執行計劃、避免失效
緩存:MySQL緩存、Mybatis一級二級緩存
SQL優化:減少JOIN、批量操作、注意大事務和死鎖
讀寫分離、分庫分表:sharding-jdbc / Mycat
4、中間件
ES、Redis、MQ、ZK...
5、硬件
增加帶寬、換SSD
二、高可用
業界通常使用多少個9衡量,比如4個9即99.99表示一年最多53分鐘不可用。
網站不可用時間(故障時間)= 故障修復時間點 - 故障發現(報告)時間點
1、應用失效轉移
搭建集羣進行負載均衡
2、數據冗餘備份
主從架構:MySQL、Redis
3、優化代碼
限流、降級、超時、重試、隔離
4、避免
壓測、監控
5、緊急處理
回滾、預案
三、可伸縮
臨時搞個促銷,多加幾臺機器性能就上去了,活動結束,機器撤掉------這就體現了可伸縮。
應用服務器集羣:無狀態
緩存服務器集羣:哈希取模算法、一致性哈希算法
數據庫集羣:增加從庫
中間件:不支持的就別用了
四、可擴展
產品:突然想到一個需求,你下班前搞好(調侃,正規點的流程都不允許)
工程師:好咧,我加一下XX就可以了
程序猿:啊?這樣整個XX都要重寫,有點難哦
------顯然,工程師的代碼耦合性低,容易擴展
1、事件驅動架構
觀察者模式(發佈訂閱)、消息隊列(MQ)
2、分佈式服務
業務和基礎可複用的區分拆開
3、數據結構
反例:ElasticSearch修改字段需要重建索引(一般預留字段)
正例:Hbase的列族設計就很靈活
4、開放接口平臺
五、幾種中間件的分佈式數據複製
1、MySQL
異步複製,優先保證可用性,但會最終一致性。
1)主庫每次提交事務之前,將數據更改的事件記錄到二進制日誌(Binary Log)中。
2)首先從庫啓動一個I/O線程,請求主庫建立一個普通的客戶端連接,然後主庫啓動一個特殊的二進制轉儲(binlog dump)線程讀取二進制日誌中的事件,最後從庫的I/O線程將接收到的事件記錄到自己的中繼日誌(Relay Log)中。
3)從庫的SQL線程讀取中繼日誌中的事件將其重放。
基於語句的複製:SQL。基於行的複製:數據。
MySQL能夠動態切換,默認情況下使用基於語句的複製,不行了就切換到基於行的複製。用戶也可以通過binlog_format進行設置。
2、Redis
主從:
異步複製,不滿足強一致性,因爲是否成功不影響主節點對外提供寫服務,所以保證可用性。
從節點會使用各種策略全力追趕主節點,所以最終一致。
Redis同步支持主從同步和從從同步(後續版本增加,以減輕主節點的同步負擔)。
主節點會把寫指令記錄在本地的內存buffer中,然後異步複製到從節點,從節點一邊重放一邊向主節點反饋自己同步的偏移量。buffer有限且是定長的環形數組,如果內容滿了會被從頭覆蓋,這時候需要執行快照同步。
主節點快照同步時把當前內存的全部數據快照到磁盤文件然後把它們傳送到從節點,從節點接收完畢首先清空當前緩存執行全量加載然後繼續增量同步。快照同步過程中如果主節點又發生覆蓋buffer的情況,只能再次進行快照同步了。避免這種死循環可以配置合適的buffer大小參數。
新節點加入時,先快照同步,完成後增量同步。
Redis 2.8.18版本 之後支持快照同步的無盤複製,主節點遍歷內存直接將序列化的內容發送到從節點。
Redis 3.0版本 之後使用wait指令可以讓異步複製變身同步複製,這樣就保證了強一致性。
哨兵模式Sentinel可以監控主節點狀態實現自動主從切換,它的min-slaves-to-write和min-slaves-max-lag兩個選項可以限制主從延遲過大,表示在指定時間內(第二個參數,秒)至少有指定數量(第一個參數)的從節點完成了正常複製,否則就對外停止寫服務,喪失可用性。
集羣:
數據各自獨立(這樣才能擴容)。
3、Zookeeper
採用基於Paxos協議(個人覺得太難理解了~)的ZAB協議。節點分爲Leader、Follower和Observer三種角色類型。
// TODO
4、ElasticSearch
// TODO
5、Eureka
AP優於CP,即優先保證可用性,但會最終一致性。
多個副本之間採用對等複製(Peer to Peer),不分主從,都可以進行寫操作,然後相互之間進行數據更新。這樣難免存在衝突問題,如何解決呢?
Eureka Server啓動時進行syncUp操作,先從其中一個節點獲取註冊的應用實例信息,然後複製到其它節點。複製時使用HEADER_REPLICATION的heep header來標識,這樣其它peer節點收到之後就不會再對它的peer節點進行復制了。
使用lastDirtyTimestamp標識數據版本高低,使用heartbeat也就是renewLease操作進行節點之間數據修復。
6、Consul
// TODO
7、Hadoop
主從:
使用Zookeeper
集羣:
// TODO