Node-redis: ํŒจํ„ด์œผ๋กœ ํ‚ค๋ฅผ ์‚ญ์ œํ•˜๋Š” ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•

์— ๋งŒ๋“  2018๋…„ 03์›” 05์ผ  ยท  12์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: NodeRedis/node-redis

์ €๋Š” ํฐ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ์ค‘์ด๊ณ  ์–ด๋–ค ๊ณณ์—์„œ๋Š” ํŒจํ„ด์œผ๋กœ ํ‚ค๋ฅผ ์‚ญ์ œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด filterProducts ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ํ‚ค๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

Google ๊ฒ€์ƒ‰์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ด ๊ธฐ์‚ฌ ์˜ ๋ฐฉ๋ฒ•๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ํฐ ํ”„๋กœ์ ํŠธ์— ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ด ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ €๋ฅผ ๋„์™€์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

  • ๋ฒ„์ „ : 2.8.0
  • ํ”Œ๋žซํผ : Linux Mint 18.2(Ubuntu 16.04 ๊ธฐ๋ฐ˜)

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ๋„๋‹ฌํ•œ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ์ฐพ๊ณ  ๊ทธ๊ฒƒ์ด ๊ฐ€์žฅ ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ๋ฏฟ๋Š” ์‚ฌ๋žŒ์„ ์œ„ํ•ด ๋‹ค์Œ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

//key example "prefix*"
function getKeysByPattern(key) {
    return new Promise((resolve, reject) => {
        var stream = redis.scanStream({
            // only returns keys following the pattern of "key"
            match: key,
            // returns approximately 100 elements per call
            count: 100
        });

        var keys = [];
        stream.on('data', function (resultKeys) {
            // `resultKeys` is an array of strings representing key names
            for (var i = 0; i < resultKeys.length; i++) {
                keys.push(resultKeys[i]);
            }
        });
        stream.on('end', function () {
            resolve(keys)
        });
    })
}

//key example "prefix*"
function deleteKeysByPattern(key) {
    var stream = redis.scanStream({
        // only returns keys following the pattern of "key"
        match: key,
        // returns approximately 100 elements per call
        count: 100
    });

    var keys = [];
    stream.on('data', function (resultKeys) {
        // `resultKeys` is an array of strings representing key names
        for (var i = 0; i < resultKeys.length; i++) {
            keys.push(resultKeys[i]);
        }
    });
    stream.on('end', function () {
        redis.unlink(keys)
    });
}

//key example "prefix*"
function batchDeletionKeysByPattern(key) {
    var stream = redis.scanStream({
        // only returns keys following the pattern of "key"
        match: key,
        // returns approximately 100 elements per call
        count: 100
    });

    stream.on('data', function (resultKeys) {
        if (resultKeys.length) {
            redis.unlink(resultKeys);
        }
    });
}

์œ„์˜ ์ฝ”๋“œ๋Š” ioredis์šฉ ์ž…๋‹ˆ๋‹ค.
๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ๊ณ„์‹  ๋ถ„์ด ๊ณ„์‹œ๋‹ค๋ฉด ์ฃผ์ €ํ•˜์ง€ ๋ง๊ณ  ๊ณต์œ ํ•ด ์ฃผ์‹ญ์‹œ์˜ค.

๋ชจ๋“  12 ๋Œ“๊ธ€

๋‹น์‹ ์ด ๋งํฌ ํ•œ ๋ฐฉ๋ฒ•์€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๊ฝค ๋”์ฐํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. KEYS ๋Š” ํ”„๋กœ๋•์…˜์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ DEL๋„ ์ƒ๋‹นํžˆ ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. SCAN ๋ฐ UNLINK ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Redis๋ฅผ ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ ๋„ ํ•œ ๋ฒˆ์— ์†Œ์ˆ˜์˜ ํ‚ค๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฆ‰, ํ•ด๋‹น ์œ ํ˜•์˜ ์Šคํฌ๋ฆฝํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@MohammedAl-Mahdawi ๋‚ด ํ”„๋กœ์ ํŠธ ์ค‘ ํ•˜๋‚˜์— ๋น„์Šทํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ์œผ๋ฉฐ ioredis์—์„œ ์ œ๊ณตํ•˜๋Š” scanStream ๊ตฌํ˜„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ scan ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋Š” ๋” ์‰ฌ์šด ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค: https://github.com/luin/ioredis#streamify -scanning

