【攻略】如何在云開發(fā)中使用 Redis?

默認(rèn)情況下,云開發(fā)的函數(shù)部署在公共網(wǎng)絡(luò)中,只可以訪問公網(wǎng)。如果開發(fā)者需要訪問騰訊云的 Redis、TencentDB、CVM、Kafka 等資源,需要建立私有網(wǎng)絡(luò)來確保數(shù)據(jù)安全及連接安全。

本文會演示如何在云開發(fā)的函數(shù)中使用 Redis,如需訪問其他數(shù)據(jù)庫資源,也可以參考本文的思路。

Redis 介紹及應(yīng)用場景

Redis 是一個開源的 In-MemoryNoSQL數(shù)據(jù)庫,可以用作數(shù)據(jù)庫、緩存和消息中間件。 支持多種類型的數(shù)據(jù)結(jié)構(gòu),如字符串(strings)、散列(hashes)、列表(lists)和集合(sets)

常見的應(yīng)用場景有:

  1. 會話緩存: Redis 不僅在內(nèi)存中存儲,讀寫速度較快,還提供了持久化方案來提供一致性

  2. 頁面緩存:可以作為 PHP 或者是 Node.js 服務(wù)端渲染結(jié)果的緩存

  3. 消息隊列: Redis 支持列表且支持 Pub/Sub,可以作為消息隊列來使用

  4. 排行榜/計數(shù):Redis 在內(nèi)存中,因此它在遞增和遞減方面做得非常出色,另外,Redis 也支持集合和排序集合數(shù)據(jù)結(jié)構(gòu),比較適合排行榜的場景

私有網(wǎng)絡(luò)介紹

私有網(wǎng)絡(luò)(Virtual Private Cloud,VPC)是基于騰訊云構(gòu)建的專屬云上網(wǎng)絡(luò)空間,為您在騰訊云上的資源提供網(wǎng)絡(luò)服務(wù),不同私有網(wǎng)絡(luò)間完全邏輯隔離。您可以自定義網(wǎng)絡(luò)環(huán)境、路由表、安全策略等;同時,私有網(wǎng)絡(luò)支持多種方式連接 Internet、連接其他 VPC、連接您的本地數(shù)據(jù)中心,助力您輕松部署云上網(wǎng)絡(luò)。

相比于用戶共享資源池的基礎(chǔ)網(wǎng)絡(luò),在私有網(wǎng)絡(luò)中用戶可以自由定義網(wǎng)段劃分、IP 地址和路由策略;安全方面可提供網(wǎng)絡(luò) ACL 及安全組的訪問控制,靈活性和安全性更高。

20191206114303.png

私有網(wǎng)絡(luò)有三個核心組成成分:私有網(wǎng)絡(luò)網(wǎng)段、子網(wǎng)和路由表。

一個私有網(wǎng)絡(luò)由至少一個子網(wǎng)組成,子網(wǎng)的 CIDR(無類別域間路由) 必須在私有網(wǎng)絡(luò)的 CIDR 內(nèi)。

子網(wǎng)用于管理彈性云服務(wù)器網(wǎng)絡(luò)平面的一個網(wǎng)絡(luò),可以提供 IP 地址管理、DNS 等服務(wù)。私有網(wǎng)絡(luò)中的所有云資源(如云服務(wù)器、云數(shù)據(jù)庫等)都必須部署在子網(wǎng)內(nèi)。

私有網(wǎng)絡(luò)具有 地域(Region) 屬性(如廣州),而子網(wǎng)具有 可用區(qū)(Zone) 屬性(如廣州一區(qū)),一個私有網(wǎng)絡(luò)下的子網(wǎng)可以屬于該地域下不同可用區(qū),同一私有網(wǎng)絡(luò)下各個子網(wǎng)內(nèi)資源無論是否在同一可用區(qū)內(nèi),均默認(rèn)內(nèi)網(wǎng)互通。

路由表由多條路由策略組成,用于控制私有網(wǎng)絡(luò)內(nèi)子網(wǎng)的出流量走向。每個子網(wǎng)僅且只能關(guān)聯(lián)一個路由表,一個路由表可以關(guān)聯(lián)多個子網(wǎng)。您可以為不同流量走向的子網(wǎng)創(chuàng)建多個路由表

