mysql和redis 資料同步解決方案總結
現在在中集e棧工作,最近在做乙個redis箱格資訊資料同步到資料庫mysql的功能。
自己想了想,也有大概方案。
1、佇列同步,變跟資料2份,使用訊息佇列,乙份給redis消費,乙份給mysql消費。
2、後台定時任務,定時重新整理redis中箱格資訊到資料庫。
網上也到處找了下解決方案,發現這麼個問題,居然是天下一大抄,還抄的一字不差,我也抄吧。
方案一:
讀: 讀redis->沒有,讀mysql->把mysql資料寫回redis
寫: 寫mysql->成功,寫redis。
就是讀的話,先讀redis,redis沒有再讀資料庫,將資料庫中的資料放入redis。
寫(增刪改),先寫資料庫,然後寫redis。
可以對此稍微優化,比如要求一致性高的資料,從資料庫讀,比如金融,交易資料。不要求強一致性的從reids中讀取。
方案二:
基於binlog使用mysql_udf_redis,將資料庫中的資料同步到redis。
方案三:
基於mq,也就是最上面想到的方式1。
方案四:
官方有個memcached的udf外掛程式,如果不是那麼強烈非要redis的話,也可以考慮
方案五:
用postgresql 替代 mysql +redis.
各種方案弊端
但是上面的方案都有各自的弊端。
方案一,明顯對於資料量巨大,更新頻繁的資料寫入無能為力。比如e棧終端的箱格,箱格數量巨大,每個箱格的變跟狀態又很頻繁,這樣很容易把資料庫寫掛。
方案二,是使用的mysql的user defined function功能,mysql_udf_redis是有人實現的同步資料到redis的功能,弊端:需要學習成本,而來,第三方的外掛程式不穩定。
方案三:怎麼保證到資料庫和到redis中的狀態一致性。就是假設一條修改資料,從佇列寫入到mysql成功,但是寫入到redis失敗,這種如何搞。還有就是需要乙個訊息佇列,使用第三方的比如kafka,rabbitmq等來實現,管理起來不方便,系統整體穩定性不行,而且只是這麼個比較小的箱格資料資訊同步。有點殺雞用牛刀。
其他的方案:
訂閱key的變化進行資料庫更新,寫的時候寫2份,乙份往redis寫,乙份是redis資料的key網更新佇列(也可以直接reids存)裡寫,再寫個定時程式從更新佇列裡取時間,根據key取出redis資料到mysql.
這個方案,其實和其他的不一樣,弊端了,就是占用記憶體大,因為需要維護乙份更新佇列。
最後了,我上級是說用定時任務,刷redis中的箱格狀態資訊到資料庫。2w個終端,乙個終端100個箱格,200w個箱格,首先是進行狀態比對,狀態不一致的放入集合,批量update資料庫。
其實也會有寫小問題,比如在比對的時候:
1、redis中的箱格狀態變跟了,怎麼辦?我們不可能在比對的時候鎖住redis,200w次迴圈,這段時間完全可能發生狀態變跟。
2、在比對的時候,有人更新了資料庫,怎麼辦?因為有些操作是可以直接更新資料庫的。比如更新箱格的layoutrow之類的資訊。
redis與mysql資料同步
應用redis實現資料的讀寫,同時利用佇列處理器定時將資料寫入mysql,此種情況存在的問題主要是如何保證mysql與redis的資料同步,二者資料同步的關鍵在於mysql資料庫中主鍵,方案是在redis啟動時去mysql讀取所有表鍵值存入redis中,往redis寫資料時,對redis主鍵自增並進...
redis與mysql資料同步
應用redis實現資料的讀寫,同時利用佇列處理器定時將資料寫入mysql,此種情況存在的問題主要是如何保證mysql與redis的資料同步,二者資料同步的關鍵在於mysql資料庫中主鍵,方案是在redis啟動時去mysql讀取所有表鍵值存入redis中,往redis寫資料時,對redis主鍵自增並進...
redis快取和mysql資料庫同步
穿透 頻繁查詢乙個不存在的資料,由於快取不命中,每次都要查詢持久層。從而失去快取的意義。解決辦法 持久層查詢不到就快取空結果,查詢時先判斷快取中是否exists key 如果有直接返回空,沒有則查詢後返回,注意insert時需清除查詢的key,否則即便db中有值也查詢不到 當然也可以設定空快取的過期...