回覆列表
  • 1 # 會技術的葛大爺

    想要知道如何處理資料併發,自然需要先了解資料併發。

    什麼是資料併發操作呢?

    就是同一時間內,不同的執行緒同時對一條資料進行讀寫操作。

    在網際網路時代,一個系統常常有很多人在使用,因此就可能出現高併發的現象,也就是不同的使用者同時對一條資料進行操作,如果沒有有效的處理,自然就會出現資料的異常。而最常見的一種資料併發的場景就是電商中的秒殺,成千上萬個使用者對在極端的時間內,搶購一個商品。針對這種場景,商品的庫存就是一個需要控制的資料,而多個使用者對在同一時間對庫存進行重寫,一個不小心就可能出現超賣的情況。

    針對這種情況,我們如何有效的處理資料併發呢?

    第一種方案、資料庫鎖

    從鎖的基本屬性來說,可以分為兩種:一種是共享鎖(S),一種是排它鎖(X)。在MySQL的資料庫中,是有四種隔離級別的,會在讀寫的時候,自動的使用這兩種鎖,防止資料出現混亂。

    這四種隔離級別分別是:

    讀未提交(Read Uncommitted)讀提交(Read Committed)可重複讀(Repeated Read)序列化(Serializable)

    當然,不同的隔離級別,效率也是不同的,對於資料的一致性保證也就有不同的結果。而這些可能出現的又有哪些呢?

    髒讀(dirty read)

    當事務與事務之間沒有任何隔離的時候,就可能會出現髒讀。例如:商家想看看所有的訂單有哪些,這時,使用者A提交了一個訂單,但事務還沒提交,商家卻看到了這個訂單。而這時就會出現一種問題,當商家去操作這個訂單時,可能使用者A的訂單由於部分問題,導致資料回滾,事務沒有提交,這時商家的操作就會失去目標。

    不可重複讀(unrepeatable read)

    一個事務中,兩次讀操作出來的同一條資料值不同,就是不可重複讀。

    例如:我們有一個事務A,需要去查詢一下商品庫存,然後做扣減,這時,事務B操作了這個商品,扣減了一部分庫存,當事務A再次去查詢商品庫存的時候,發現這一次的結果和上次不同了,這就是不可重複讀。

    幻讀(phantom problem)

    一個事務中,兩次讀操作出來的結果集不同,就是幻讀。

    例如:一個事務A,去查詢現在已經支付的訂單有哪些,得到了一個結果集。這時,事務B新提交了一個訂單,當事務A再次去查詢時,就會出現,兩次得到的結果集不同的情況,也就是幻讀了。

    那針對這些結果,不同的隔離級別可以幹什麼呢?

    “讀未提(Read Uncommitted)”能預防啥?啥都預防不了。

    “讀提交(Read Committed)”能預防啥?使用“快照讀(Snapshot Read)”方式,避免“髒讀”,但是可能出現“不可重複讀”和“幻讀”。

    “可重複讀(Repeated Red)”能預防啥?使用“快照讀(Snapshot Read)”方式,鎖住被讀取記錄,避免出現“髒讀”、“不可重複讀”,但是可能出現“幻讀”。

    “序列化(Serializable)”能預防啥?有效避免“髒讀”、“不可重複讀”、“幻讀”,不過執行效率奇差。

    好了,鎖說完了,但是,我們的資料庫鎖,並不能有效的解決併發的問題,只是儘可能保證資料的一致性,當併發量特別大時,資料庫還是容易扛不住。那解決資料併發的另一個手段就是,儘可能的提高處理的速度。

    因為資料的IO要提升難度比較大,那麼透過其他的方式,對資料進行處理,減少資料庫的IO,就是提高併發能力的有效手段了。

    最有效的一種方式就是:快取

    想要減少併發出現的機率,那麼讀寫的效率越高,讀寫的執行時間越短,自然資料併發的可能性就變小了,併發效能也有提高了。

    還是用剛才的秒殺舉例,我們為的就是保證庫存的資料不出錯,賣出一個商品,減一個庫存,那麼,我們就可以將庫存放在記憶體中進行處理。這樣,就能夠保證庫存有序的及時扣減,並且不出現問題。這樣,我們的資料庫的寫操作也變少了,執行效率也就大大提高了。

    當然,常用的分散式快取方式有:Redis和Memcache,Redis可以持久化到硬碟,而Memcache不行,應該怎麼選擇,就看具體的使用場景了。

    當然,快取畢竟使用的範圍有限,很多的資料我們還是必須持久化到硬碟中,那我們就需要提高資料庫的IO能力,這樣避免一個執行緒執行時間太長,造成執行緒的阻塞。

    那麼,讀寫分離就是另一種有效的方式了

    當我們的寫成為了瓶頸的時候,讀寫分離就是一種可以選擇的方式了。

    我們的讀庫就只需要執行讀,寫庫就只需要執行寫,把讀的壓力從主庫中分離出去,讓主庫的資源只是用來保證寫的效率,從而提高寫操作的效能。

  • 中秋節和大豐收的關聯?
  • 老婆懷孕,有點貧血吃什麼好?