最近在開發(fā)一個定時活動,而且活動是多個場次的。這個是后就需要在活動開始的時候推送信息給客戶端,結(jié)束的時候也要推送一次。簡單的設(shè)計方案就是將配置緩存在redis,然后每隔一秒就輪詢reids,獲取配置信息,然后判斷是不是到活動開始或者結(jié)束的時間點,然后推送給客戶端。
但是,這里會有一個問題,如果沒有到活動開始或結(jié)束的時間點,這里會造成很多無用的輪詢操作。這個操作不但增大了對這個key的訪問量,同時也會占用cpu,降低機器性能。
redis在2.8.0版本提供了一個鍵空間通知功能機制,對于這個功能的詳細描述,可以查閱官方文檔。簡單總結(jié)就是,客戶端可以訂閱一個key,當(dāng)這個可以發(fā)生改變時,redis會通知到已經(jīng)訂閱的客戶端。
這個實現(xiàn)也很簡單,我們可以通過一個demo來看看如何使用這個機制。
package main import ( "context" "fmt" "github.com/go-redis/redis/v8" "time" ) var redisCli *redis.Client func init() { // 連接redis redisCli = redis.NewClient(redis.Options{ Addr: "127.0.0.1:6379", Password: "redis123", }) } /* * redis key 過期自動通知 */ func SetExpireEvent() { // 設(shè)置一個鍵,并且3秒鐘之后過期 redisCli.Set(context.Background(), "test_expire_event_notify", "測試鍵值過期通知", 3*time.Second) } func SubExpireEvent() { // 訂閱key過期事件 sub := redisCli2.Subscribe(context.Background(), "__keyevent@0__:expired") // 這里通過一個for循環(huán)監(jiān)聽redis-server發(fā)來的消息。 // 當(dāng)客戶端接收到redis-server發(fā)送的事件通知時, // 客戶端會通過一個channel告知我們。我們再根據(jù) // msg的channel字段來判斷是不是我們期望收到的消息, // 然后再進行業(yè)務(wù)處理。 for { msg := -sub.Channel() fmt.Println("Channel ", msg.Channel) fmt.Println("pattern ", msg.Pattern) fmt.Println("pattern ", msg.Payload) fmt.Println("PayloadSlice ", msg.PayloadSlice) } } func main() { SetExpireEvent() go SubExpireEvent() // 這里sleep是為了防止main方法直接推出 time.Sleep(10 * time.Second) }
代碼結(jié)果輸出如下:
上面代碼實現(xiàn)邏輯很簡單,核心邏輯就是訂閱__keyevent@0__:expired這個事件,然后一個循環(huán)等待事件的通知。值得注意的是,要啟用這個特性需要修改配置文件,啟用notify-keyspace-events這個配置,可以參考配置文件中的注釋對不同事件進行啟用。
回到開始提及的業(yè)務(wù)場景,如何在這種場景中使用redis的機制呢?其實很簡單,當(dāng)活動配置到數(shù)據(jù)庫之后,會有一個更新緩存的步驟。在將數(shù)據(jù)設(shè)置在活動緩存時,只要我們計算當(dāng)前時間到活動開始/結(jié)束這個時間差,將這個差作為鍵的過期時間。
例如,活動id1的開始時間為t0, 結(jié)束時間為t2, 當(dāng)前時間為t。這個時候就可以這么設(shè)置:
// 活動開始的key設(shè)置 redisCli.Set(context.Background(), "id1:start", "活動開始了", t0 - t) // 活動結(jié)束結(jié)束的key設(shè)置 redisCli.Set(context.Background(), "id1:start", "活動開始了", t1 - t)
通過這么設(shè)置,當(dāng)活動開啟/結(jié)束就可以接收到相應(yīng)的通知了。
這種方案其實可以完全滿足文中的需求場景,但是這種方案其實也存在一些問題。其實這些問題在redis文檔中也有相應(yīng)說明。
本文介紹了使用redis的鍵空間通知機制來實現(xiàn)了一種業(yè)務(wù)場景,當(dāng)然這種方式并不是最好的,還有其他方式來實現(xiàn)。在實際開發(fā)中會有很多的因素要考慮,而且實現(xiàn)方式也是多種多樣,這個就需要我們分析每一種方案的利弊,然后進行抉擇。
到此這篇關(guān)于redis鍵空間通知使用實現(xiàn)的文章就介紹到這了,更多相關(guān)redis鍵空間通知 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
標(biāo)簽:果洛 北京 江蘇 大慶 臺州 楊凌 吉安 朝陽
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《redis鍵空間通知使用實現(xiàn)》,本文關(guān)鍵詞 redis,鍵,空間,通知,使用,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。