快取,併發更新的大坑?
《快取,究竟是淘汰,還是修改?》發出後,有朋友提到,高併發的情況下,快取的更新可能存在問題,今天簡單聊聊這個話題。
業務場景:
(1)呼叫第三方服務,例如微信,一般會分配一個token,每次訪問介面需要帶上這個token;
(2)這個token是有有效期的,當token過期時,需要去重新認證申請;
(3)也可以在token過期前重新申請,但此時舊token會失效。
常見實現方式,如圖:
(1)把token放在快取中,每次帶上token去呼叫介面;
(2)如果token過期,需要去申請新token;
(3)申請完新token,需要把新token更新到快取裡。
高併發下可能存在的問題,如圖:
(1)取舊token,訪問介面,發現token過期;
(2)併發請求,取舊token,訪問介面,也發現token過期;
(3)去申請新token1;
(3)併發申請新token2(此時token1會過期);
(4)把token1放入快取,同時使用token1訪問介面(此時token1已經過期),發現token1過期,可能會遞迴申請新token3(此時token2過期);
(5)把token2放入快取,同時使用token2訪問介面(此時token2已經過期),發現token2過期,可能會遞迴申請新token4(此時token3過期);
…
額,高併發請求導致相互失效。
常見解決方案,如圖:
線上s1和s2只從快取讀取token
更新token非同步,asy-Master定期更新token,避免併發更新
使用shadow-master保證token更新高可用,asy-Master掛了,asy-Backup頂上
潛在缺點:s1/s2/asy-master直接呼叫同一個快取例項,如果快取例項變更,可能需要同步變更,導致耦合。
潛在優化:
(1)asy-Master利用多執行緒,實現在s1/s2裡,保證高可用;
(2)redis裡用一個時間戳表示token的更新時間,更新token時,檢視token的時間戳,如果token剛更新過,併發的請求便不再更新。
文字雖短,希望問題描述清楚了,希望大家有收穫。
歡迎大家分享更多的方案。
相關推薦: