知其所以然~redis的原子性

原子性

原子性是數據庫的事務中的特性。在數據庫事務的情景下,原子性指的是:一個事務(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中的事務其實是要保證批量操作的原子性。

事務

MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事務相關的命令。事務可以一次執行多個命令, 并且帶有以下兩個重要的保證:

  • 事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。
  • 事務是一個原子操作:事務中的命令要么全部被執行,要么全部都不執行。

事務的關鍵字

  • EXEC 命令負責觸發并執行事務中的所有命令:
    如果客戶端在使用 MULTI 開啟了一個事務之后,卻因為斷線而沒有成功執行 EXEC ,那么事務中的所有命令都不會被執行。
  • 另一方面,如果客戶端成功在開啟事務之后執行 EXEC ,那么事務中的所有命令都會被執行。
    當使用 AOF 方式做持久化的時候, Redis 會使用單個 write(2) 命令將事務寫入到磁盤中。
    然而,如果 Redis 服務器因為某些原因被管理員殺死,或者遇上某種硬件故障,那么可能只有部分事務命令會被成功寫入到磁盤中。
    如果 Redis 在重新啟動時發現 AOF 文件出了這樣的問題,那么它會退出,并匯報一個錯誤。
    使用redis-check-aof程序可以修復這一問題:它會移除 AOF 文件中不完整事務的信息,確保服務器可以順利啟動。
    從 2.2 版本開始,Redis 還可以通過樂觀鎖(optimistic lock)實現 CAS (check-and-set)操作,具體信息請參考文檔的后半部分。

事務的語句

> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1

為什么 Redis 不支持回滾(roll back)

如果你有使用關系式數據庫的經驗, 那么 “Redis 在事務失敗時不進行回滾,而是繼續執行余下的命令”這種做法可能會讓你覺得有點奇怪。
以下是這種做法的優點:

  • Redis 命令只會因為錯誤的語法而失敗(并且這些問題不能在入隊時發現),或是命令用在了錯誤類型的鍵上面:這也就是說,從實用性的角度來說,失敗的命令是由編程錯誤造成的,而這些錯誤應該在開發的過程中被發現,而不應該出現在生產環境中。
  • 因為不需要對回滾進行支持,所以 Redis 的內部可以保持簡單且快速。
    有種觀點認為 Redis 處理事務的做法會產生 bug , 然而需要注意的是, 在通常情況下, 回滾并不能解決編程錯誤帶來的問題。 舉個例子, 如果你本來想通過 INCR 命令將鍵的值加上 1 , 卻不小心加上了 2 , 又或者對錯誤類型的鍵執行了 INCR , 回滾是沒有辦法處理這些情況的。

轉載于:https://www.cnblogs.com/lori/p/9300087.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451223.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451223.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451223.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JoinPoint的用法

JoinPoint 對象 JoinPoint對象封裝了SpringAop中切面方法的信息,在切面方法中添加JoinPoint參數,就可以獲取到封裝了該方法信息的JoinPoint對象. 常用api: 方法名功能Signature getSignature();獲取封裝了署名信息的對象,在該對象中可以獲取到目標方法名,所屬類的Class等信息…

解決 No projects are available for deployment to this server!

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 如題,今天在嘗試部署從SVN上down下來的項目時,發現不能被tomcat識別成web項目!原因是SVN上down下來的…

地大信工成果快報

在成果快報投稿中,請注意以下幾個問題:(1)成果信息一定要準確、全面,所有作者必須都要列出來,而不要出現et al. 這樣的表述,通訊作者一定要用*號標注;(2)成果…

javaBean的命名規則

前段時間,寫程序時,出了錯誤,竟然沒有想到是自己屬性命名的問題,哎~~~真是一定要注意規范呀,在這里我從網上找了些,規范作為參考 Sun 推薦的命名規范 1 ,類名要首字母大寫,后面的單詞…

volatile的應用

volatile,中文意思是不穩定的、反復無常的,用來修飾變量,和多線程、并發有關系。 Java代碼在編譯后會變成Java字節碼,字節碼被類加載器加載到JVM里,JVM執行字節碼,最終需要轉化為匯編指令在CPU上執行。 在多…

漫談國內智能手機市場現狀

本文純屬一時興起,想到哪兒寫到哪兒,本人文筆也不咋地,寫的也比較隨意,如有錯誤歡迎指正,有啥意見歡迎交流。原創文章,轉載注明emouse的技術專欄。 我是一個不折不扣的數碼愛好者,對電腦手機這些…

【刷題】BZOJ 4195 [Noi2015]程序自動分析

Description 在實現程序自動分析的過程中,常常需要判定一些約束條件是否能被同時滿足。 考慮一個約束滿足問題的簡化版本:假設x1,x2,x3,…代表程序中出現的變量,給定n個形如xixj或xi≠xj的變量相等/不等的約束條件,請判定是否可以分別為每一個…

mysql 5.5 安裝配置方法圖文教程

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 回憶一下mysql 5.5 安裝配置方法,整理mysql 5.5 安裝配置教程筆記,分享給大家。 MySQL下載地址:htt…

git解除與遠程分支的關聯

在工作中,經常需要將同一份代碼傳到不同的git倉庫中去 如果本地同樣一份代碼,已經關聯了一個與遠程分支,那么怎么才能解除原程分支,并關聯到一個新的分支將代碼提交到新的分支上去呢? 1、如果你已經在遠程創建了一個分…

FindWindow用法

函數功能:該函數獲得一個頂層窗口的句柄,該窗口的類名和窗口名與給定的字符串相匹配。這個函數不查找子窗口。在查找時不區分大小寫。 函數型:HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName&#xff0…

中國大城市政治地位綜合實力排名

中國大城市政治地位綜合實力排名! 中國大城市政治地位綜合實力排名!政治地位: 政治地位: 1(直轄市 4 個):上海、北京、天津、重慶 2(副省級城市 15 個):廣州、深圳、武漢、南京、沈陽…

sourcemap總結

sourcemap在線上壓縮文件調試中很重要,在此總結如下: 1. 開啟sourcemap (1). 瀏覽器要開啟source-map支持(2). 壓縮文件底部要有source-map的URL,壓縮要開啟source-map(3). .map文件要放在服務器,source-map URL指向的位置 2. sou…

navicat 導出的sql文件,再導入,運行SQL文件成功,數據庫中卻沒有表

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。 問題描述:本來在數據庫上右鍵 ,運行SQL文件 ,就可以導入 sql ,建表成功,并且數據也該的…

mysql索引之二級索引學習總結

二級索引又稱輔助索引、非聚集索引(no-clustered index)。b&#xff0b;tree樹結構。然而二級索引的葉子節點不保存記錄中的所有列&#xff0c;其葉子節點保存的是<健值&#xff0c;(記錄)地址>。好似聚集索引中非葉子節點保存的信息&#xff0c;不同的是二級索引保存的是…

264,avs中Skip宏塊與Direct預測模式 ,對稱模式的區別

1. B_Skip類型宏塊 &#xff1a;無像素殘差&#xff0c;無運動矢量殘差&#xff08;MVD&#xff09;和參考幀。解碼時&#xff0c;通過Direct預測模式&#xff08;時間或空間&#xff09;計算出前、后向MV后&#xff0c;直接利用前、后向MV得到像素預測值。像 素重構值像…

【hdu 6444】Neko's loop

【鏈接】 我是鏈接,點我呀:) 【題意】 給你一個序列. 你可以選擇起點i。 然后每次往右跳k次。 得到下一個值a[ik];。 問你跳m次能得到的最大值ma是多少。 如果>s輸出0 否則輸出s-ma; 【題解】 最后肯定會形成gcd(n,k)個環的。 對于每個環(長度為cnt。 預處理出從1..2cnt的…

高性能MySQL之Count統計查詢

近一段時間&#xff0c;有同事問我 “MySQL執行count很慢&#xff0c;有沒有什么優化的空間”。當時在忙&#xff0c;就回復了一句“innodb里面count統計都是實時統計&#xff0c;慢一些是正常的”&#xff0c; 周末閑暇下來&#xff0c;想到以前有好多人都問過關于count的問題…

js轉換字符串為base64位

在window對象下有兩個api,可以對ASCII編碼進行編譯,得到base64位的字符串 btoa:編碼為base64atob:解碼為ASCII碼此種方法不能對中文進行操作,因為ASCII碼中沒有中文,如果編碼會得到亂碼 要編碼中文可以先用encodeURIComponent() 對字符串進行轉義,轉義后再btoa()成base64就可以…

java 文件下載,中文表名,中文內容

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 RequestMapping("userDownloadTemplet")private void userDownloadTemplet(HttpServletRequest request,HttpServletResponse …

cherry-pick的用法

簡述 git cherry-pick可以選擇某一個分支中的一個或幾個commit(s)來進行操作。例如&#xff0c;假設我們有個穩定版本的分支&#xff0c;叫v2.0&#xff0c;另外還有個開發版本的分支v3.0&#xff0c;我們不能直接把兩個分支合并&#xff0c;這樣會導致穩定版本混亂&#xff0c…