Ⅰ 後台服務異常具體怎麼操作
?1、在桌面選中「我的電腦」,滑鼠右鍵選擇「管理」;??????2、在「管理」窗口中,選取「服務和應用程序」擴展項目下的「服務」選項(如圖),在右側出現系統服務列表中找到「PrintSpooler」服務,雙擊進入「PrintSpooler」服務設置;????3、在「PrintSpooler」服務設置窗口中,將「啟動類型」設置為「自動」,點擊「啟動」按鈕;此時系統會嘗試啟動該服務;當服務啟動成功後,「服務狀態」會顯示為「已啟動」,重新進行添加或是使用列印機的其它操作。????另外,如果按上述步驟執行後仍無法啟動該「列印後台程序服務」,或執行列印機操作時報錯依舊,多是與操作系統重要的文件存在問題相關,嘗試對電腦查毒後再試;仍有問題,建議備份重要文件後,重新安裝操作系統。??-----------------------------------------------------------------大家知道,利用後台列印功能可以確保Windows系統快速將操作控制許可權交還給列印操作者,從而確保列印用戶始終高效地操作計算機。不過,要是對後台列印功能管理不當的話,有時不但不會提高系統的運行效率,反而會影響列印機的輸出速度。為了有效提高列印效率,我們必須對系統的後台列印功能進行合適管理;這不,本文下面就以Windows2003操作系統為例,來向各位詳細介紹幾則後台列印的管理技巧!????巧移位置,高效應對大批量作業????後台列印功能在默認狀態下,會自動將接受到的列印作業,按照列印作業執行時間的先後順序,依次緩存到Windows2003系統中的「%systemroot%\system32\spool\printers」目錄中,之後後台列印功能會自動對當前列印機的工作狀態進行監視,以決定到底何時執行某個特定的列印作業。但由於「%systemroot%\system32\spool\printers」目錄同時包含了Windows2003的其他系統文件,而在進行大批量列印操作時,系統會頻繁地訪問這些系統文件,這將導致列印速度以及其他系統性能的嚴重下降。另外,在進行大批量列印操作時,可能會有不少大容量的列印作業保存在硬碟的「%systemroot%\system32\spool\printers」目錄中,如此一來就容易耗用掉寶貴的硬碟資源,從而影響整個計算機的運行性能。有鑒於此,我們必須將後台列印的緩存位置巧妙轉移到與操作系統無關的磁碟分區中,以盡可能地降低後台列印功能對系統整體性能的影響,確保列印機能夠高效、快速地應對大批量作業。在轉移後台列印功能的緩存位置時,可以按下面的方法來操作:????首先單擊「開始」菜單中的「設置」選項,從彈出的下級菜單中單擊「列印機和傳真機」選項,打開列印機的列表窗口,用滑鼠選中該窗口中的目標列印機;????接著單擊該窗口菜單欄中的「文件」選項,並執行下拉菜單中的「伺服器屬性」命令,打開列印機伺服器屬性界面,單擊該界面中的「高級」選項卡,進入到如圖1所示的高級選項設置界面;????在該界面的「後台列印文件夾」文本框中,你將看到系統默認的後台列印文件夾保存路徑為「%systemroot%\system32\spool\printers」,要想更換它的保存路徑時,只要在該文本框中直接輸入新的路徑就可以了;例如,要想把後台列印的緩存位置轉移到「F:\qqq」文件夾中時,只要輸入「F:\qqq」並重新將計算機系統啟動一下就可以了。????不過上面的方法會改變所有列印機後台列印緩存位置,要是在當前計算機系統中安裝了多台列印機時,我們有沒有法僅僅只轉移指定列印機的後台列印緩存位置呢?答案是肯定的,不過這需要通過修改系統的注冊表才能實現,這對不熟悉注冊表操作的「菜鳥」朋友來說有點難度。但是「菜鳥」朋友們只要依次按照如下步驟,還是可以輕松完成後台列印緩存位置的轉移任務的:????依次單擊「開始」/「運行」命令,在彈出的「打開」文本框中直接輸入字元串命令「regedit」,單擊回車鍵後打開系統的注冊表編輯界面;????在該界面的左側窗格中,用滑鼠逐一HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers\HPLaserJet4VC注冊表子鍵(其中HPLaserJet4VC為安裝在筆者計算機中的指定列印機名稱,用戶自己的列印機名稱可以在列印機列表窗口中清楚地查看到),如圖2所示;??在指定列印機名稱的右側窗格區域中,檢查一下是否存在一個名為「SpoolDirectory」的字元串值,要是找不到的話,可以依次單擊注冊表編輯窗口中的「編輯」/「新建」/「字元串值」命令,並將新創建的字元串值名稱設置為「SpoolDirectory」;之後再用滑鼠雙擊該字元串值,在隨後出現的「數值數據」設置框中,可以直接輸入指定列印機的新緩存路徑,最後單擊「確定」按鈕並刷新一下系統注冊表就可以使上述設置生效了。????設置服務,巧妙解決後台列印故障??????有時在計算機系統中添加新的列印機時,我們常會發現系統提示無法運行列印機後台程序的錯誤,很顯然這種列印故障與後台列印功能有關。那麼列印機為什麼會出現這種故障,我們又該如何解決該故障呢?????後台列印程序無法運行,通常有兩種可能,一種可能是列印機的驅動程序由於受到病毒的攻擊或者頻繁卸載軟體的干擾而導致某些驅動文件丟失,另外一種可能就是列印機的後台列印服務由於種種因素導致意外停止,因此要解決這種後台列印故障就需要從兩個方面著手:????首先找來最新版本的殺毒軟體,將其安裝在出現後台列印故障的計算機中,然後通過網路將殺毒程序升級到最新版本,之後再對計算機系統進行徹底查殺,看看計算機中是否有病毒存在;????倘若上面的方法不能解決該後台列印故障的話,那多半是系統的後台列印服務因系統優化或設置不當被意外停止了,此時我們可以按下面的操作來將它重新啟動起來:????依次單擊「開始」/「控制面板」命令,打開系統的控制面板窗口,雙擊該窗口中的「管理工具」圖標,再在其後彈出的界面中雙擊「服務」圖標,在之後出現的服務列表窗口中,找到「printspooler」服務項目;??用滑鼠雙擊該服務項目,打開如圖3所示的服務屬性界面,在該界面中我們可以清楚地看到後台列印服務的當前工作狀態;要是發現該服務已經被停止的話,只要單擊一下該界面中的「啟動」按鈕,然後將它的啟動類型設置為「自動」,最後單擊「確定」按鈕就可以了。????適時屏蔽,分步排除無法進紙故障??????列印機無法進紙的故障是十分常見的一種故障,除了列印機自身的進紙系統與列印用戶自身的不當操作會造成該故障外,列印機的參數設置出錯也能引發無法進紙故障,例如要是事先啟用了列印機的後台列印功能時,即使操作者已經向列印機發出了列印命令,列印機也不會立即執行進紙操作,這在外人看來還以為是無法進紙故障呢!因此當我們不幸遇到列印機無法進紙故障時,除了要對列印機走紙系統以及放紙操作進行檢查外,還需要對後台列印功能進行適時屏蔽一下:????首先單擊「開始」菜單中的「設置」選項,從彈出的下級菜單中單擊「列印機和傳真機」選項,打開列印機的列表窗口,用滑鼠選中該窗口中的目標列印機圖標,並用滑鼠右鍵單擊之;????從彈出的右鍵菜單中單擊「屬性」命令,在彈出的列印機屬性設置框中單擊「高級」標簽,然後在對應的標簽頁面中,看看列印機是否將後台列印功能啟用了,要是發現已經啟用的話,不妨取消「使用後台列印……」選項,同時將「直接列印到列印機」選項選中,如圖4所示,並單擊「確定」按鈕,再看看是否能排除無法進紙故障;??要是無法消除該故障的話,我們再單擊圖4標簽頁面中的「列印機默認值」按鈕,在其後彈出的設置窗口中找到「送紙器選擇」設置項,檢查當前列印機的紙張來源是否是「手動送紙」,如果不是的話,不妨將它調整過來看看是否能排除無法進紙故障。??
Ⅱ 為什麼軟體無法運行,後台服務找不到應用
軟體無法運行,後台服務找不到應用原因如下:
1、內存不足引起
2、軟體緩存過多
3、軟體版本過低
4、恢復出廠設置
5、安裝位置不對
Ⅲ 華為榮耀10老自動清理後台應用和緩存,怎麼辦
華為手機有一個鎖屏清理應用的開關,關閉相關開關可以防止鎖屏後自動清理應用:
打開手機管家;
點擊鎖屏清理應用;
關閉相關應用的開關。
這樣操作鎖屏後,後台應用就不會被清理掉了。
Ⅳ 網站後台更新緩存出現Internal Server Error,且後台網站也進不去。
一般來說是不關你的事,主要是伺服器現在了問題,因為我們瀏覽網頁都是通過我們本地的計算機(也就是電腦)向伺服器(也就是網站程序運行的計算機)發出一個請求,然伺服器就會發出一個瀏覽器可以解析的文件數據給本地計算機的瀏覽器。
伺服器程序運行如果出現錯誤就是會出向請求方出一個顯示錯誤的信息,如果處理好,我們是看不到像你出現的那樣不友好的信息的。一般來說都是網站在設計時沒有處理好,或者其他原因(如:被人黑了、硬體等等)。
但也有另外一種可能,就是你的計算機或瀏覽器被木馬或病毒感染,那麼也有可能會出現這種情況,所以你也可以試一試你殺毒。
如果是網站的問題,建議你不要到這樣的網站去購物了,安全性不好。
Ⅳ 注冊賬號顯示緩存數據失效
有可能對方更換了伺服器。緩存表面看是地址,地址沒有變出現了失效、地址不存在。其實緩存的包含了伺服器地址等代碼,只是你看不到。一旦後台動了賬號的伺服器,其伺服器地址就變了。地址雖然沒有變,但緩存的地址會出現無效的情況。
Ⅵ PHP網站發布文章不能生成html了,後台【更新緩存】功能失效,怎麼辦急!
如果一開始就不能生成,有可能網站目錄的許可權不可寫;如果一直都能生成,突然不能了,則回想一下此前是否改過模板,可能改出毛病了,退回模板修改之前,也許就解決了。
Ⅶ 如何禁止安卓後台緩存
不建議清理。。這是安卓系統的設計
這種設計本來就是一個非常好的設計,下次啟動程序時,會更快,因為不需要讀取界面資源。 Android系統這樣的設計不僅非常適合移動終端的需要,而且減少了系統崩潰的可能,確保了系統的穩定性。
有的兄弟說後台掛著程序很費電,事實上Android的應用在被切換到後台時,它其實已經被暫停了,並不會消耗cpu資源,只保留了運行狀態。 至於QQ、音樂播放之類的程序可以在後台運行,是因為這些程序在後台開啟了服務,而服務可以後台運行,所以沒有帶服務的應用在後台是完全不耗電的,沒有必要關閉。
老想著清理內存的同學完全是因為被塞班或者Windows毒害太深,事實上,經常用Taskiller之類的軟體關閉後台所有進程,很容易造成系統的不穩定。很多時候出現問題,只要重啟就能解決,其原因也在於此。 說了這么多,總結起來很簡單,牛B的人自己去操縱系統內存分配的閾值,而普通用戶則是想怎麼用就怎麼用,完全不用去鳥剩餘內存的問題,那些內存清理的程序完全可以扔到一邊了。
Ⅷ 請教下後台更新DIY緩存無效的問題
d sd d w d無奈的就能玩寄到你家煩不煩如假包換煩人不好吧好吧
Ⅸ 我在網站的後台點擊了下更新緩存,我在進入後台就進不進去了,提示「錯誤」,訪問網站也訪問不了了,
這應該是您的Web伺服器的配置問題
往往是不公開的伺服器錯誤重寫功能
Ⅹ 如何保證資料庫緩存的最終一致性
對於互聯網業務來說,傳統的直接訪問資料庫方式,主要通過數據分片、一主多從等方式來扛住讀寫流量,但隨著數據量的積累和流量的激增,僅依賴資料庫來承接所有流量,不僅成本高、效率低、而且還伴隨著穩定性降低的風險。
鑒於大部分業務通常是讀多寫少(讀取頻率遠遠高於更新頻率),甚至存在讀操作數量高出寫操作多個數量級的情況。因此, 在架構設計中,常採用增加緩存層來提高系統的響應能力 ,提升數據讀寫性能、減少資料庫訪問壓力,從而提升業務的穩定性和訪問體驗。
根據 CAP 原理,分布式系統在可用性、一致性和分區容錯性上無法兼得,通常由於分區容錯無法避免,所以一致性和可用性難以同時成立。對於緩存系統來說, 如何保證其數據一致性是一個在應用緩存的同時不得不解決的問題 。
需要明確的是,緩存系統的數據一致性通常包括持久化層和緩存層的一致性、以及多級緩存之間的一致性,這里我們僅討論前者。持久化層和緩存層的一致性問題也通常被稱為雙寫一致性問題,「雙寫」意為數據既在資料庫中保存一份,也在緩存中保存一份。
對於一致性來說,包含強一致性和弱一致性 ,強一致性保證寫入後立即可以讀取,弱一致性則不保證立即可以讀取寫入後的值,而是盡可能的保證在經過一定時間後可以讀取到,在弱一致性中應用最為廣泛的模型則是最終一致性模型,即保證在一定時間之後寫入和讀取達到一致的狀態。對於應用緩存的大部分場景來說,追求的則是最終一致性,少部分對數據一致性要求極高的場景則會追求強一致性。
為了達到最終一致性,針對不同的場景,業界逐步形成了下面這幾種應用緩存的策略。
— 1 —
Cache-Aside
Cache-Aside 意為旁路緩存模式,是應用最為廣泛的一種緩存策略。下面的圖示展示了它的讀寫流程,來看看它是如何保證最終一致性的。在讀請求中,首先請求緩存,若緩存命中(cache hit),則直接返回緩存中的數據;若緩存未命中(cache miss),則查詢資料庫並將查詢結果更新至緩存,然後返回查詢出的數據(demand-filled look-aside )。在寫請求中,先更新資料庫,再刪除緩存(write-invalidate)。
1、為什麼刪除緩存,而不是更新緩存?
在 Cache-Aside 中,對於讀請求的處理比較容易理解,但在寫請求中,可能會有讀者提出疑問,為什麼要刪除緩存,而不是更新緩存?站在符合直覺的角度來看,更新緩存是一個容易被理解的方案,但站在性能和安全的角度,更新緩存則可能會導致一些不好的後果。
首先是性能 ,當該緩存對應的結果需要消耗大量的計算過程才能得到時,比如需要訪問多張資料庫表並聯合計算,那麼在寫操作中更新緩存的動作將會是一筆不小的開銷。同時,當寫操作較多時,可能也會存在剛更新的緩存還沒有被讀取到,又再次被更新的情況(這常被稱為緩存擾動),顯然,這樣的更新是白白消耗機器性能的,會導致緩存利用率不高。
而等到讀請求未命中緩存時再去更新,也符合懶載入的思路,需要時再進行計算。刪除緩存的操作不僅是冪等的,可以在發生異常時重試,而且寫-刪除和讀-更新在語義上更加對稱。
其次是安全 ,在並發場景下,在寫請求中更新緩存可能會引發數據的不一致問題。參考下面的圖示,若存在兩個來自不同線程的寫請求,首先來自線程 1 的寫請求更新了資料庫(step 1),接著來自線程 2 的寫請求再次更新了資料庫(step 3),但由於網路延遲等原因,線程 1 可能會晚於線程 2 更新緩存(step 4 晚於 step 3),那麼這樣便會導致最終寫入資料庫的結果是來自線程 2 的新值,寫入緩存的結果是來自線程 1 的舊值,即緩存落後於資料庫,此時再有讀請求命中緩存(step 5),讀取到的便是舊值。
2、為什麼先更新資料庫,而不是先刪除緩存?
另外,有讀者也會對更新資料庫和刪除緩存的時序產生疑問,那麼為什麼不先刪除緩存,再更新資料庫呢?在單線程下,這種方案看似具有一定合理性,這種合理性體現在刪除緩存成功。
但更新資料庫失敗的場景下,盡管緩存被刪除了,下次讀操作時,仍能將正確的數據寫回緩存,相對於 Cache-Aside 中更新資料庫成功,刪除緩存失敗的場景來說,先刪除緩存的方案似乎更合理一些。那麼,先刪除緩存有什麼問題呢?
問題仍然出現在並發場景下,首先來自線程 1 的寫請求刪除了緩存(step 1),接著來自線程 2 的讀請求由於緩存的刪除導致緩存未命中,根據 Cache-Aside 模式,線程 2 繼而查詢資料庫(step 2),但由於寫請求通常慢於讀請求,線程 1 更新資料庫的操作可能會晚於線程 2 查詢資料庫後更新緩存的操作(step 4 晚於 step 3),那麼這樣便會導致最終寫入緩存的結果是來自線程 2 中查詢到的舊值,而寫入資料庫的結果是來自線程 1 的新值,即緩存落後於資料庫,此時再有讀請求命中緩存( step 5 ),讀取到的便是舊值。
另外,先刪除緩存,由於緩存中數據缺失,加劇資料庫的請求壓力,可能會增大緩存穿透出現的概率。
3、如果選擇先刪除緩存,再更新資料庫,那如何解決一致性問題呢?
為了避免「先刪除緩存,再更新資料庫」這一方案在讀寫並發時可能帶來的緩存臟數據,業界又提出了延時雙刪的策略,即在更新資料庫之後,延遲一段時間再次刪除緩存,為了保證第二次刪除緩存的時間點在讀請求更新緩存之後,這個延遲時間的經驗值通常應稍大於業務中讀請求的耗時。
延遲的實現可以在代碼中 sleep 或採用延遲隊列。顯而易見的是,無論這個值如何預估,都很難和讀請求的完成時間點准確銜接,這也是延時雙刪被詬病的主要原因。
4、那麼 Cache-Aside 存在數據不一致的可能嗎?
在 Cache-Aside 中,也存在數據不一致的可能性。在下面的讀寫並發場景下,首先來自線程 1 的讀請求在未命中緩存的情況下查詢資料庫(step 1),接著來自線程 2 的寫請求更新資料庫(step 2),但由於一些極端原因,線程 1 中讀請求的更新緩存操作晚於線程 2 中寫請求的刪除緩存的操作(step 4 晚於 step 3),那麼這樣便會導致最終寫入緩存中的是來自線程 1 的舊值,而寫入資料庫中的是來自線程 2 的新值,即緩存落後於資料庫,此時再有讀請求命中緩存(step 5),讀取到的便是舊值。
這種場景的出現,不僅需要緩存失效且讀寫並發執行,而且還需要讀請求查詢資料庫的執行早於寫請求更新資料庫,同時讀請求的執行完成晚於寫請求。足以見得,這種 不一致場景產生的條件非常嚴格,在實際的生產中出現的可能性較小 。
除此之外,在並發環境下,Cache-Aside 中也存在讀請求命中緩存的時間點在寫請求更新資料庫之後,刪除緩存之前,這樣也會導致讀請求查詢到的緩存落後於資料庫的情況。
雖然在下一次讀請求中,緩存會被更新,但如果業務層面對這種情況的容忍度較低,那麼可以採用加鎖在寫請求中保證「更新資料庫&刪除緩存」的串列執行為原子性操作(同理也可對讀請求中緩存的更新加鎖)。 加鎖勢必會導致吞吐量的下降,故採取加鎖的方案應該對性能的損耗有所預期。
— 2 —
補償機制
我們在上面提到了,在 Cache-Aside 中可能存在更新資料庫成功,但刪除緩存失敗的場景,如果發生這種情況,那麼便會導致緩存中的數據落後於資料庫,產生數據的不一致的問題。
其實,不僅 Cache-Aside 存在這樣的問題,在延時雙刪等策略中也存在這樣的問題。針對可能出現的刪除失敗問題,目前業界主要有以下幾種補償機制。
1、刪除重試機制
由於同步重試刪除在性能上會影響吞吐量,所以常通過引入消息隊列,將刪除失敗的緩存對應的 key 放入消息隊列中,在對應的消費者中獲取刪除失敗的 key ,非同步重試刪除。這種方法在實現上相對簡單,但由於刪除失敗後的邏輯需要基於業務代碼的 trigger 來觸發 ,對業務代碼具有一定入侵性。
鑒於上述方案對業務代碼具有一定入侵性,所以需要一種更加優雅的解決方案,讓緩存刪除失敗的補償機制運行在背後,盡量少的耦合於業務代碼。一個簡單的思路是通過後台任務使用更新時間戳或者版本作為對比獲取資料庫的增量數據更新至緩存中,這種方式在小規模數據的場景可以起到一定作用,但其擴展性、穩定性都有所欠缺。
一個相對成熟的方案是基於 MySQL 資料庫增量日誌進行解析和消費,這里較為流行的是阿里巴巴開源的作為 MySQL binlog 增量獲取和解析的組件 canal(類似的開源組件還有 Maxwell、Databus 等)。
canal sever 模擬 MySQL slave 的交互協議,偽裝為 MySQL slave,向 MySQL master 發送 mp 協議,MySQL master 收到 mp 請求,開始推送 binary log 給 slave (即 canal sever ),canal sever 解析 binary log 對象(原始為 byte 流),可由 canal client 拉取進行消費,同時 canal server 也默認支持將變更記錄投遞到 MQ 系統中,主動推送給其他系統進行消費。
在 ack 機制的加持下,不管是推送還是拉取,都可以有效的保證數據按照預期被消費。當前版本的 canal 支持的 MQ 有 Kafka 或者 RocketMQ。另外, canal 依賴 ZooKeeper 作為分布式協調組件來實現 HA ,canal 的 HA 分為兩個部分:
那麼,針對緩存的刪除操作便可以在 canal client 或 consumer 中編寫相關業務代碼來完成。這樣,結合資料庫日誌增量解析消費的方案以及 Cache-Aside 模型,在讀請求中未命中緩存時更新緩存(通常這里會涉及到復雜的業務邏輯),在寫請求更新資料庫後刪除緩存,並基於日誌增量解析來補償資料庫更新時可能的緩存刪除失敗問題,在絕大多數場景下,可以有效的保證緩存的最終一致性。
另外需要注意的是,還應該隔離事務與緩存,確保資料庫入庫後再進行緩存的刪除操作。 比如考慮到資料庫的主從架構,主從同步及讀從寫主的場景下,可能會造成讀取到從庫的舊數據後便更新了緩存,導致緩存落後於資料庫的問題,這就要求對緩存的刪除應該確保在資料庫操作完成之後。所以,基於 binlog 增量日誌進行數據同步的方案,可以通過選擇解析從節點的 binlog,來避免主從同步下刪除緩存過早的問題。
3、數據傳輸服務 DTS
— 3 —
Read-Through
Read-Through 意為讀穿透模式,它的流程和 Cache-Aside 類似,不同點在於 Read-Through 中多了一個訪問控制層,讀請求只和該訪問控制層進行交互,而背後緩存命中與否的邏輯則由訪問控制層與數據源進行交互,業務層的實現會更加簡潔,並且對於緩存層及持久化層交互的封裝程度更高,更易於移植。
— 4 —
Write-Through
Write-Through 意為直寫模式,對於 Write-Through 直寫模式來說,它也增加了訪問控制層來提供更高程度的封裝。不同於 Cache-Aside 的是,Write-Through 直寫模式在寫請求更新資料庫之後,並不會刪除緩存,而是更新緩存。
這種方式的 優勢在於讀請求過程簡單 ,不需要查詢資料庫更新緩存等操作。但其劣勢也非常明顯,除了上面我們提到的更新資料庫再更新緩存的弊端之外,這種方案還會造成更新效率低,並且兩個寫操作任何一次寫失敗都會造成數據不一致。
如果要使用這種方案, 最好可以將這兩個操作作為事務處理,可以同時失敗或者同時成功,支持回滾,並且防止並發環境下的不一致 。另外,為了防止緩存擾動的頻發,也可以給緩存增加 TTL 來緩解。
站在可行性的角度,不管是 Write-Through 模式還是 Cache-Aside 模式,理想狀況下都可以通過分布式事務保證緩存層數據與持久化層數據的一致性,但在實際項目中,大多都對一致性的要求存在一些寬容度,所以在方案上往往有所折衷。
Write-Through 直寫模式適合寫操作較多,並且對一致性要求較高的場景,在應用 Write-Through 模式時,也需要通過一定的補償機制來解決它的問題。首先,在並發環境下,我們前面提到了先更新資料庫,再更新緩存會導致緩存和資料庫的不一致,那麼先更新緩存,再更新資料庫呢?
這樣的操作時序仍然會導致下面這樣線程 1 先更新緩存,最後更新資料庫的情況,即由於線程 1 和 線程 2 的執行不確定性導致資料庫和緩存的不一致。這種由於線程競爭導致的緩存不一致,可以通過分布式鎖解決,保證對緩存和資料庫的操作僅能由同一個線程完成。對於沒有拿到鎖的線程,一是通過鎖的 timeout 時間進行控制,二是將請求暫存在消息隊列中順序消費。
在下面這種並發執行場景下,來自線程 1 的寫請求更新了資料庫,接著來自線程 2 的讀請求命中緩存,接著線程 1 才更新緩存,這樣便會導致線程 2 讀取到的緩存落後於資料庫。同理,先更新緩存後更新資料庫在寫請求和讀請求並發時,也會出現類似的問題。面對這種場景,我們也可以加鎖解決。
另在,在 Write-Through 模式下,不管是先更新緩存還是先更新資料庫,都存在更新緩存或者更新資料庫失敗的情況,上面提到的重試機制和補償機制在這里也是奏效的。
— 5 —
Write-Behind
Write behind 意為非同步回寫模式,它也具有類似 Read-Through/Write-Through 的訪問控制層,不同的是,Write behind 在處理寫請求時,只更新緩存而不更新資料庫,對於資料庫的更新,則是通過批量非同步更新的方式進行的,批量寫入的時間點可以選在資料庫負載較低的時間進行。
在 Write-Behind 模式下,寫請求延遲較低,減輕了資料庫的壓力,具有較好的吞吐性。但資料庫和緩存的一致性較弱,比如當更新的數據還未被寫入資料庫時,直接從資料庫中查詢數據是落後於緩存的。同時,緩存的負載較大,如果緩存宕機會導致數據丟失,所以需要做好緩存的高可用。顯然,Write behind 模式下適合大量寫操作的場景,常用於電商秒殺場景中庫存的扣減。
— 6 —
Write-Around
如果一些非核心業務,對一致性的要求較弱,可以選擇在 cache aside 讀模式下增加一個緩存過期時間,在寫請求中僅僅更新資料庫,不做任何刪除或更新緩存的操作,這樣,緩存僅能通過過期時間失效。這種方案實現簡單,但緩存中的數據和資料庫數據一致性較差,往往會造成用戶的體驗較差,應慎重選擇。
— 7 —
總結
在解決緩存一致性的過程中,有多種途徑可以保證緩存的最終一致性,應該根據場景來設計合適的方案,讀多寫少的場景下,可以選擇採用「Cache-Aside 結合消費資料庫日誌做補償」的方案,寫多的場景下,可以選擇採用「Write-Through 結合分布式鎖」的方案 ,寫多的極端場景下,可以選擇採用「Write-Behind」的方案。