分布式的一些思考?


一、前言

     最近系統上遇到一些問題,我又仔細去思考了一下CAP相關方面的東西,有點感悟想寫篇文章,來好好思索下CAP這個東西;

二、先聊聊一聊我遇到的問題?

     簡單的說說我的場景,MQ推送消息過來以后寫入redis,然后多個進程去消費redis中的數據,最后處理完成進入ES。最近更改一些需求,要求必須是只能生成一條明細,我們系統可能推送多次,我們通過緩存是可以判斷出最早的一條,但是系統上線以后還是會出現多條,后來經過排查發現原來是MQ時序問題,導致最終生成2條明細,后來我采用使用唯一ID處理這個問題,中間還思考通過ES版本號處理的這種方式,最終還是采用唯一Id處理,這里我們不比較這兩種方式好壞。還是要關注我們說主題分布式的思考,我只想通過我這例子來說說CAP到底是處理什么問題的?

      

      上圖基本就是我們處理數據的流程,我省去了很多東西,比如分布式鎖、緩存呀等等這些東西。我們單純就借助這個模型來說說分布式的問題,A、B、C代表進程,我們都是分開部署多個節點在不同的機器上,類似於很多單體Web程序部署多台機器上通過Nginx分發處理請求,我們這些也都可以算是分布式系統,我們只是單純自己玩,不相互聯系而已,以一個不恰當的比喻來說最熟悉的陌生人。那CAP是處理什么問題的,大家可以看下這篇文章,看不懂可以翻譯下,當然我就是屬於看不懂的,哈哈。摘錄下其中比較重要的話,翻譯過來以后是:

      在一個分布式系統(指互相連接並共享數據的節點的集合)中,在讀/寫操作的時候,一致性(Consistence)、可用性(Availability)、分區容錯性(Partition Tolerance)只能同時保證其中兩者,比如我們上面說兩種情況,雖然分布式有讀寫操作,但是系統之間沒有共享數據和相互連接,所以我們可以保證這3者同時存在。這里我們思考一個場景來解釋下什么是共享數據和相互連接,就拿我們經常使用的淘寶買東西來說吧,當你買一件東西的時候,需要查看你的余額,然后發生扣款,打入到第三方賬戶種,這里你的錢就是共享數據和相互連接,明白這兩個概念我們就來解釋解釋CAP的概念。

     一致性(Consistence):其實就是類似於事務的隔離性,客戶端不會讀取到正在提交的事務,只有提交成功以后才客戶端才可以查詢到變更的信息,舉個形象一點的例子來說,淘寶在你下單成功以后才會扣你的錢,不會下單失敗了扣你的錢,在你下單的過程中你的賬戶里面的錢是不會動的,這就是一致性;

     可用性(Availability):非故障的節點在合理的時間內返回合理的響應(不是錯誤和超時的響應),這個我感覺不需要舉例子吧,就是系統的每個功能都能正常的返回結果;

     分區容錯性(Partition Tolerance):當發生網絡分區后,系統依然能夠發揮原來的作用,舉個例子就是當ES某個節點掛掉的時候我們依然可以正常使用,這個例子可能不是恰當,但是能說明分區容錯性的重要性,后面我們再來討論下ES的CAP設計,這還是一件蠻有意思的事情;

     在了解這3者之間的關系時候,我們就來思考下為什么只能三選二?在分布式系統中,必須要多台機器部署才能叫做分布式,多台機器相互聯系的時候可能會發生網絡或者其他一些故障,我們在設計的時候必須考慮到P,這個時候我們就該考慮C和A為什么不能共存,這二者本就是矛和盾的存在,當發生分區故障的時候,為了保證C,系統必須禁止寫入,當有寫入的請求的時候,系統就會返回錯誤,這個時候就和A沖突掉了,A要求的是不能是錯誤和超時響應,所以這就分布式系統理論上不能夠選着CA,只能夠選擇CP和AP;

三、分析一波

     前幾篇博客一直都是在分析ES,那我們就來分析分析ES中CAP應用,大家可以提出不同的意見,支持辯駁。之前ES系列文章中也講過ES會有腦裂的現象,這就是ES在P上的設計,這個不是我們討論的重點,我們重點是ES到底是CP還是AP?可以在這幾方面的進行討論,讀,寫去解釋下ES對於A和C的設計。

     讀

     在ES讀取數據的時候有preference這個類型,默認情況下操作在可用的分片中隨機讀取,我們可以通過設置參數來控制只讀主,不懂這個大家可以參考下官方文檔,做一點深層次思考preference的設計就是A和C的權衡,當我們系統要求很高的一致性性的時候我們就可以只讀主分片,當要求不高的時候我們就可以隨機讀取,具體大家使用可以根據自己系統進行選擇;

   

    在之前的系列中也講過ES的translog(事務日志)機制和flush機制,其實這里面的設計也是ES對C和A的選擇,只是權力交給了我們,大家具體可以參考官方文檔,這里我們也做下介紹,

    TransLog

    index.translog.durability:如果設為 async,默認情況下,ES 會每隔五秒對 TransLog 執行一次 fsync 和 commit 的操作;如果設為 request(default),則在每次真正執行index、delete、update 或者 bulk index 操作前立刻將 TransLog fsync 到每一個主分片和副本分片中,並返回成功;

    index.translog.sync_interval:設置為async時,每次持久化間隔的時間;

    還有上面我們講述的ES鎖的控制,有樂觀和悲觀鎖,樂觀鎖是通過版本控制也就是我們常用的最終一致,悲觀鎖是強一致,設計方面的東西就理解到這里,其實我認為ES跟偏向於AP的設計,畢竟如果對這些不是很了解的話,他都是默認高可用,其實某些情況下還是不要過多執着於這個系統到底是CP還是AP,畢竟有些特殊情況嘛。

四、結束

    馬上就要年關了,該寫篇總結了,給自己指定的很多指標還是沒有完成,還需要多努力,歡迎大家加群438836709,歡迎大家關注我!

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM