iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
DevOps

其實沒有那麼難 — Docker系列 第 20

D20 - 團隊觀戰區爬蟲 v4 ft. Redis

  • 分享至 

  • xImage
  •  

今天繼續來把我們的玩具爬蟲加入新的元素

D17 - 團隊觀戰區爬蟲 v3 ft. AWS S3 時,我們把爬蟲的結果上傳到 S3,作為一種減少爬蟲次數的解法,並讓 S3 來替我們扛流量,

那如果我只是想要減少爬蟲次數,但依然開 API 讓 Client 使用、而不是上傳到其他地方的話,可以怎麼做呢?

我們可以加入 Cache 的機制,把結果暫存起來繼續使用,
就讓我們來看看要怎麼做。


Cache

什麼是 Cache 的機制?

當我們的爬蟲,每次爬完資料後,就先把結果暫存到 Cache,
當下一次 Request 進來時,會先檢查 Cache 內是不是有我要的資料,如果沒有,才會重新執行爬蟲,

藉著 Cache 的機制,我們可以讓爬蟲爬回來的結果不是僅限於單次的 Response,而是可以被重複使用,

另外,稍微釐清一點,有時,CacheCache 機制 並不完全相等,
Cache 有時指的是 CPU快取記憶體,是電腦中用來加速的一個硬體零件,
Cache 機制則是廣泛地指把會常用的資料暫存起來供重複利用,以達到加速或節省資源的方式。


Redis

說到 Cache 的工具,Redis 幾乎是最知名的,

可以把它想成是一個很快的 Server、Database、或單純的一張表,
寫入索引跟要儲存的值,下次查找時則輸入索引,看是否存在值,

除了暫存以外,Redis 會把資料放在電腦的記憶體內,使儲存跟查找的速度非常快,
但同時,當伺服器 (或開發電腦) 關機後,Redis 中的資料就會遺失,

因此,Redis 這樣的工具是來強化效能、加速用的,
關鍵的資料請避免放在 Redis,而是要放在資料庫。


爬蟲 v4

接下來,讓我們直接送上,加入了 Redis 的程式碼:

每次 Request 進來時,會先檢查 Cache,
如果有 Cache,就直接回傳,
如果沒有 Cache,就執行爬蟲,並把爬蟲結果寫回 Cache,

我把 Cache 設定為 1 分鐘就會過期,也就是,在一分鐘後,下一個 Request 就會需要重新爬蟲,抓取最新的鐵人賽資料。

// src/router.js

import Router from 'express';
import { createClient } from 'redis';
import { getMembersWithPostInfo } from './ithelp-crawler.js';


const router = Router();

const client = createClient({
	url: process.env.REDIS_URL,
});


router.get('/team/:teamId/members', async (req, res) => {
	const teamId = parseInt(req.params.teamId);
	if (!Number.isInteger(teamId)) {
		return res.status(400).json({
			error: 'teamId is not an integer'
		});
	}

	await client.connect();
	const cacheKey = `team_${teamId}`;
	const cache = await client.get(cacheKey);

	const members = cache
		? JSON.parse(cache)
		: await getMembersWithPostInfo(teamId);
	
	await client.setEx(cacheKey, 20, JSON.stringify(members));

	await client.disconnect();
	return res.json({ data: members });
});

export default router;

Docker Compose

依然透過方便的 Docker compose 來定義 container:

# docker-compose.yml

version: "3"
services:
  redis:
    image: redis

  crawler:
    build: .
    ports:
      - 3000:3000
    environment:
      - REDIS_URL=redis://redis

執行:

$ sudo docker compose up -d

接著就可以使用我們的 API 了,
一樣,如果是雲端平台,記得要在後台打開 Server 的防火牆,

Redis

好的,我們的玩具箱越來越豐富了,那今天就到這邊。


上一篇
D19 - 建立 Image manifest
下一篇
D21 - PHP 指定版本的開發環境 ft. Laravel
系列文
其實沒有那麼難 — Docker30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言