Coding Hero

We solve your problems

Node.Js 使用 Redis 優化效能

2019-10-14 Briannode js

redis.png


最近在開發上,需要處理大量前端 request,也算是第一次要設計 to client 的專案,查詢資料庫可能會變得更加頻繁。

這時!腦海中浮現快取,cache,當我首次寫 Node.js 後端時,只知道要去資料庫去撈資料,毫不留情地做巢狀查詢, 吐給前端的同事,但他一直在喊要快取,蛤要快取什麼?找我麻煩膩!

我在程式碼不留餘地的使用對資料庫的操作語法,看似達成目的,果不巧資料才幾百筆就出現效能低落。

那如果同時百萬人都在對資料庫在查詢,那我的程式不就…


Why Redis?


當下使用 node-cache 套件處理,在查詢前檢查 cache 是否存在? 我所查到的結果是 你也正在使用內存

但在這次開發上,為了可擴展,就暫且掛上 Redis Server 試試看吧!


我對 Redis 的認知


  • 存 key value,而且還支援 list,set,zset,hash。
  • 記憶體快取,能夠減輕對資料庫的負擔。

快速上手


首先安裝 Redis:

$ brew install redis

啟動 Redis server:

$ redis-server

開啟 Redis CLI:

$ redis-cli

在專案安裝 Redis:

$ npm install redis

Node.js 連線到 Redis:

import redis from "redis"

const host = REDIS_SERVER
const port = REDIS_PORT || 6379

const cache = redis.createClient(port, host)

cache.on("error", err => {
  console.log(err)
})

寫入/讀取 Redis:

const cacheData = {
  id: 1,
  name: Brian,
  company: {
    id: "c1",
    name: "4idps"
  }
}

// 寫入
const key = cacheData.id
cache.set(key, JSON.stringify(cacheData))
// 寫入hash map set
cache.hmset("short", { js: "javascript", cs: "c sharp" })
cache.hmset("short", "html", "hyperText")

// 讀取
cache.get(key, (err, results) => {
  console.log(results)
})
// 讀取hash get
cache.hgetall("short", (err, results) => {
  console.log(results)
})

Apollo Server 使用 redis cache 處理


編輯 Apollo Server 的參數:

import { RedisCache } from('apollo-server-cache-redis')

const server = new ApolloServer({
  typeDefs,
  resolvers,
  cache: new RedisCache({
    host: REDIS_SERVER,
    // Options are passed through to the Redis client
  })
})

總結


實作 Redis 非常簡單,只要 run Redis server 跟設定 key value 即可。開發中大型專案建議可以使用 Redis,增加擴展性,使用排程定時更新暫存快取,開 API 接口直接吐出 Redis 取得的快取,降低 request 對資料庫操作的負擔。

但也要記得快取資料是否與你真實的存在資料相符,快取也應該注意快取時間,根據資料是否變動頻率來決定,這些眉角都應注意。


參考


https://github.com/NodeRedis/node_redis