【併發編程】高併發相關技術

高併發之擴容思路

垂直擴容(縱向擴展):提升系統部件能力
水平擴容(橫向擴展):增長更多系統成員來實現redis

讀操做擴展:memcache、redis、CDN等緩存
寫操做擴展:Cassandra、Hbase等算法

高併發之緩存思路

緩存特徵

命中率:命中數/(命中數+未命中數)
最大元素(空間)
清空策略:FIFO, LFU, LRU, 過時時間,隨機等數據庫

緩存命中率影響因素

業務場景和業務需求
緩存的設計(粒度和策略)
緩存容量和基礎設施apache

緩存分類和應用場景

本地緩存:編程實現(成員變量、局部變量、靜態變量)、Guava Cache
分佈式緩存:Memcache、Redis編程

高併發場景下緩存的常見問題

緩存一致性緩存

不一致的場景
更新數據庫成功->更新緩存失敗->數據不一致
更新緩存成功->更新數據庫失敗->數據不一致
更新數據庫成功->淘汰緩存失敗->數據不一致
淘汰緩存成功->更新數據庫失敗->查詢緩存miss服務器

緩存併發問題
使用鎖
併發

緩存穿透(擊穿)問題
框架

解決方案:
緩存空對象:對查詢結果爲空的對象也進行緩存,若是是集合,能夠緩存一個空集合
若是是緩存單個對象,能夠經過對象標識區分,防止請求擊穿到數據庫。這種方式實現成本低
適合命中不高可是可能頻繁更新的數據。
單獨過濾處理:對全部可能對應數據爲空的對象單獨存放,並在請求前攔截,防止請求擊穿到數據庫。
這種方式實現複雜,適合命中不高,更新不頻繁的數據。數據庫設計

緩存的雪崩問題

限流、降級、熔斷、多級緩存

高併發之消息隊列思路

消息隊列

開始流程A->發送消息A1到隊列->消息A1被處理->處理消息A1(處理流程A)

消息隊列特性

業務無關:只作消息分發
FIFO:先投遞先到達
容災:節點的動態增刪和消息的持久化
性能:吞吐量提高,系統內部通訊效率提升

爲何須要消息隊列

【生產】和【消費】的速度或穩定性等因素不一致

消息隊列的好處

業務解耦:基於消息的應用關心的是通知不是處理
最終一致性:兩個系統最終狀態一致,如轉帳流程,轉入和轉出要同時成功或失敗。(跨JVM一致性問題的通用解決方案包括最終一致性和強一致性(分佈式事務,技術難度高))實現相對簡單,經過記錄和補償方式處理。狀態包括成功、失敗(記錄、重試)、不肯定。最終一致性不是消息隊列必備特性,可是能夠經過消息隊列實現最終一致性。

Kafka等消息隊列在設計層面上就有丟消息的可能性,如定時刷盤或掉電均可能丟消息,哪怕只有千分之一可能丟消息也要使用其餘手段保證結果正確。
廣播
錯峯與流控
因爲部件或系統性能不一致致使處理能力不一樣,須要消息隊列進行錯峯和流控。

消息隊列不是萬能的,對於須要強事務保證並且延時很敏感的RPC遠程調用優於消息隊列。對於一些無關痛癢或者對於別人很是重要可是對本身不是那麼關心的情事,可經過消息隊列作;支持最終一致性的消息隊列可以用來處理延遲不那麼敏感的分佈式事務場景,相對於笨重的分佈式事務多是更優的處理方式;當上下游處理能力存在差別時,能夠利用消息隊列作一個漏斗,在下游部件有能力處理時再分發,同時以下下游有不少系統關心當前系統發出的通知的時候,也適用消息隊列。

消息隊列舉例

Kafka
RabbitMQ

高併發之應用拆分思路

應用拆分

根據業務功能拆分:
如一個股票系統包括用戶信息、開戶、股票行情、交易、訂單等功能,能夠拆分爲交易中心(股票買入與賣出)、帳戶中心(流程處理、定時任務)、用戶中心(基礎數據維護)、行情中心(定時任務、流程處理)、通知中心(短信、郵件推送)。

優勢:便於管理維護。
缺點:增長了成本和開銷。

應用拆分基本原則

業務優先
按部就班
兼顧技術:重構、分層
可靠測試

應用拆分-思考

應用之間通訊:RPC(dubbo等)--強一致性、消息隊列--最終一致性
應用之間數據庫設計:每一個應用都有獨立的數據庫
避免事務操做跨應用

應用拆分-經常使用組件

服務化 Dubbo
消息隊列
微服務 Spring Cloud

高併發之應用限流思路

應用限流

必定時間內代碼執行的次數

應用限流--算法

計數器法
臨界問題很致命
滑動窗口算法的一種
滑動窗口
時間窗
漏桶算法
接口以恆定速率處理請求
令牌桶算法
能夠很好地處理臨界問題

高併發之服務降級與服務熔斷思路

服務降級

對一些服務和頁面有策略的降級,以此緩解保證部分或大部分用戶獲得響應。若應用處理不了了請求,返回一個默認結果。

服務熔斷

軟件系統裏因爲某種緣由形成系統過載,爲防止系統故障採起的一種保護措施,也稱爲過載保護。

分類:
自動降級:超時、失敗次數、故障、限流
人工降級:秒殺、雙11大促等

服務降級與服務熔斷對比

共性:目的相同(可用性可靠性方面)、最終表現、粒度(服務級,也有更細粒度)、自治性要求高
區別:觸發緣由不一樣(熔斷因爲下游故障引發、降級是從總體負荷考慮)、管理目標層次不一樣(熔斷是框架級處理每一個微服務都須要、降級通常須要對業務有層級區分,降級通常從最外圍服務開始)、實現方式不一樣

服務降級要考慮的問題

核心服務、非核心服務
是否支持降級,降級策略
業務放通場景,策略

Hystrix可用於實現服務降級

高併發之數據庫切庫分庫分表思路

數據庫瓶頸

單個庫數據量太大(1T~2T):多個庫
單個數據庫服務器壓力過大、讀寫瓶頸:多個庫
單個表數據量過大:分表

數據庫切庫

切庫基礎及實際運用:讀寫分離
通常採用一個主庫(實時查詢),多個從庫(非實時查詢)
可使用Spring MVC、AOP、註解實現。(參考手記)

數據庫支持多個數據源與分庫

支持多數據源、分庫
一個數據庫支持多數據源(參考手記)

數據庫分表

當單表數據量過大時,大到作優化和索引後還影響正常業務時就須要分表。(須要提早設計)
單表數據量過千萬時,基本查詢等操做性能會大幅降低

橫向(水平)分表:表結構相同

縱向(垂直)分表:根據數據活躍度分表

數據庫分表:MyBatic分表插件shrdbatis2.0(參考手記)

高併發之高可用手段

任務調度系統分佈式:elastic-job(噹噹開源) + zookeeper
主備切換:apache curator + zookeeper 分佈式鎖實現
兩臺服務器交替做爲主備服務器
監控報警(告警)機制(參考手記)

相關文章
相關標籤/搜索