今天忽然想到一个问题
对于高并发条件下,后台对数据的更新和实例化是怎么进行的?
1、直接插入数据库,然后更新缓存?
这样这个更新操作将会有IO阻塞风险吧、
2、直接更新缓存,然后使用消息队列更新数据库?
只能延缓IO阻塞,并不能避免
3、直接更新缓存,定时批量更新数据库
这样IO的问题是解决了,但是数据在缓存里感觉很慌。
也没实践过真正的高并发系统,这种情况怎么解决?
----------补充----------
总结一下
就是已知直接插入和更新数据库将面临IO阻塞的风险,那么将数据最终实例化到数据库的过程是怎么样的。
中間池啊,cache啊,redis、反正就是這個意思;
如果池都阻塞了,還是+處理單元吧;這就像櫻桃小口小瘦子,吃一鍋飯,用多大碗都不行,那就找十個櫻桃小口小瘦子或找個嘴敞的大胖子;
更新:
寫操作時無法直接避免的,如果你總是考慮「極端情況」那麼就會忽略問題的重點。
先寫入緩存,然後再持久化到磁碟中,樓主是擔心快取伺服器掛了導致資料遺失?
一般生產環境下無論是應用伺服器、資料庫伺服器或快取伺服器,都不會是也不應該是單機的,至少都是主從的結構,一台掛了還有另一台頂著,在負載正常的情況下,單台掛的是幾率本身就不是很高,更何況是兩台同時掛了,而類似Redis可以做集群,所以如果部署正常的話,這個問題出現的可能性相當低。
樓主可以去了解一下
CAP
理论,根据你的描述你想要达到的效果和CAP
闡述的是差不多的,沒有絕對完美的方案。謝邀,但我對處理這個問題沒啥經驗,只能從理論上說說
首先,加上快取是必然的,快取的目錄就是將處理不過來的東西暫存起來,延長等待時間。例如突然10分鐘的高併發,引起需要處理的問題堆積,透過緩存,可以讓這10分鐘的內容在半小時處理完。當然這裡有一個假設,就是10分鐘高併發後的時間裡,沒有太多需要處理的問題流入。
那麼問題來了,如果後面的流入速度仍然很高,根本處理不過來怎麼辦?最近剛好學了一個詞,backpressure,背壓,最到背壓最直接的處理辦法是丟棄一部分內容。當然對於數據來說,你絕對不想丟棄,那就只能從處理效率上去想辦法,所以使用擴展、集群、分流等一大堆的並發處理技術
以上都是個人理解,用的口水話,不夠專業,僅供參考
這問題比較大,不同場景下的高並發也是有不同的方案的。
例如微博是高並發,金融系統也是高並發,前者就算發生資訊遺失也問題不大,後者則對資訊持久化有嚴格的要求。
還有你這個是高並發讀還是高並發寫?
是某時段高並發,還是持續性高併發?
沒有說明前提條件,讓人怎麼回答?
這個問題問的其實很好。
如果是對於讀取操作,應該是沒有問題的,因為對於目前大多的資料庫,資料大多是寫時才更新的(Copy on Write),因為現在的主流資料庫大多已經能很好的在資料庫層面的高並發支援並發讀了,關鍵是對於寫入操作,怎麼保證資料的一致性,在更新完資料的同時能保證快取也被更新,這有資料庫的ACID理論作為保證。
對於寫入操作,現在網路的資料庫的ACID特別是一致性,談的是資料的最終一致性,而不是傳統的一致性,這樣能保證使用者的請求可以很快被回應。這篇文章是CAP的介紹,http://blog.csdn.net/starxu85... 可供參考
你的這個問題其實對應的場景就是「雙十一」的秒殺,幾千個人或更多去搶拍一個商品,如果資料庫頻繁的寫,勢必導致鎖表、阻塞其他操作,所幸的是目前有些資料庫針對這種場景做了性能優化(比如新開源的基於MySQL做了針對秒殺優化的AliSQL),可以在資料庫的快取中對這些請求做訊息佇列,然後一次更新,保證了高並發。當然中間有其他的理論支撐,像是高低水位、線程池等。
以上是本人的一點拙見,本人也並非專業的DBA,如果有理論錯誤的話,也歡迎各位補充。
樓主的這個問題,普遍存在大部分的應用,並且這個和系統是否高並發關係不是很大,我以前也有思考過類似的問題
淺談緩存(二)
首先說一下緩存,我們的程序在絕大部分情況下,對快取其實應該是"弱依賴」的,怎麼去理解這個「弱依賴」呢?
我的理解是,我們的程式的資料的正確性在大部分情況下,都不會由快取中的資料來判斷,比如說"商品詳情頁商品的價格"其實就是快取中的資料,但是我們在產生訂單的時候的總價,必須要去資料庫裡面在查一遍.當然我說的是大部分情況,但是還有極少數情況下對數據正確性沒那麼嚴格(比如說抽象,安慰獎數量可以事先加載到緩存,後續業務需求可以直接通過緩存中的獎品數量來計算,因為根據一般業務,安慰獎都是一些對商家有利的附加比如說滿100減5元,這個時候就算緩存掛掉,重新刷一遍對商家影響也是很小)
那有沒有辦法,能保證資料庫和快取強一致性呢?在這個過程中就涉及到分散式事務,雙方實現X/Open XA協定,但是
redis
目前還為實現該協定,並且由於在整個分散式中需要長時間鎖定資源,所以這種方式並不推薦使用(最終一致性還會有可能出現一段時間內數據不一致,這樣會大大增加redis的複雜度)所以常用情況下,我們一般都是先保證資料庫資料正確的情況下,同步/失效/異步去更新快取