Redis 的操作為什么是的原子性的詳解【轉】


源地址:https://blog.csdn.net/ahjxhy2010/article/details/80520434

原子性

原子性是數據庫的事務中的特性。在數據庫事務的情景下,原子性指的是:一個事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節。

對於Redis而言,命令的原子性指的是:一個操作的不可以再分,操作要么執行,要么不執行。

Redis操作原子性的原因

Redis的操作之所以是原子性的,是因為Redis是單線程的。

由於對操作系統相關的知識不是很熟悉,從上面這句話並不能真正理解Redis操作是原子性的原因,進一步查閱進程與線程的概念及其區別。

 

進程與線程

進程

計算機中已執行程序的實體。比如,一個啟動了的php-fpm,就是一個進程。

線程

操作系統能夠進行運算調度的最小單元。它被包含在進程之中,是進程的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每條線程並行執行不同的任務。比如,mysql運行時,mysql啟動后,該mysql服務就是一個進程,而mysql的連接、查詢的操作,就是線程。

進程與線程的區別

  • 資源(如打開文件):進程間的資源相互獨立,同一進程的各線程間共享資源。某進程的線程在其他進程不可見。

  • 通信:進程間通信:消息傳遞、同步、共享內存、遠程過程調用、管道。線程間通信:直接讀寫進程數據段(需要進程同步和互斥手段的輔助,以保證數據的一致性)。

  • 調度和切換:線程上下文切換比進程上下文切換要快得多。

線程,是操作系統最小的執行單元,在單線程程序中,任務一個一個地做,必須做完一個任務后,才會去做另一個任務。

Redis在並發中的表現

Redis的API是原子性的操作,那么多個命令在並發中也是原子性的嗎?

看看下面這段代碼:

$redis= newRedis();

$redis->connect('127.0.0.1',6379);

for($i= 0;$iget('val');

$num++;

$redis->set('val',$num);

usleep(10000);

}

用兩個終端執行上面的程序,發現val的結果是小於2000的值,那么可以知道,在程序中執行多個Redis命令並非是原子性的,這也和普通數據庫的表現是一樣的。

如果想在上面的程序中實現原子性,可以將get和set改成單命令操作,比如incr,或者使用Redis的事務,或者使用Redis+Lua的方式實現。

總結

綜上所述,對Redis來說,執行get、set以及eval等API,都是一個一個的任務,這些任務都會由Redis的線程去負責執行,任務要么執行成功,要么執行失敗,這就是Redis的命令是原子性的原因。

Redis本身提供的所有API都是原子操作,Redis中的事務其實是要保證批量操作的原子性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM