1、前言html
最近系統上遇到一些問題,我又仔細去思考了一下CAP相關方面的東西,有點感悟想寫篇文章,來好好思索下CAP這個東西;redis
2、先聊聊一聊我遇到的問題?緩存
簡單的說說個人場景,MQ推送消息過來之後寫入redis,而後多個進程去消費redis中的數據,最後處理完成進入ES。最近更改一些需求,要求必須是隻能生成一條明細,咱們系統可能推送屢次,咱們經過緩存是能夠判斷出最先的一條,可是系統上線之後仍是會出現多條,後來通過排查發現原來是MQ時序問題,致使最終生成2條明細,後來我採用使用惟一ID處理這個問題,中間還思考經過ES版本號處理的這種方式,最終仍是採用惟一Id處理,這裏咱們不比較這兩種方式好壞。仍是要關注咱們說主題分佈式的思考,我只想經過我這例子來講說CAP究竟是處理什麼問題的?網絡
上圖基本就是咱們處理數據的流程,我省去了不少東西,好比分佈式鎖、緩存呀等等這些東西。咱們單純就藉助這個模型來講說分佈式的問題,A、B、C表明進程,咱們都是分開部署多個節點在不一樣的機器上,相似於不少單體Web程序部署多臺機器上經過Nginx分發處理請求,咱們這些也均可以算是分佈式系統,咱們只是單純本身玩,不相互聯繫而已,以一個不恰當的比喻來講最熟悉的陌生人。那CAP是處理什麼問題的,你們能夠看下這篇文章,看不懂能夠翻譯下,固然我就是屬於看不懂的,哈哈。摘錄下其中比較重要的話,翻譯過來之後是:async
在一個分佈式系統(指互相鏈接並共享數據的節點的集合)中,在讀/寫操做的時候,一致性(Consistence)、可用性(Availability)、分區容錯性(Partition Tolerance)只能同時保證其中二者,好比咱們上面說兩種狀況,雖然分佈式有讀寫操做,可是系統之間沒有共享數據和相互鏈接,因此咱們能夠保證這3者同時存在。這裏咱們思考一個場景來解釋下什麼是共享數據和相互鏈接,就拿咱們常用的淘寶買東西來講吧,當你買一件東西的時候,須要查看你的餘額,而後發生扣款,打入到第三方帳戶種,這裏你的錢就是共享數據和相互鏈接,明白這兩個概念咱們就來解釋解釋CAP的概念。elasticsearch
一致性(Consistence):其實就是相似於事務的隔離性,客戶端不會讀取到正在提交的事務,只有提交成功之後才客戶端才能夠查詢到變動的信息,舉個形象一點的例子來講,淘寶在你下單成功之後纔會扣你的錢,不會下單失敗了扣你的錢,在你下單的過程當中你的帳戶裏面的錢是不會動的,這就是一致性;分佈式
可用性(Availability):非故障的節點在合理的時間內返回合理的響應(不是錯誤和超時的響應),這個我感受不須要舉例子吧,就是系統的每一個功能都能正常的返回結果;ide
分區容錯性(Partition Tolerance):當發生網絡分區後,系統依然可以發揮原來的做用,舉個例子就是當ES某個節點掛掉的時候咱們依然能夠正常使用,這個例子可能不是恰當,可是能說明分區容錯性的重要性,後面咱們再來討論下ES的CAP設計,這仍是一件蠻有意思的事情;ui
在瞭解這3者之間的關係時候,咱們就來思考下爲何只能三選二?在分佈式系統中,必需要多臺機器部署才能叫作分佈式,多臺機器相互聯繫的時候可能會發生網絡或者其餘一些故障,咱們在設計的時候必須考慮到P,這個時候咱們就該考慮C和A爲何不能共存,這兩者本就是矛和盾的存在,當發生分區故障的時候,爲了保證C,系統必須禁止寫入,當有寫入的請求的時候,系統就會返回錯誤,這個時候就和A衝突掉了,A要求的是不能是錯誤和超時響應,因此這就分佈式系統理論上不可以選着CA,只可以選擇CP和AP;翻譯
3、分析一波
前幾篇博客一直都是在分析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,畢竟有些特殊狀況嘛。
4、結束
立刻就要年關了,該寫篇總結了,給本身指定的不少指標仍是沒有完成,還須要多努力,歡迎你們加羣438836709,歡迎你們關注我!