基於雲開發搭建 KV 緩存系統 2.0

昨天分享了基於雲開發實現 KV 緩存的方法,但在實際的開發過程當中,這樣的功能其實很難知足全部的需求。在這個時候,就須要對原有的方案進行優化,來解決一些其餘的問題。緩存

具體來講,以前的代碼有如下幾個問題:async

  1. 沒有進行錯誤處理
  2. 沒有對數據進行過時時間的處理
  3. 若是沒有數據的話,如何觸發數據更新

這些都沒有在昨天的文章中說起,今天就補全這些部分。函數

對數據進行錯誤處理

在使用雲開發的時候,是有出錯的可能的,所以,咱們須要對可能出錯的部分進行處理,以確保函數自己是能夠正常返回的。優化

咱們須要在原有的函數中進行修改,修改後的結果以下spa

設置緩存

async function setCache(key, value) {
    try {
        let result = await db.collection("cache").add({
            data: {
                _id: key,
                value: value
            }
        })
        return {
            code:0
        }
    } catch (error) {
        return {
            code:1,
            msg: error
        }
    }
}

讀取緩存

async function getCache(key) {
    try {
        let { data } = await db.collection("cache").doc(key).get();
        return {
            code: 0,
            value: data.value
        };
    } catch (error) {
        return {
            code: 1,
            msg: error
        }
    }
}

經過這一輪的修改,咱們在原有的函數基礎之上添加了錯誤處理,不管如何,緩存函數自己不會報錯,不會阻塞外部邏輯的執行。在外部邏輯側只須要根據返回的 code 來進行判斷是獲取緩存,仍是直接進行邏輯計算,完成全部的工做。3d

對數據進行過時時間的處理

在前一個版本中,咱們加入了錯誤處理,但仍是沒有解決一個問題,那就是數據的過時邏輯。但緩存在實際使用過程當中,是存在過時的可能,既然存在過時,咱們就須要在緩存中,實現相應的過時邏輯的處理。code

想要實現,成本倒也不高,你只須要在數據中加一個過時時間字段expiredAt就能夠完成相應的處理。blog

設置緩存

對設定緩存的函數加入一個新的可選參數,來設定緩存過時時間。未設定緩存過時時間的狀況下,你能夠緩存 3600 秒(一小時)。接口

async function setCache(key, value,expire_time = 3600) {
    try {
        let expired_time = (new Date()) + expire_time * 1000
        let result = await db.collection("cache").add({
            data: {
                _id: key,
                value: value,
                expiredAt: expired_time
            }
        })
        return {
            code:0
        }
    } catch (error) {
        return {
            code:1,
            msg: error
        }
    }
}

讀取緩存

相似的,在緩存中加入相應的配置,能夠完成緩存過時的處理開發

async function getCache(key) {
    try {
        let { data } = await db.collection("cache").doc(key).get();
        let current = (new Date()).valueOf();
        if (data.expiredAt < current) {
            return { 
                code:1,
                msg: "Cache expired"
            }
        }
        return {
            code: 0,
            value: data.value
        };
    } catch (error) {
        return {
            code: 1,
            msg: error
        }
    }
}

如何觸發數據的更新

在上一個版本中,咱們完成了數據的過時,但目前數據的過時後處理是由業務邏輯來完成的,咱們有沒有辦法在緩存過時的時候,進行相應的觸發,從而主動更新緩存,這樣能夠確保緩存接口始終能夠拿到數據?

也能夠。咱們能夠再新增一個參數來完成。這一部分主要影響的是獲取 Cache 的部分,因此,設置緩存和上一個版本相同。

設置緩存

async function setCache(key, value,expire_time = 3600) {
    try {
        let expired_time = (new Date()) + expire_time * 1000
        let result = await db.collection("cache").add({
            data: {
                _id: key,
                value: value,
                expiredAt: expired_time
            }
        })
        return {
            code:0
        }
    } catch (error) {
        return {
            code:1,
            msg: error
        }
    }
}

獲取緩存

獲取緩存時,咱們須要可以實現相應的數據更新的能力,所以,咱們須要新增一個參數,來完成數據更新的部分。新的參數中咱們須要傳入一個函數,這個函數將會執行數據更新邏輯,將數據

async function getCache(key,uploadFunction) {
    try {
        let { data } = await db.collection("cache").doc(key).get();
        let current = (new Date()).valueOf();
        if (data.expiredAt < current) {
            if(uploadFunction){
                const data = uploadFunction();
                setCache(key,data)
                return {
                    code:0,
                    value: data
                }
            }
            return { 
                code:1,
                msg: "Cache expired"
            }
        }
        return {
            code: 0,
            value: data.value
        };
    } catch (error) {
        return {
            code: 1,
            msg: error
        }
    }
}

總結

在今天的文章中,咱們經過一些簡單的處理,完成了緩存函數的三步優化,分別加入了緩存處理、過時時間和自動更新,讓緩存能夠變得更好用。

那麼問題來了,你以爲這個緩存系統還有什麼能夠優化的點麼?

相關文章
相關標籤/搜索