【乾貨】整理分佈式技術框架經常使用的算法及策略

將一些零散的知識點進行整理, 以便加深理解,方便查閱,也但願能幫到你們。html

1、負載均衡算法

1. 隨機

  1. 徹底隨機

經過系統隨機函數,根據後端服務器列表的大小值來隨機選擇其中一臺進行訪問。由機率統計理論能夠得知,隨着調用量的增大,其實際效果愈來愈接近於平均分配流量到每一臺後端服務器,也就是輪詢的效果。算法

  1. 加權隨機數據庫

    雖然仍是採用的隨機算法,可是爲每臺服務器根據不一樣的配置和負載狀況來配置不一樣的權重,權重大的服務器得到的機率大一些,權重小的服務器得到的機率小一些。後端

2. 輪詢

  1. 徹底輪詢數組

    將請求按順序輪流地分配到服務器上,它均衡地對待後端的每一臺服務器,而不關心服務器實際的鏈接數和當前的系統負載狀況。緩存

  2. 加權輪詢服務器

    根據服務器的不一樣處理能力,給每一個服務器分配不一樣的權重值,使其可以將請求順序的按照權重分配到後端服務器上,權重越大,對應的服務器每輪所得到的請求數量越多。負載均衡

  3. 平滑加權輪詢異步

    每一個服務器都有兩個權重變量:ide

      a:weight,配置文件中指定的該服務器的權重,這個值是固定不變的;

      b:current_weight,服務器目前的權重(非固定權重)。一開始爲0,以後會動態調整。

      每次當請求到來,選取服務器時,會遍歷數組中全部服務器。對於每一個服務器,讓它的current_weight增長它的weight;同時累加全部服務器的weight,並保存爲total。

      遍歷完全部服務器以後,若是該服務器的current_weight是最大的,就選擇這個服務器處理本次請求。最後把該服務器的current_weight減去total。

3. 哈希(Hash)法

先將後端服務器列表(如:按照地址IP)計算出哈希值,而後映射到HASH環上(若是服務器實例節點較少能夠增長虛擬節點),當接收請求時,根據請求的信息(如請求的客戶端IP、用戶ID等)計算出哈希值,最後將請求信息的哈希值映射到HASH環上,按順時針方向,肯定落在哪一個區間中,則選擇區間的下一個服務器節點做爲處理這次請求的服務器。

4. 最小鏈接數(Least Connections)法

因爲後端服務器的配置不盡相同,對於請求的處理有快有慢,根據後端服務器當前的鏈接狀況,動態地選取其中當前積壓鏈接數最少的一臺服務器來處理當前請求,儘量地提升後端服務器的利用效率,將負載合理地分流到每一臺機器。

可參見網上文章:淺談負載均衡算法與實現一致性hash算法釋義

2、限流算法

1. 計數器(固定窗口)算法

計數器算法是使用計數器在週期內累加訪問次數,當達到設定的限流值時,觸發限流策略。下一個週期開始時,進行清零,從新計數。

2. 滑動窗口算法

滑動窗口算法是將時間週期分爲N個小週期,分別記錄每一個小週期內訪問次數,而且根據時間滑動刪除過時的小週期。

3. 漏桶算法

漏桶算法是訪問請求到達時直接放入漏桶,如當前容量已達到上限(限流值),則進行丟棄(觸發限流策略)。漏桶以固定的速率進行釋放訪問請求(即請求經過),直到漏桶爲空。

4. 令牌桶算法

令牌桶算法是程序以r(r=時間週期/限流值)的速度向令牌桶中增長令牌,直到令牌桶滿,請求到達時向令牌桶請求令牌,如獲取到令牌則經過請求,不然觸發限流策略。

可參見網上文章:

經常使用4種限流算法介紹及比較

限流相關的算法

3、緩存淘汰(過時)策略

1. FIFO(First In First out)

先進先出,淘汰最早緩存的數據,新加入的緩存數據最遲被淘汰,徹底符合隊列。

2. LRU(Least recently used)

最近最少使用,淘汰必定時期內被訪問次數最少的緩存數據,以次數做爲參考。

3. LFU(Least frequently used)

最近使用次數最少,淘汰最長時間未被使用的頁面,以時間做爲參考。

4. Two queues(2Q)