์ด๋ฏธ ์–ธ๊ธ‰ํ•œ @stockholmux ์™€ ๊ฐ™์ด SCAN ๋ฐ UNLINK ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ Redis๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ์›ํ•˜๋Š” ์ˆ˜์˜ ํ‚ค๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@dirkbonhomme ๋„์™€ ์ฃผ์…”์„œ ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์˜ ์กฐ์–ธ์„ ๋”ฐ๋ฅด๊ณ  ioredis๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ํฐ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ€์žฅ ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ธ์ง€ ์•Œ๋ ค์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

//key example "prefix*"
function getKeysByPattern(key) {
    return new Promise((resolve, reject) => {
        var stream = redis.scanStream({
            // only returns keys following the pattern of "key"
            match: key,
            // returns approximately 100 elements per call
            count: 100
        });

        var keys = [];
        stream.on('data', function (resultKeys) {
            // `resultKeys` is an array of strings representing key names
            for (var i = 0; i < resultKeys.length; i++) {
                keys.push(resultKeys[i]);
            }
        });
        stream.on('end', function () {
            resolve(keys)
        });
    })
}

//key example "prefix*"
function deleteKeysByPattern(key) {
    var stream = redis.scanStream({
        // only returns keys following the pattern of "key"
        match: key,
        // returns approximately 100 elements per call
        count: 100
    });

    var keys = [];
    stream.on('data', function (resultKeys) {
        // `resultKeys` is an array of strings representing key names
        for (var i = 0; i < resultKeys.length; i++) {
            keys.push(resultKeys[i]);
        }
    });
    stream.on('end', function () {
        redis.unlink(keys)
    });
}

@MohammedAl-Mahdawi๋Š” ๋‚˜์—๊ฒŒ ์ข‹์•„ ๋ณด์ธ๋‹ค. ๊ฐ€๋Šฅํ•œ ๋ฌธ์ œ๋Š” ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ํ‚ค๋ฅผ ํ•œ ๋ฒˆ์— ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋“œํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋ฌธ์ œ๋ผ๋ฉด, ๊ทธ๊ฒƒ๋“ค์ด ๋“ค์–ด์˜ค๋Š” ์ฆ‰์‹œ ์ผ๊ด„์ ์œผ๋กœ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

stream.on('data', function (resultKeys) {
        if (resultKeys.length) {
              redis.unlink(resultKeys);
        }
    });

@dirkbonhomme ๋ฐ @MohammedAl-Mahdawi ์ด ๋ฐฉ๋ฒ•์—๋Š” ํ”„๋กœ๋•์…˜์—์„œ ์‚ฌ์šฉ์ž๋ฅผ ๋ฌผ๋ฆด ์ˆ˜ ์žˆ๋Š” ์›์ž์„ฑ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@stockholmux ๋„์›€์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ํ•ด๊ฒฐ์ฑ…์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ๋„๋‹ฌํ•œ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ์ฐพ๊ณ  ๊ทธ๊ฒƒ์ด ๊ฐ€์žฅ ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ๋ฏฟ๋Š” ์‚ฌ๋žŒ์„ ์œ„ํ•ด ๋‹ค์Œ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

//key example "prefix*"
function getKeysByPattern(key) {
    return new Promise((resolve, reject) => {
        var stream = redis.scanStream({
            // only returns keys following the pattern of "key"
            match: key,
            // returns approximately 100 elements per call
            count: 100
        });

        var keys = [];
        stream.on('data', function (resultKeys) {
            // `resultKeys` is an array of strings representing key names
            for (var i = 0; i < resultKeys.length; i++) {
                keys.push(resultKeys[i]);
            }
        });
        stream.on('end', function () {
            resolve(keys)
        });
    })
}

//key example "prefix*"
function deleteKeysByPattern(key) {
    var stream = redis.scanStream({
        // only returns keys following the pattern of "key"
        match: key,
        // returns approximately 100 elements per call
        count: 100
    });

    var keys = [];
    stream.on('data', function (resultKeys) {
        // `resultKeys` is an array of strings representing key names
        for (var i = 0; i < resultKeys.length; i++) {
            keys.push(resultKeys[i]);
        }
    });
    stream.on('end', function () {
        redis.unlink(keys)
    });
}

