您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“go-zero實(shí)踐中的緩存設(shè)計(jì)之如何使用biz cache”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
選課系統(tǒng)
內(nèi)容社交系統(tǒng)
秒殺
像這些系統(tǒng),我們可以在業(yè)務(wù)層再增加一層緩存來存儲系統(tǒng)中的關(guān)鍵信息,如選課系統(tǒng)中學(xué)生選課信息,課程剩余名額;內(nèi)容社交系統(tǒng)中某一段時間之間的內(nèi)容信息等。
接下來,我們以內(nèi)容社交系統(tǒng)來進(jìn)行舉例說明。
在內(nèi)容社交系統(tǒng)中,我們一般是先查詢一批內(nèi)容列表,然后點(diǎn)擊某條內(nèi)容查看詳情,
在沒有添加biz緩存前,內(nèi)容信息的查詢流程圖應(yīng)該為:
從上圖以及上一篇文章 緩存設(shè)計(jì)的好,服務(wù)基本不會倒 中我們可以知道,內(nèi)容列表的獲取是沒辦法依賴緩存的, 如果我們在業(yè)務(wù)層添加一層緩存用來存儲列表中的關(guān)鍵信息(甚至完整信息),那么多行記錄的訪問不再是一個問題,這就是biz redis要做的事情。 接下來我們來看一下設(shè)計(jì)方案,假設(shè)內(nèi)容系統(tǒng)中單行記錄包含以下字段
字段名稱 | 字段類型 | 備注 |
---|---|---|
id | string | 內(nèi)容id |
title | string | 標(biāo)題 |
content | string | 詳細(xì)內(nèi)容 |
createTime | time.Time | 創(chuàng)建時間 |
我們的目標(biāo)是獲取一批內(nèi)容列表,而盡量避免內(nèi)容列表走db造成訪問壓力,首先我們采用redis的sort set數(shù)據(jù)結(jié)構(gòu)來存儲,根需要存儲的字段信息量,有兩種redis存儲方案:
緩存局部信息 對其關(guān)鍵字段信息(如:id等)按照一定規(guī)則壓縮,并存儲,score我們用createTime
毫秒值(時間值相等這里不討論),這種存儲方案的好處是節(jié)約redis存儲空間, 那另一方面,缺點(diǎn)就是需要對列表詳細(xì)內(nèi)容進(jìn)行二次回查(但這次回查是會利用到持久層的行記錄緩存的)
緩存完整信息 對發(fā)布的所有內(nèi)容按照一定規(guī)則壓縮后均進(jìn)行存儲,同樣score我們還是用createTime
毫秒值,這種存儲方案的好處是業(yè)務(wù)的增、刪、查、改均走reids,而db層這時候 就可以不用考慮行記錄緩存了,持久層僅提供數(shù)據(jù)備份和恢復(fù)使用,從另一方面來看,其缺點(diǎn)也很明顯,需要的存儲空間、配置要求更高,費(fèi)用也會隨之增大。
示例代碼:
type Content struct { Id string `json:"id"` Title string `json:"title"` Content string `json:"content"` CreateTime time.Time `json:"create_time"` } const bizContentCacheKey = `biz#content#cache` // AddContent 提供內(nèi)容存儲 func AddContent(r redis.Redis, c *Content) error { v := compress(c) _, err := r.Zadd(bizContentCacheKey, c.CreateTime.UnixNano()/1e6, v) return err } // DelContent 提供內(nèi)容刪除 func DelContent(r redis.Redis, c *Content) error { v := compress(c) _, err := r.Zrem(bizContentCacheKey, v) return err } // 內(nèi)容壓縮 func compress(c *Content) string { // todo: do it yourself var ret string return ret } // 內(nèi)容解壓 func uncompress(v string) *Content { // todo: do it yourself var ret Content return &ret } // ListByRangeTime提供根據(jù)時間段進(jìn)行數(shù)據(jù)查詢 func ListByRangeTime(r redis.Redis, start, end time.Time) ([]*Content, error) { kvs, err := r.ZrangebyscoreWithScores(bizContentCacheKey, start.UnixNano()/1e6, end.UnixNano()/1e6) if err != nil { return nil, err } var list []*Content for _, kv := range kvs { data := uncompress(kv.Key) list = append(list, data) } return list, nil }
在以上例子中,redis是沒有設(shè)置過期時間的,我們將增、刪、改、查操作均同步到redis,我們認(rèn)為內(nèi)容社交系統(tǒng)的列表訪問請求是比較高的情況下才做這樣的方案設(shè)計(jì), 除此之外,還有一些數(shù)據(jù)訪問,沒有像內(nèi)容設(shè)計(jì)系統(tǒng)這么頻繁的訪問, 可能是某一時間段內(nèi)訪問量突如其來的增加,之后可能很長一段時間才會再訪問一次,以此間隔,或者說不會再訪問了,面對這種場景,我們又該如何考慮緩存的設(shè)計(jì)呢?在go-zero內(nèi)容實(shí)踐中,有兩種方案可以解決這種問題:
增加內(nèi)存緩存:通過內(nèi)存緩存來存儲當(dāng)前可能突發(fā)訪問量比較大的數(shù)據(jù),常用的存儲方案采用map數(shù)據(jù)結(jié)構(gòu)來存儲,map數(shù)據(jù)存儲實(shí)現(xiàn)比較簡單,但緩存過期處理則需要增加定時器來處理,另一宗方案是通過go-zero庫中的 Cache ,其是專門用于內(nèi)存緩存管理。
采用biz redis,并設(shè)置合理的過期時間
“go-zero實(shí)踐中的緩存設(shè)計(jì)之如何使用biz cache”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。