1. 程式人生 > 其它 >分散式系統中的一些問題

分散式系統中的一些問題

一.CAP理論,BASE理論?

CAP:

  • C:強一致性,保證每一節點(微服務)統一時間點資料的完全一致
  • A:可用性,整個系統是一直可用的,而且是正常響應時間。不允許出現使用者訪問失敗的情況
  • P:分割槽容錯性,某一個節點或者網路分割槽發生故障時,整個系統還是可用的,對於使用者來說沒有影響

注意:CAP理論就是說在分散式儲存系統中,最多隻能實現上面的兩點。P一定要實現,所以就是CP和AP的權衡。


BASE:

  • BA:基本可用,系統出現問題,使用者的響應時間增加了,或者非核心功能不可用了。都是可以的。
  • S:軟狀態,資料同步允許有延遲,這一段延遲的狀態就是軟狀態。
  • E:資料最終一致性,在經過一段時間的資料同步後,最終能達到一直就行,不要求實時。

總結:cap是最理想化的,base是對cap的一些理解,更加現實化,是對cap的妥協。

二.負載均衡演算法,型別?

演算法:

  • 輪詢法加權輪詢法
  • 隨機法加權隨機法
  • 源地址雜湊法:根據客戶端ip地址,通過雜湊計算得到一個數值,對伺服器列表進行取模,得到的結果就是要訪問的伺服器的序號。
    • 可以保證同一個ip地址的客戶,每次請求都會對映到指定的伺服器.
  • 最小連線數法:比較靈活和智慧,比如A伺服器有5個連結,B有3個,C沒有連結。下次請求就會進入C伺服器。

型別:

  • DNS實現的負載均衡:訪問一個域名,對映到不同的ip地址
  • 硬體負載均衡:F5和A10
  • 軟體負載均衡: Nginx,HAproxy,LVS等
三.分散式架構下,session共享有什麼方案?
  • 使用jwt
  • 使用cookie (有安全風險)
  • 伺服器之間進行session同步:保證每個伺服器都有session資訊,消耗比較大。
  • ip繫結策略:比如使用Ngnix進行源地址雜湊法的負載均衡,讓每一個ip固定訪問一個伺服器, 但是這種就失去分散式的作用。
  • 使用redis儲存:是業界最廣泛的。 可實現不同服務,不同平臺(網頁/app),甚至不同語言的session共享。
四.分散式id生成方案?
  • UUID時間戳+時鐘序列(計數器)+唯一的IEEE機器識別碼(比如網絡卡的MAC地址)
    • 對資料庫不友好,因為隨機不連續。mysql的主鍵預設使用聚集索引,造成索引不連續
  • 資料庫自增:對於資料庫叢集模型,要設定不同的資料庫起始值不同,但是步長(自增幾)相同。
  • Leaf-segment:(美團大眾點評的)採用每次獲取一個ID區間的方式。
    • 比如一次和資料庫的互動, 就請求到100個id,資料來了直接用。避免每次新增資料都請求一個id,增加了資料庫的壓力。 也是對資料庫自增策略的一個優化。
  • 雪花演算法(最流行)
    • snowflake是Twitter開源的分散式ID生成演算法,結果是一個長度為64bit的long型的ID。
    • 其核心思想是:41位時間戳+10位機器id+12位序列號+符號位(0)。 12bit作為毫秒內的流水號,就是說每個節點在每毫秒可以產生4096 個ID,並且是趨勢遞增的。
    • 這樣適合於Mysql的聚集索引,因為趨勢遞增。索引的連續性好。
    • 缺點:依賴於時間戳,時間戳是根據機器的時間得到的。比如linux中,如果人為的進行時鐘回撥,就可能造成id重複。
五.如何實現介面的冪等性?

介面冪等性就是使用者對於同一操作發起的一次請求或者多次請求的結果是一致的,,不會因為多次點選而產生了副作用。比如註冊,支付時,不會因為多次點選產生不正確的結果。

  • mysql 的唯一索引:比如註冊,設定賬號唯一,多次插入時就不會成功。但是需要每次操作資料庫,不好
  • token機制:伺服器在訪問介面前就傳給使用者一個特定token並且儲存在redis,訪問介面帶上該token, 判斷是否是第一次,是的話允許操作,完成邏輯後刪除token;不是的話不允許操作。

  • redis的setnx命令:如圖

  • 版本控制:加樂觀鎖,對於update時常用。
  • 狀態控制:例如訂單的狀態有已支付,未支付,支付中,支付失敗等。只有處於未支付的時候才允許修改為支付中

寄語:寶劍鋒從磨礪出,梅花香自苦寒來