practice - redis를 이용한 캐시 서버 구현 및 성능 테스트

백근영·2019년 10월 27일
0

practice

목록 보기
3/20
post-thumbnail

1. 10초 후 만료되는 캐시 구현하기

index.js

app.post('/profile', (req, res, next) => {
    req.accepts('application/json');

    const key = req.body.name;
    const value = JSON.stringify(req.body);

    req.cache.set(key, value, (err,data) => {
        if(err){
            console.log(err);
            res.send("error :" + err);
            return;
        }

        req.cache.expire(key, 10);
        res.json(value);
        //console.log(value);
    });
});

app.get('/profile/:name', (req, res, next) => {
    const key = req.params.name;
    console.log('name : ' + key);

    req.cache.get(key, (err, data) => {
        if(err){
            console.log(err);
            res.send("error : " + err);
            return;
        }

        const value = JSON.parse(data);
        res.json(value);
    });
});

/profile/에 post 요청을 통해 데이터를 보낼 때마다 이 값을 redis server에 저장하도록 하고,
만료되는 시간제한을 10초로 설정함.

테스트 결과 post 요청을 보낸 후 10초가 지나기 전에 /profile/:name 라우트에 get 요청을 보내면
적절한 값을 받아올 수 있고, 10초 후에 다시 get 요청을 보내보면 null을 반환함.

2 . redis를 썼을 때와 쓰지 않았을 때 성능 비교하기

mongoDB에 1000개의 document를 생성한 후, 이를 그대로 받아오는 api를 만들어 성능을 테스트함.

2-1. redis cache를 사용하지 않는 api

app.get('/view', async (req, res) => {
    const allData = await Profile.find().lean().exec();
    res.send(allData)
});

2-2. redis cache를 사용하는 api

app.get('/view_redis', (req, res) => {
    req.cache.get('profiles', async (err, data) => {
        if(err){
            console.log(err);
            res.send("error : " + err);
            return;
        }

        if(!data) {
            const allData = await Profile.find().lean().exec();
            const dataArr = JSON.stringify(allData);
            req.cache.set('profiles', dataArr, (err, data) => {
                if(err){
                    console.log(err);
                    res.send("error :" + err);
                    return;
                }

                req.cache.expire('profiles', 10);
                res.send(dataArr)
            })
        }

        else {
            res.send(data)
        }
    });
});

특정 주소로 여러 번의 요청을 보내서 서버가 얼마나 잘 요청을 처리해내는지를 테스트하는 loadtest라는 프로그램을 이용해
위 두 api의 성능을 각각 테스트해본다.

[Tue Oct 22 2019 18:18:46 GMT+0900 (GMT+09:00)] INFO Requests: 0 (0%), requests per second: 0, mean latency: 0 ms
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Target URL:          http://localhost:3000/view
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Max requests:        100
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Concurrency level:   1
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Agent:               none
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Completed requests:  100
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Total time:          0.8381079 s
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Requests per second: 119
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Mean latency:        8.3 ms
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO Percentage of the requests served within a certain time
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO   50%      6 ms
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO   90%      7 ms
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO   95%      8 ms
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO   99%      141 ms
[Tue Oct 22 2019 18:18:47 GMT+0900 (GMT+09:00)] INFO  100%      141 ms (longest request)

(↑ redis 사용하지 않는 api 성능)

[Tue Oct 22 2019 18:19:17 GMT+0900 (GMT+09:00)] INFO Requests: 0 (0%), requests per second: 0, mean latency: 0 ms
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Target URL:          http://localhost:3000/view_redis
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Max requests:        100
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Concurrency level:   1
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Agent:               none
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Completed requests:  100
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Total errors:        0
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Total time:          0.3754709 s
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Requests per second: 266
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Mean latency:        3.7 ms
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO Percentage of the requests served within a certain time
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO   50%      2 ms
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO   90%      3 ms
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO   95%      3 ms
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO   99%      108 ms
[Tue Oct 22 2019 18:19:18 GMT+0900 (GMT+09:00)] INFO  100%      108 ms (longest request)

(↑ redis 사용하는 api 성능)

결과 : redis cache를 사용하는 api가 약 두 배 정도 빠른 실행속도를 보였음.

주의할 점

redis를 사용할 시, redis cache에 있는 데이터와 실제 DB에 있는 데이터가 항상 같음을 보장할 수 없다.
cache server를 사용할 때는 성능에 앞서 기능에 문제가 없는 지를 철저히 확인하고 사용해야 한다.

profile
서울대학교 컴퓨터공학부 github.com/BaekGeunYoung

0개의 댓글