2Q算法有兩個緩存隊列,一個是FIFO隊列,一個是LRU隊列。當數據第一次訪問時,2Q算法將數據緩存在FIFO隊列裏面,當數據第二次被訪問時,則將數據從FIFO隊列移到LRU隊列裏面,兩個隊列各自按照本身的方法淘汰數據。

可參見網上文章:
經常使用緩存策略
Redis的過時策略和內存淘汰策略

4、緩存更新策略

1. Cache Aside

應用在查詢數據的時候,先從緩存Cache中讀取數據,若是緩存中沒有,則再從數據庫中讀取數據,獲得數據庫的數據以後,將這個數據也放到緩存Cache中。若是應用要更新某個數據,也是先去更新數據庫中的數據,更新完成以後,則經過指令讓緩存Cache中的數據失效。

2. Read/Write Through

應用要讀數據和更新數據都直接訪問緩存服務,緩存服務同步的將數據更新到數據庫,在應用的眼中只有緩存服務。

3. Write Behind

應用要讀數據和更新數據都直接訪問緩存服務,緩存服務異步的將數據更新到數據庫(經過異步任務)

4. refresh-ahead

在緩存數據過時前,能自動的刷新緩存數據(在緩存過時前剩餘時間區間內【可自定義】取數據時,緩存先將以前緩存的結果返回給外部應用程序,而後異步的再從數據庫去更新緩存中的值,以儘量的保證緩存的值是最新的。若是取數據的的時候超過了緩存的過時時間,就安裝read-through的方式執行)

可參見網上文章:
Caching漫談--關於Cache的幾個理論
緩存服務的更新策略有哪些?

5、分庫分表方式與策略

1. 分庫分表方式

  1. 垂直分庫

    爲依據,按照業務歸屬不一樣,將不一樣的拆分到不一樣的中。

    結果:

    • 每一個結構都不同;
    • 每一個數據也不同,沒有交集;
    • 全部並集是全量數據;
  2. 垂直分表

    字段爲依據,按照字段的活躍性,將中字段拆到不一樣的(主表和擴展表)中。

    結果

    • 每一個結構都不同;

    • 每一個數據也不同,通常來講,每一個表的字段至少有一列交集,通常是主鍵,用於關聯數據;

    • 全部並集是全量數據;

  3. 水平分庫

    字段爲依據,按照必定策略(hash、range等),將一個中的數據拆分到多個中。

    結果:

    • 每一個結構都同樣;
    • 每一個數據都不同,沒有交集;
    • 全部並集是全量數據;
  4. 水平分表

    字段爲依據,按照必定策略(hash、range等),將一個中的數據拆分到多個中。

    結果:

    • 每一個結構都同樣;
    • 每一個數據都不同,沒有交集;
    • 全部並集是全量數據;

2. 分庫分表策略

  1. hash取模

    對指定的路由key(如:id)按分表總數進行取模,獲得的結果即爲對應的表序號

    • 優勢:訂單數據能夠均勻的放到那4張表中,這樣此訂單進行操做時,就不會有熱點問題。
    • 缺點:未來的數據遷移和擴容,會很難。
  2. range範圍

    按必定範圍路由key(如:id,時間戳)把對應的記錄存放到同一張表中,多個範圍區間則存放多張表【即:每一個範圍區間對應一張表】

    • 優勢:有利於未來的擴容,不須要作數據遷移
    • 有熱點問題,在某一個時間範圍內某個表的IO壓力可能會很是大
  3. range+hash分組

    首先用range方案讓數據落地到一個範圍裏面(即:分組區間)。這樣之後id再變大,那之前的數據是不須要遷移的。而後在這個範圍裏面(即:分組區間)再根據路由key(如:id)按分表總數(注意含全部分組中的全部分表總數)進行取模,獲得的結果即爲對應的表序號【即:在必定範圍內均勻分佈數據】

    • 優勢:避免熱問題,擴容相對容易
    • 缺點:實現較複雜
  4. 一致性hash

    經過哈希函數,每一個節點都會被分配到環上的一個位置,每一個鍵值也會被映射到環上的一個位置。這個鍵值最終被放置在距離該它的位置最近的,且位置編號大於等於該值的節點上面,即放置到順時針的下一個節點上面。

    • 優勢:避免熱問題,擴容相對容易

    • 缺點:實現較複雜

​ 可參見網上文章:

海量數據分庫分表方案(一)算法方案
數據庫怎麼分庫分表,垂直?水平?
分庫分表?如何作到永不遷移數據和避免熱點?

相關文章
相關標籤/搜索