Heroku Redis 사용하기

Jiyun Park·2022년 6월 3일
0

MERN 스택을 사용하는 프로젝트를 조금 더 최적화하기 위해 redis를 사용하기로 하였다. 다행히 서버를 호스팅해주는 Heroku에서 redis 기능도 지원해서 쉽게(?) 추가할 수 있었다.

다음 3가지 레퍼런스를 참고하여 Heroku에 redis를 추가하고 Nodejs와 연결하였다. 각 레퍼런스에 방법이 자세히 나와있으니 참고하면 좋다.

1. hsik0225님의 github: [Heroku] Redis 사용하기
2. npm: node-redis
3. Heroku Dev Center: Connecting to Heroku Redis

팁이 있다면,
먼저 localhost에서 redis에 값이 잘 저장되는지, 에러가 나지는 않는지 테스트를 먼저 해본 후 heroku redis에 연결하는 것을 추천한다. Heroku로 업로드하는데도 은근 시간이 걸리고 에러가 localhost에서 돌릴 때처럼 직관적으로 콘솔에 찍히지 않기 때문에 개인적으로 좀 불편하다고 느꼈다.

또한, 아래와 같은 command로 Heroku의 Redis에 접근할 수 있어서 실제로 값이 잘 저장되고 있는지 확인할 수 있다.

$ heroku redis:cli -a <app_name>

끝으로, 혹시 도움이 될까 싶어 우리 프로젝트에서 Heroku redis와 관련된 코드를 첨부한다.

node의 index.js

// localhost에서 redis를 띄울 때 사용 (localhost:6379)
// const redis_client = redis.createClient();

// Heroku에서 redis를 띄울 때 사용
const redis_client = redis.createClient({url: process.env.REDIS_URL});

redis_client.on('error', (err) => console.log('Redis Client Error', err));

await redis_client.connect();

// test용: redis에 임의의 값 set
await redis_client.set('key', 'value');
const value = await redis_client.get('key');
console.log(value);

// 다른 파일에서도 redis_client를 사용하기 위해 export
export default redis_client;

node의 controller

import PostSelection from "../models/postSelection.js";
import redis_client from "../index.js";


// count값을 구하는 함수
export const getCount = async (req, res) => {
    try {
        // redis에 key가 count인 값이 있는지 확인
        const data = await redis_client.get('count');
        // 있다면 value를 response로 보내기
        if (data != null) {
            console.log("Get the count value in redis!"); 
            res.status(200).json(parseInt(data) + 1);
        } else {	// 없다면 db에서 값 불러오기
            try {
                const count = await PostSelection.find().count();
                
                // 200: OK
                res.status(200).json(count);
                console.log("GET count DONE! : ", count); 
              	// redis에 count값 저장
                await redis_client.set('count', count);
                console.log("Save the count value in redis!"); 
            } catch (error) {
                // 404: Not Found
                res.status(404).json({ message: error.message });
                console.log(error.message);
            }
        }

    } catch (error) {
        // 404: Not Found
        res.status(404).json({ message: error.message });
        console.log(error.message);
    }
}


// post를 db에 저장하는 함수
export const createPosts = async (req, res) => {
    const post = req.body;
    const newPost = new PostSelection(post);

    try {
        await newPost.save();

        // 201: created
        res.status(201).json(newPost);
        console.log("POST DONE!"); 

        // redis에 key가 count인 값이 있다면 count + 1로 업데이트 해준다 (본 함수는 post가 하나 추가되는 함수이기 때문)
        try {
            const count = await redis_client.get('count');
            if (count != null) {
                await redis_client.set('count', parseInt(count) + 1);
                console.log("Update count in redis!", parseInt(count) + 1); 
            }
        } catch (error) {
            // 404: Not Found
            res.status(404).json({ message:  "Couldn't get the redis value when create the post. " + error.message });
            console.log(error.message);
        }
       
    } catch (error) {
        // 409: Conflict
        res.status(409).json({ message: error.message });
        console.log(error.message);
    }

}

0개의 댓글