新建私有網(wǎng)絡(luò)

在騰訊云控制臺的私有網(wǎng)絡(luò)中可以免費創(chuàng)建私有網(wǎng)絡(luò),由于私有網(wǎng)絡(luò)具有地域(Region)屬性,我們需要在函數(shù)所在的地域來新建私有網(wǎng)絡(luò)。

這里我們選擇華東地區(qū)(上海)地域,如果您已經(jīng)在該地域建立了私有網(wǎng)絡(luò),可以跳過這一步

20191206102827.png

創(chuàng)建私有網(wǎng)絡(luò)時需要初始化一個子網(wǎng),這里我們選擇建一個在上海二區(qū)可用區(qū)的子網(wǎng)

20191206103504.png

將云函數(shù)加入私有網(wǎng)絡(luò)

創(chuàng)建私有網(wǎng)絡(luò)和子網(wǎng)之后,我們需要配置函數(shù)的網(wǎng)絡(luò)模式,將函數(shù)加入到華東地區(qū)(上海)地域的私有網(wǎng)絡(luò)中

在騰訊云的云開發(fā)控制臺中,找到需要配置的云函數(shù),點擊編輯進入配置界面

20191205144942.png

在函數(shù)配置界面中,修改網(wǎng)絡(luò)配置為華東地區(qū)(上海)地域的虛擬網(wǎng)絡(luò)和子網(wǎng)。

20191206104719.png

購買 Redis 并加入同一個私有網(wǎng)絡(luò)

接下來我們在騰訊云的云數(shù)據(jù)庫控制臺中,找到上海地域,新建一個 Redis 實例

20191206102732.png

這里為了方便演示,我們選擇了一個內(nèi)存為 256 MB 的單副本實例,您也可以根據(jù)具體的需求和場景來選擇合適的套餐。

TIPS

在生產(chǎn)環(huán)境中,為了保證可靠性和高可用,建議不要選擇選擇單副本,最好選擇多副本或者 Redis 集群;另外如果只在 CVM 等單機部署了 Redis,也需要做好容災(zāi)和備份

注意網(wǎng)絡(luò)類型需要選擇私有網(wǎng)絡(luò),同時選擇剛才建好的私有網(wǎng)絡(luò)和子網(wǎng)

20191206103751.png

云函數(shù)中連接 Redis

購買 Redis 之后,很快就會創(chuàng)建 Redis 的實例,創(chuàng)建成功之后,在網(wǎng)絡(luò)下我們可以看到 Redis 實例的 ip,我們需要在云函數(shù)中連接這個實例

20191206105019.png

在云函數(shù)中安裝 Redis 客戶端庫

為了連接和操作 Redis 實例,我們需要一個 Redis 客戶端,這里我們使用社區(qū)開源的 ioredis 作為 Redis 客戶端庫作為示例:

20191206132609.png

首先,在云函數(shù)目錄中的 package.json 中新增依賴 ioredis 依賴,設(shè)置完之后記得在開發(fā)者工具中選擇 上傳并部署(云端安裝依賴)

{
  "name": "redis-demo",
  "dependencies": {
    "wx-server-sdk": "latest",
    "ioredis": "4.14.1"
  }
}

云函數(shù)中連接和操作 Redis

接下來,在云函數(shù)中編寫代碼來連接和操作 Redis,這里需要提供 Redis 實例的 ip、端口和密碼等信息

TIPS

建議在 main 函數(shù)外面新建 Redis 客戶端實例,這樣在函數(shù)實例被復(fù)用時不會重復(fù)連接 Redis ,性能更好

在 main 函數(shù)中可通過 redis.get、redis.set 等方法讀取和寫入數(shù)據(jù),具體可以查看 ioredis 的 API 文檔

const Redis = require('ioredis');
// 建議在 main 函數(shù)外面新建 Redis 客戶端實例
// 這樣在函數(shù)實例被復(fù)用時不會重復(fù)連接 Redis
const redis = new Redis({
  port: 6379, // Redis port
  host: 'YOUR_REDIS_IP', // Redis host
  family: 4, // 4 (IPv4) or 6 (IPv6)
  password: 'YOUR_PASSWORD',
  db: 0,
});

