## redis與隊列
>[info] BLPOP 是列表的阻塞式(blocking)彈出原語。
redis是個對性能要求高的數據存取,特別適合隊列,它原生支持并發時串行對數據的存取操作,保證了不會重復取數據,但是它對于儲存大量結構化數據,和查詢上面不足,畢竟它是nosql,而mysql中規中矩天生關系型數據庫,對儲存大量數據,和查詢select支持得比較好,數據都是持久化的,但是它沒有像redis那樣原生對并發問題的支持,所以用來做隊列實在不明智。所以為了互補,需要結合,redis持久化,和數據查詢不好,但是我們又想看到延時隊列,延時任務,那么數據存量份就完美解決問題了,redis像往常一樣,用來存消息,存消息的同時還往mysql中存一份,隊列還跟往常一樣,處理消息時,把結果寫到mysql那份的狀態中,這樣就實現了我們的效果,對隊列沒影響,同時還有記錄方便我們查詢。
redis的blpop操作是原子性的,原子操作就是不可分割的操作,這個操作有兩個動作,取和彈出,數據從隊列中取出來,并從隊列中刪除,這是兩步操作,但是由于是原子操作的,所以不可分割,這兩步操作就是一個整體不可分割,要么都成功,要么都失敗。并且它還是阻塞性的,保證了不會重復取消息。
如果用mysql做這種操作,雖然用鎖也可以保證相同的效果,但是太慢了,就沒有做隊列的價值了,redis數據是在內存中操作,所以很快,即使是單線程阻塞的,也還是很快,快到耗時幾乎可以忽略不計,所以用來最隊列是最好不過的了。
>[danger] 原子操作是一個整體,不可分割,這個過程是一個整體,別人是不可能插進來的,也就是沒有間隙。
* * * * *
多個工人安全的取(不能重復執行,重復取),有鎖會阻塞,即使是redis也會阻塞,所以效率低,同一時刻只能有一個工人取,其它的工人,再多也會被阻塞,效率很低,mysql就更低了,如果是錯開的方式就不會這樣了,工人就可以同時取,還能保證安全,不會重復取,但是這種,對部署等其它方面有要求。不過其實隊列任務最耗時的部分是執行部分,取阻塞這點時間,對于任務執行時間來說不算什么,所以工人阻塞也沒事,取一下很快的,取了馬上就釋放了,釋放后才開始執行任務,所以這個幾乎沒什么影響,不是問題。
**比喻:**
1. 兩個廚師炒菜,但取菜窗口同時只能有一個人取,假設他們,取菜時間相同,炒菜時間也相同,那么,循環往復,他們只會開始時阻塞一次,此后就不會阻塞。(可以畫一個時序圖,在時間線上就能夠很容易的看出來這些特性)
2. 多個人一起包餃子,但是只有一雙筷子用來夾餡兒,那么當一個人在用筷子夾餡兒時,其他人都要等待。
* * * * *
### 根本在于縮短的鎖的路徑(過程),和量的削峰
> redis也并沒有銀彈,是的,它也繞不開鎖,但是這不影響它解決問題的方式和意義,之所以你覺得它是銀彈,可能根本原因在于你沒有理解你遇到的問題的根本原因。
redis隊列雖然彈出時還是串行的,還是鎖,但是它縮短串行的路徑,或者說串行的長度、范圍,而其它方式鎖,鎖的路徑太長了,鎖的是整個執行過程,所以redis方案有意義。
>[danger] **另外如果是多工人進程的話,雖然取是排隊串行,但是對于執行時還是會有并發搶占資源問題,還是離不開傳統的行鎖,所以想只用隊列解決并發問題就能高枕無憂一勞永逸是不現實的(沒有銀彈),除非只有一個工人進程。**
但即使這樣隊列也有它的意義,起碼并發工人進程數量比用戶數量少吧(可以理解為用戶量是無限的),工人進程還是傳統的鎖,而少量的工人進程去競爭鎖對系統來說幾乎沒什么壓力。**這么來看的話,在這種情況下,redis的作用就是限流和削峰了,其實回到最初的問題,就不難理解這一點了**,最初的問題是mysql(行鎖)扛不住高流量、高并發,**只是在大并發時性能下降很快,并不是行鎖不行、mysql做不了事**,其根本原因是性能問題,所以我們解決高請求量的問題就行了。
*****
### 參考
[Redis 實現隊列 · php筆記 · 看云](http://www.hmoore.net/xiak/php-node/399425)
[BLPOP — Redis 命令參考](http://redisdoc.com/list/blpop.html)
[Redis 實現隊列](http://mp.weixin.qq.com/s/Dkz85tZgTs7aPYSJoq4XwA)
[高級開發不得不懂的Redis Cluster數據分片機制](https://mp.weixin.qq.com/s/Jm7eg3PHkQwK5gTpksSXQw)
[伯克利推出世界最快的KVS數據庫Anna:秒殺Redis和Cassandra](http://mp.weixin.qq.com/s/3WmGpZkEuSz-ox_2CPCsqg)
> 針對同一個鍵值的并行更新操作會被串行化,它們需要同步機制來防止多個線程同時更新同一個鍵值。
[如何保障消息100%成功投遞給MQ中間件](https://mp.weixin.qq.com/s/fKTXHvmhdnO_EqBawnBGKQ)
[memcache內核,一文搞定!面試再也不怕了!!!(值得收藏)](https://mp.weixin.qq.com/s/zh9fq_e2BgdIeR8RKtY6Sg)
[想不到吧?我是這樣用Redis實現消息定時推送的!](https://mp.weixin.qq.com/s/ugYV8CBZwbSTs7VkmWy5xg)
[一份完整的阿里云 Redis 開發規范,值得收藏](https://mp.weixin.qq.com/s/uKXENaHqfbrIFnbwfJxRNw)
[除了緩存,Redis 都解決了哪些問題?](https://mp.weixin.qq.com/s/HUmByMp__slWxoOFdbQCOg)
[Memcache & Mysql 常用場景案例](http://blog.sina.com.cn/s/blog_466c66400100i29r.html)
[【開源組件】搞懂Redis到底快在哪里](https://mp.weixin.qq.com/s/3EgT5fyaxs-AsfSWi8XG3w)
[什么場景應該用 MongoDB ?](https://mp.weixin.qq.com/s/Nw4ZcJUH2vH-SQDY5wPVPg)
[微信高并發資金交易系統設計方案——百億紅包背后的技術支撐](https://mp.weixin.qq.com/s/suBAJrP6uN2kFgHtGz16mw)
> 任何大規模的東西都是模塊化的,手機就是個例子,手機的功能沒有局限性是因為可以安裝各種軟件,這些軟件就相當于手機的一個模塊。
> sql ,redis 命令,函數,語句,等等,你寫的那些都不是真正起作用的地方,都不是實際做操作的地方,都是一些命令發送,系統調用而已,執行 redis 命令只是將命令從客戶端發送給redis服務端而已,是否真正執行,何時執行,如何執行,都是由接收命令的服務端決定的,函數調用也是如此,寫代碼的地方都不是真正起作用做事的地方,真正處理的地方是底層的操作系統,而如何處理接收到的系統調用是操作系統決定的。在任何地方工作,都需要遵守它的規則才能更好的完成任務,編碼就是這樣,遵循服務端軟件的規則,了解操作系統底層的一些原理,將對你編碼有很大幫助,能讓你從底層去理解函數執行的細節,從而徹底掌控你寫的代碼。
[優雅實現延時任務之Redis篇](https://mp.weixin.qq.com/s/MjOq3qO9tqxhHX7W0v6ZPw)
[Redis進階不得不了解的內存優化細節](https://mp.weixin.qq.com/s/8dFB-ksyfn7nZ6HGeV56Aw)
[關系型數據庫 VS NoSQL,誰才是王者](https://mp.weixin.qq.com/s/PIVpNFPZn2go7rDhh-7pLQ)
[InfluxDB - 簡書]([https://www.jianshu.com/p/68c471bf5533](https://www.jianshu.com/p/68c471bf5533))
> InfluxDB(時序數據庫),常用的一種使用場景:監控數據統計。每毫秒記錄一下電腦內存的使用情況,然后就可以根據統計的數據,利用圖形化界面(InfluxDB V1一般配合Grafana)制作內存使用情況的折線圖;
[「ThinkPHP開發者周刊」第26期——Redis](http://www.hmoore.net/thinkphp/weekly/content/26.md)
[Reids之神奇的HyperLoglog解決統計問題](https://mp.weixin.qq.com/s/8FyBfqZClBNJ4wqGxkcuIA)
[Redis之發布/訂閱與Stream](https://mp.weixin.qq.com/s/awYFIP-grggXZkzlbrbulA)
[為什么 Redis 默認 16 個庫?90% 以上程序員不知道!](https://mp.weixin.qq.com/s/_jFxvy6sit24oooSf55q2g)
[不支持原子性的 Redis 事務也叫事務嗎? - 不假 - 博客園](https://www.cnblogs.com/lazyegg/p/13625275.html)
> Redis 事務可以一次執行多個命令,本質是一組命令的集合。一個事務中的所有命令都會序列化,**按順序地串行化執行而不會被其它命令插入,不許加塞。**
[圖解|什么是高并發利器NoSQL](https://mp.weixin.qq.com/s/ZxY97aHVKSEXiNywx3OYkg)
[你真的知道怎么實現一個延遲隊列嗎 ?](https://mp.weixin.qq.com/s/DcyXPGxXFYcXCQJII1INpg)
[簡單理解 Kafka 的消息可靠性策略](https://mp.weixin.qq.com/s/T6gCc8OBgyV-yeAg_MUzPQ)
> 沒有任何人能為你保證可靠,業務方自己能確認任務完成才是最可靠的,畢竟自己說可靠才算是可靠。
[WeCron是怎樣處理定時任務的](https://blog.betacat.io/post/how-wecron-schedules/)
[Why Disaster Happens at the Edges: An Introduction to Queue Theory – The New Stack 為什么災難發生在邊緣: 排隊論導論](https://thenewstack.io/an-introduction-to-queue-theory-why-disaster-happens-at-the-edges/)
----
last update:2018-3-11 10:25:01
- 開始
- 公益
- 更好的使用看云
- 推薦書單
- 優秀資源整理
- 技術文章寫作規范
- SublimeText - 編碼利器
- PSR-0/PSR-4命名標準
- php的多進程實驗分析
- 高級PHP
- 進程
- 信號
- 事件
- IO模型
- 同步、異步
- socket
- Swoole
- PHP擴展
- Composer
- easyswoole
- php多線程
- 守護程序
- 文件鎖
- s-socket
- aphp
- 隊列&并發
- 隊列
- 講個故事
- 如何最大效率的問題
- 訪問式的web服務(一)
- 訪問式的web服務(二)
- 請求
- 瀏覽器訪問阻塞問題
- Swoole
- 你必須理解的計算機核心概念 - 碼農翻身
- CPU阿甘 - 碼農翻身
- 異步通知,那我要怎么通知你啊?
- 實時操作系統
- 深入實時 Linux
- Redis 實現隊列
- redis與隊列
- 定時-時鐘-阻塞
- 計算機的生命
- 多進程/多線程
- 進程通信
- 拜占庭將軍問題深入探討
- JAVA CAS原理深度分析
- 隊列的思考
- 走進并發的世界
- 鎖
- 事務筆記
- 并發問題帶來的后果
- 為什么說樂觀鎖是安全的
- 內存鎖與內存事務 - 劉小兵2014
- 加鎖還是不加鎖,這是一個問題 - 碼農翻身
- 編程世界的那把鎖 - 碼農翻身
- 如何保證萬無一失
- 傳統事務與柔性事務
- 大白話搞懂什么是同步/異步/阻塞/非阻塞
- redis實現鎖
- 淺談mysql事務
- PHP異常
- php錯誤
- 文件加載
- 路由與偽靜態
- URL模式之分析
- 字符串處理
- 正則表達式
- 數組合并與+
- 文件上傳
- 常用驗證與過濾
- 記錄
- 趣圖
- foreach需要注意的問題
- Discuz!筆記
- 程序設計思維
- 抽象與具體
- 配置
- 關于如何學習的思考
- 編程思維
- 談編程
- 如何安全的修改對象
- 臨時
- 臨時筆記
- 透過問題看本質
- 程序后門
- 邊界檢查
- session
- 安全
- 王垠
- 第三方數據接口
- 驗證碼問題
- 還是少不了虛擬機
- 程序員如何談戀愛
- 程序員為什么要一直改BUG,為什么不能一次性把代碼寫好?
- 碎碎念
- 算法
- 實用代碼
- 相對私密與絕對私密
- 學習目標
- 隨記
- 編程小知識
- foo
- 落盤
- URL編碼的思考
- 字符編碼
- Elasticsearch
- TCP-IP協議
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依賴注入
- 科目一
- 開發筆記
- 經緯度格式轉換
- php時區問題
- 解決本地開發時調用遠程AIP跨域問題
- 后期靜態綁定
- 談tp的跳轉提示頁面
- 無限分類問題
- 生成微縮圖
- MVC名詞
- MVC架構
- 也許模塊不是唯一的答案
- 哈希算法
- 開發后臺
- 軟件設計架構
- mysql表字段設計
- 上傳表如何設計
- 二開心得
- awesomes-tables
- 安全的代碼部署
- 微信開發筆記
- 賬戶授權相關
- 小程序獲取是否關注其公眾號
- 支付相關
- 提交訂單
- 微信支付筆記
- 支付接口筆記
- 支付中心開發
- 下單與支付
- 支付流程設計
- 訂單與支付設計
- 敏感操作驗證
- 排序設計
- 代碼的運行環境
- 搜索關鍵字的顯示處理
- 接口異步更新ip信息
- 圖片處理
- 項目搭建
- 閱讀文檔的新方式
- mysql_insert_id并發問題思考
- 行鎖注意事項
- 細節注意
- 如何處理用戶的輸入
- 不可見的字符
- 抽獎
- 時間處理
- 應用開發實戰
- python 學習記錄
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文檔相似度驗證
- thinkphp5.0數據庫與模型的研究
- workerman進程管理
- workerman網絡分析
- java學習記錄
- docker
- 筆記
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京東
- pc_detailpage_wareBusiness
- doc
- 電商網站設計
- iwebshop
- 商品規格分析
- 商品屬性分析
- tpshop
- 商品規格分析
- 商品屬性分析
- 電商表設計
- 設計記錄
- 優惠券
- 生成唯一訂單號
- 購物車技術
- 分類與類型
- 微信登錄與綁定
- 京東到家庫存系統架構設計
- crmeb
- 命名規范
- Nginx https配置
- 關于人工智能
- 從人的思考方式到二叉樹
- 架構
- 今日有感
- 文章保存
- 安全背后: 瀏覽器是如何校驗證書的
- 避不開的分布式事務
- devops自動化運維、部署、測試的最后一公里 —— ApiFox 云時代的接口管理工具
- 找到自己今生要做的事
- 自動化生活
- 開源與漿果
- Apifox: API 接口自動化測試指南