1. 程式人生 > >一次redis資料遷移實施方案

一次redis資料遷移實施方案

背景

       最近上線了一個專案,項目中使用到了redis為服務提供資料快取和資料儲存。剛開始業務還能正常執行,單機redis基本可以滿足服務的效能要求。由於業務增長加快,隨著服務的QPS流量越來越大,引起redis的QPS也急劇上升。這是由於服務中有3個介面的QPS流量迅猛上升,而且每個介面中都多次訪問redis,因此出現redis的訪問QPS越來越大,達到了將近7W/s的量,引起公司監控系統多次告警。

解決方案1

      問題出現後,面對近乎瘋狂的QPS增長,最直接想到的解決方案是想辦法削弱3個介面的單次呼叫的redis操作次數,減少不必要的redis get操作,從業務邏輯方面壓縮單次呼叫服務的redis操作次數。採用這種思路也是基於小步優化的考慮,而且改動較小,能夠快速上線,不影響線上服務正常執行,實際的工程效果也顯示上線之後redis的QPS流量增幅得到小幅度遏制,為後面實施redis的從單機到叢集遷移置換了許多寶貴的時間。

解決方案2

       解決方案1輕便易施行,但缺點是治標不治本,短期內redis的QPS稍微壓了下來,業務如果繼續迅速增長,必然會吃掉方案1優化出來的餘量,後來服務執行也正是如此。從服務的高可用性來說,也應該避免單機裸奔在情況不定的線上環境,因此使用redis叢集代替單機redis勢在必行,redis叢集方案既能支撐更高的業務量,也能保證服務的高可用。那麼問題出現了,我的服務已經上線了,難道為了從單機redis切換到redis叢集,要停掉線上服務,造成服務停用,給我們的使用者造成不便嗎,如果這樣的話那就沒必要寫本篇部落格了,畢竟,還是要記錄點有價值的東西嘛。

      問題的難點在於如何保證線上功能

的平穩執行,不影響線上業務。總結我的解決方案就是一句話:單點到叢集的複製 + 單點&叢集雙寫。

redis中儲存的資料有快取,也有部分是儲存的資料。快取的資料可以丟失,不管。要解決的是redis被當作儲存使用的那部分資料。方案分兩步走,分別是複製和雙寫。redis集群系統使用公司內部的redis叢集中介軟體訪問,為配合本次遷移,針對兩個步驟,分別設定三個開關:

xxx.msgBox.redis.write--雙寫開關,開關為true,redis get/set操作同時寫入單點和叢集redis系統,保持雙寫過程;開關為false,redis get/set操作只向叢集redis系統寫入,單點redis不在更新資料。


 xxx.msgBox.redis.query--服務redis查詢選擇開關。開關值為0,表示服務從單點redis系統查詢資料,此時redis流量均在單點redis上,開關值為100,表示服務從redis集群系統查詢資料,此時redis流量均在叢集redis系統上。開關值為n(0<n<100),表示當前百分n的QPS流量在叢集redis系統上,(100-n)百分比的QPS流量在單點redis系統上。

xxx.msgBox.redis.sync--單點redis向叢集redis系統複製開關。開關值為true,開啟單點redis複製資料到叢集redis系統,開關值為false,關閉單點redis複製資料到集群系統。

操作步驟:

1、開啟redis的雙寫開關,置xxx.msgBox.redis.write=true,單點redis和叢集redis系統同時接受服務的寫操作,並保持雙寫。雙寫的過程中,單點redis資料正常提供讀寫服務,就像沒有叢集redis系統一樣,叢集redis系統此時會不斷地有新的redis key寫入,並更新已經存在的部分key,但叢集redis系統的資料基本是錯誤的,因為叢集redis系統沒有服務的之前資料,redis叢集資料庫中普遍是髒資料。

2、開啟redis的單點到叢集的複製開關,置xxx.msgBox.redis.sync=true,實現單點redis中的老資料同步複製到叢集redis系統,經過步驟1和2的操作,叢集redis系統的資料已經和單點redis系統資料保持一致。從而使資料準確無誤滴遷移到了新的集群系統。

     僅就資料遷移而言,資料已經遷移完畢,為了實現服務由單redis向叢集redis系統的過渡,另外設定了灰度控制開關( xxx.msgBox.redis.query),實現Redis QPS流量逐漸地由單點向叢集過渡,多次調大灰度開關值,使得redis集群系統逐漸承擔起redis流量的主體,也避免了新部署的集群系統不可用或者我們的遷移出現失誤導致的服務不可用現象,大約經過一週的灰度調控,服務上的redis操作已經完全使用叢集redis系統承擔了。同時,資料遷移完成之後,保持一段時間的新舊redis雙寫,也是出於安全穩定性考慮。

     至此,本次redis的資料遷移才算完成。