//key example "prefix*"
function batchDeletionKeysByPattern(key) {
    var stream = redis.scanStream({
        // only returns keys following the pattern of "key"
        match: key,
        // returns approximately 100 elements per call
        count: 100
    });

    stream.on('data', function (resultKeys) {
        if (resultKeys.length) {
            redis.unlink(resultKeys);
        }
    });
}

์œ„์˜ ์ฝ”๋“œ๋Š” ioredis์šฉ ์ž…๋‹ˆ๋‹ค.
๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ๊ณ„์‹  ๋ถ„์ด ๊ณ„์‹œ๋‹ค๋ฉด ์ฃผ์ €ํ•˜์ง€ ๋ง๊ณ  ๊ณต์œ ํ•ด ์ฃผ์‹ญ์‹œ์˜ค.

@MohammedAl-Mahdawi ,
๋‚˜๋Š”์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์•„์ด๋””์–ด
์ฝ”๋“œ๋ฒ ์ด์Šค:

let redisDel = () => {
    var key="employees*"

    return new Promise((resolve, reject) => {

        var stream = redis.scanStream({
            // only returns keys following the pattern of "key"
            match: key,
            // returns approximately 100 elements per call
            count: 100
        });

        stream.on('data', function (resultKeys) {
            if (resultKeys.length) {
                console.log(resultKeys)
                redis.unlink(resultKeys);
            }
        });
        stream.on('end', function (resultKeys) {
            resolve()
        })

    })
}

screenshot from 2019-03-05 19 28 10

์•„๋ฌด๋„ ์—ฌ๊ธฐ์— ์™„๋ฒฝํ•œ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๊นŒ?

@siddhkadam1881 ๋งํฌ ํ•ด์ œ ๋ช…๋ น์€ Redis 4 https://redis.io/commands/unlink ์ดํ›„๋กœ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„๋งˆ๋„ ์ด์ „ ๋ฒ„์ „์„ ์‹คํ–‰ ์ค‘์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹  del ๋ฅผ) ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค.

์Šค์บ”์ด ์–ด๋–ป๊ฒŒ ์ˆ˜ํ–‰๋˜๋Š”์ง€ ์ดํ•ดํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์‚ญ์ œ๊ฐ€ ์ผ๊ด„ ์ฒ˜๋ฆฌ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ @MohammedAl-Mahdawi์˜ ์†”๋ฃจ์…˜์—์„œ ์‚ญ์ œํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ์ƒˆ ํ‚ค๊ฐ€ ๊ทธ ์‹œ๊ฐ„์— ์ถ”๊ฐ€๋˜๋ฉด ์Šค์บ” ๋ฐ ์‚ญ์ œ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ฃจ์•„ ์Šคํฌ๋ฆฝํŠธ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ด ์†”๋ฃจ์…˜์ด ๋งค์šฐ ๊ฐ„๋‹จํ•œ 1 ์ธ์Šคํ„ด์Šค ElastiCache ์„œ๋ฒ„์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์ง€๋งŒ ๋กœ์ปฌ์—์„œ๋Š” ์ž‘๋™ํ•˜๋Š” ์ด์œ ๋ฅผ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ •์ƒ์ ์œผ๋กœ ํ‚ค๋ฅผ ์ง€์šธ ์ˆ˜ ์žˆ์ง€๋งŒ ์ŠคํŠธ๋ฆผ ๊ตฌํ˜„์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ElastiCache์—์„œ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰

๊ด€๋ จ ๋ฌธ์ œ

Atala picture Atala  ยท  3์ฝ”๋ฉ˜ํŠธ

yuany picture yuany  ยท  4์ฝ”๋ฉ˜ํŠธ

strumwolf picture strumwolf  ยท  4์ฝ”๋ฉ˜ํŠธ

id0Sch picture id0Sch  ยท  4์ฝ”๋ฉ˜ํŠธ

Mickael-van-der-Beek picture Mickael-van-der-Beek  ยท  6์ฝ”๋ฉ˜ํŠธ