分布式的系統有很多種,通常情況下,我們的業務系統有數據存儲分布式的,也有應用程序分布式的,不同的場景會應用到不同的分布式解決方案。
你這個問題提到了訪問到舊數據,感覺像是數據庫讀寫分離或者是主從機的場景。通常我們對于數據庫主從設計,都是設置一臺主庫數據庫服務器,一臺或多臺庫數據庫服務器,通過數據庫日志訂閱的模式進行數據同步。我們的系統也是寫操作在主庫進行,讀操作在從庫進行。
而這種方式中,主庫和從庫之間的數據同步會需要一定的時間,所以很大概率會出現寫入主庫的數據還沒有同步到從庫,用戶就去讀數據了,往往讀出來的就是舊數據。
其實解決方案也有不少,主要看我們的場景是什么,然后考慮如何應用。
最簡單的就是半同步復制(semi-sync)
這種實現方式非常簡單,我們的數據庫同步就自帶了此功能。當我們的寫請求到主庫以后,主庫先自己把數據保存好,但是并不返回,而是等待從庫同步,從庫同步完成后,主庫再告訴我們的應用程序數據保存成功。
使用這種方式的話,我們不需要修改任何的代碼,數據庫原本就帶有這樣的功能,配置也非常方便。但是不好的就是,我們的寫請求時間會變長,鎖表的時間也會增加,這會導致數據執行效率下降、吞吐量也就降低了。
如果我們對效率比較看重,那么可以使用這種方式——緩存
緩存是一個好東西,在我們的各個業務場景都大量的使用。而緩存也可以用來保證讀寫分離以后的數據一致性。
方法其實也比較簡單,就是我們在數據Commit成功以后,讓緩存里面寫入一條數據,我們的讀并不直接作用到從庫,而是作用到緩存上,這樣就能夠保證用戶每次讀取出來的數據都是最新的了。
不過,這里有一個問題,就是如果我們在一個事務里面進行了寫操作,事務提交之前去讀這個數據的話,如果去讀緩存,就會讀到舊的數據,可能導致我們的業務失敗。所以,我們這里需要做一個處理,如果在事務里面讀的話,我們需要讀寫庫。只有沒有事務的讀,才會讀緩存,這樣就可以防止這種情況了。
當然,關于數據庫緩存的一致性保證,其實是一個比較復雜的場景,還有很多的問題在里面,也有很多的解決方案。不管如何,使用這種方式的話,首先是需要增加設備成本——緩存服務器,其次就是代碼需要進行改動,業務邏輯復雜度也會提高。