// 云函數(shù)入口函數(shù)
exports.main = async (event, context) => {
  // TODO 可以使用 redis.get、redis.set 等方法來操作 Redis
};

示例:云函數(shù)中使用 Redis 作為緩存

我們現(xiàn)在來實際演示下一下如何在云函數(shù)中使用 Redis 作為緩存

我們需要新建一個名為 redis-demo 的云函數(shù) ,該函數(shù)的主要實現(xiàn)是:

  • 連接部署在同一個私有網(wǎng)絡(luò)的 Redis
  • 在用戶請求云函數(shù)時,會首先用用戶的 openid 作為 key 來從 Redis 中查詢是否有緩存
  • 如果有緩存則直接返回
  • 沒有緩存,則會執(zhí)行一個函數(shù)來拿到結(jié)果,我們這里模擬了一個耗時 2s 的操作來返回一個隨機數(shù)作為示例,拿到結(jié)果之后,會緩存在 Redis 中并返回

示例函數(shù)代碼

// 云函數(shù)入口文件
const cloud = require('wx-server-sdk');
const Redis = require('ioredis');

cloud.init();

const redis = new Redis({
  port: 6379, // Redis port
  host: 'YOUR_REDIS_IP', // Redis host
  family: 4, // 4 (IPv4) or 6 (IPv6)
  password: 'YOUR_PASSWORD',
  db: 0,
});

// 云函數(shù)入口函數(shù)
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext();
  const cacheKey = wxContext.OPENID;

  const cache = await redis.get(cacheKey);

  if (!cache) {
    const result = await new Promise((resolve, reject) => {
      // 模擬一個耗時 2s 的任務(wù),返回了一個隨機數(shù)
      setTimeout(() => resolve(Math.random()), 2000);
    });

    // 緩存一小時
    redis.set(cacheKey, result, 'EX', 3600);
    return result;
  } else {
    return cache;
  }
};

編寫完代碼之后,我們需要上傳并部署 redis-demo 函數(shù),然后嘗試在小程序中調(diào)用這個云函數(shù)來測試一下效果:

20191206105847.png

我們可以看到,由于使用了 Redis 作為緩存,在多次的調(diào)用云函數(shù)請求中,在 300 ms 左右都可以獲取到函數(shù)的結(jié)果,函數(shù)返回的結(jié)果正是我們緩存的隨機數(shù),符合預(yù)期的效果。

總結(jié)

如果有需要訪問云開發(fā)之外的騰訊云資源,可以選擇使用私有網(wǎng)絡(luò)這種網(wǎng)絡(luò)模式,將云開發(fā)資源如函數(shù)和其他資源放在同一個私有網(wǎng)絡(luò)即可,私有網(wǎng)絡(luò)相比基礎(chǔ)網(wǎng)絡(luò)更加安全和靈活。本文雖然只演示了在函數(shù)中使用騰訊云的 Redis 資源,如果需要訪問騰訊云的其他的數(shù)據(jù)庫資源,思路也是一樣的,只需要將函數(shù)和數(shù)據(jù)庫資源放在同一個私有網(wǎng)絡(luò),就可以在函數(shù)中訪問。

通過私有網(wǎng)絡(luò)還可以實現(xiàn)對公網(wǎng)訪問服務(wù)、實現(xiàn)和騰訊云之外的 IDC 互聯(lián)等功能,關(guān)于這部分的介紹,我們后續(xù)進行講解。


關(guān)于我

binggg(Booker Zhao) @騰訊

- 先后就職于迅雷、騰訊等,個人開源項目有 mrn.js 等
- 創(chuàng)辦了迅雷內(nèi)部組件倉庫 XNPM ,參與幾個迅雷前端開源項目的開發(fā)
- 熱衷于優(yōu)化和提效,是一個奉行“懶惰使人進步”的懶人工程師

社交資料

微信公眾號 binggg_net, 歡迎關(guān)注

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容