使用PostgreSQL替代Redis實現佇列、分散式鎖和釋出/訂閱
兩種常用架構:
- 用於資料儲存的 PostgreSQL
- Redis 用於協調後臺作業佇列(以及一些有限的原子操作)
Redis 非常棒,但如果我告訴你這個堆疊最常見的用例實際上可以只使用 PostgreSQL 來實現呢?很有可能您使用 Redis 做的事情實際上也適用於 PostgreSQL。跳過Redis並節省依賴多個資料服務的運營成本和開發複雜性可能是一個值得的權衡。(banq注:擴充套件性從小到大:本文方式<Redis<kafka,複雜性是倒過來的)
用例 1:作業佇列
也許我見過的 Redis 最常見的用途是協調從您的 Web 服務到後臺工作人員池的作業分派。這個概念是,您希望記錄執行某些後臺工作的願望(可能帶有一些輸入資料),並確保您的眾多後臺工作人員中只有一個會監聽它。Redis 對此有所幫助,因為它為其資料結構提供了一組豐富的原子操作。
但是自從 9.5 版引入後,PostgreSQL 就有了語句的SKIP LOCKED選項SELECT ... FOR ...(這裡是文件)。當指定這個選項時,PostgreSQL 將忽略任何需要等待被釋放鎖的行。
BEGIN; WITH job AS ( SELECT id FROM jobs WHERE status = 'pending' LIMIT 1 FOR UPDATE SKIP LOCKED ) UPDATE jobs SET status = 'running' WHERE jobs.id = job.id RETURNING jobs.*; COMMIT; |
透過指定FOR UPDATE SKIP LOCKED,將為從 返回的任何行隱式獲取行級鎖SELECT。此外,因為您指定了SKIP LOCKED,此語句不可能阻塞另一個事務。如果有另一個作業準備處理,它將被返回。由於行級鎖定,執行此命令的多個工作人員無需擔心接收同一行。
這種技術的最大警告是,如果您有大量工作人員試圖退出此佇列,並且有大量工作為他們提供服務,他們可能會花一些時間單步執行工作並嘗試獲取鎖。在實踐中,我開發的大多數應用程式的後臺工作人員都不到十幾個,而且成本可能不會很高。
用例 2:應用程式鎖
假設您有一個與第三方服務的同步例程,並且您只想為所有伺服器程式中的任何給定使用者執行它的一個例項。這是我見過的 Redis 的另一個常見應用:分散式鎖定。
PostgreSQL 也可以使用它的Advisory鎖來實現這一點。Advisory鎖允許您利用 PostgreSQL 在內部使用的相同鎖定引擎來實現您自己的應用程式定義的目的。
用例 3:釋出/訂閱
我把最酷的例子留到最後:將事件推送到您的活躍客戶。例如,假設您需要通知使用者他們有新訊息可供閱讀。或者,您可能希望在資料可用時將資料流式傳輸到客戶端。通常,Web 套接字是這些事件的傳輸層,而 Redis 作為 Pub/Sub 引擎。
但是,從版本 9 開始,PostgreSQL 也透過LISTENandNOTIFY語句提供了此功能。任何 PostgreSQL 客戶端都可以訂閱 ( LISTEN) 到一個特定的訊息通道,它只是一個任意字串。當任何其他客戶端NOTIFY在該頻道上傳送訊息 ( ) 時,所有其他訂閱的客戶端都會收到通知。或者,可以附加一條小訊息。
如果您碰巧使用 Rails 和 ActionCable,那麼使用 PostgreSQL 甚至是開箱即用的。
相關文章
- .NetCore使用Redis,StackExchange.Redis佇列,釋出與訂閱,分散式鎖的簡單使用NetCoreRedis佇列分散式
- Redisson 分散式鎖實現之前置篇 → Redis 的釋出/訂閱 與 LuaRedis分散式
- Redis 釋出訂閱模式:原理拆解並實現一個訊息佇列Redis模式佇列
- 用 Redis 實現分散式鎖與實現任務佇列Redis分散式佇列
- 使用Spring Data Redis 實現訂閱/釋出SpringRedis
- RabbitMQ釋出訂閱實戰-實現延時重試佇列MQ佇列
- 使用redis和zookeeper實現分散式鎖Redis分散式
- Redis 分散式鎖與任務佇列實戰Redis分散式佇列
- 使用 Redis 實現分散式鎖Redis分散式
- Postgres是否合適替代Redis或Kafka實現釋出訂閱作業? - HNRedisKafka
- Redis釋出訂閱Redis
- 如何使用Redis實現分散式鎖Redis分散式
- Redis 設計與實現 (六)--釋出訂閱Redis
- [實戰]laravel + redis訂閱釋出 +swoole實現實時訂單通知LaravelRedis
- 分散式鎖----Redis實現分散式Redis
- Redis實現分散式鎖Redis分散式
- Redis的釋出訂閱Redis
- Redis分散式鎖的原理和實現Redis分散式
- Redis的訊息釋出和訂閱Redis
- 使用Redis分散式鎖實現主備Redis分散式
- 【Redis】利用 Redis 實現分散式鎖Redis分散式
- Redis(設計與實現):---釋出與訂閱介紹Redis
- SpringBoot+Redis 實現訊息訂閱釋出Spring BootRedis
- Redis的釋出訂閱及.NET客戶端實現Redis客戶端
- Redis之分散式鎖實現Redis分散式
- 分散式鎖之Redis實現分散式Redis
- redis分散式鎖-java實現Redis分散式Java
- Redis如何實現分散式鎖Redis分散式
- 分散式鎖實現(一):Redis分散式Redis
- 利用Redis實現分散式鎖Redis分散式
- redis分散式鎖的實現Redis分散式
- redis分散式鎖-SETNX實現Redis分散式
- Redis 的訂閱與釋出Redis
- Laravel Redis釋出與訂閱.LaravelRedis
- Redis之釋出與訂閱Redis
- Redis分散式鎖的使用與實現原理Redis分散式
- node 訂閱釋出及實現
- 實現簡單延遲佇列和分散式延遲佇列佇列分散式