Node-redis: Cara efisien untuk menghapus kunci berdasarkan pola

Dibuat pada 5 Mar 2018  ·  12Komentar  ·  Sumber: NodeRedis/node-redis

Saya sedang mengerjakan proyek besar dan di beberapa tempat, saya harus menghapus kunci dengan pola, misalnya, saya ingin menghapus semua kunci yang dimulai dengan filterProducts

Saya melakukan pencarian Google dan menemukan beberapa metode untuk melakukannya seperti, misalnya, metode dalam artikel ini

Tapi saya tidak tahu apa yang efisien untuk proyek besar, bisakah Anda membantu saya?

  • Versi : 2.8.0
  • Platform : Linux Mint 18.2 (Dibangun di Ubuntu 16.04)

Komentar yang paling membantu

Bagi siapa saja yang mencari hasil akhir yang sampai sekarang kami capai dan percaya itu adalah cara yang paling efisien adalah sebagai berikut:

//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);
        }
    });
}

Kode di atas adalah untuk ioredis .
Tolong jika Anda adalah seseorang yang tahu cara yang lebih baik untuk melakukannya, jangan ragu untuk berbagi.

Semua 12 komentar

Metode yang Anda tautkan adalah cara yang sangat buruk untuk melakukannya. KEYS tidak dapat digunakan untuk produksi dan DEL juga sangat tidak efisien. Saya akan memeriksa menggunakan SCAN dan UNLINK . Dengan cara ini Anda dapat menghapus beberapa kunci sekaligus tanpa mengikat Redis.

Semua itu dikatakan, jenis skrip itu terserah Anda dan di luar cakupan pustaka klien. Saya akan menutup masalah ini.

@MohammedAl-Mahdawi Saya memiliki kasus penggunaan serupa di salah satu proyek saya dan menggunakan implementasi scanStream ditawarkan oleh ioredis. Ini pada dasarnya adalah cara yang lebih mudah untuk menggunakan perintah scan : https://github.com/luin/ioredis#streamify -scanning

Jika Anda menggunakan SCAN dan UNLINK seperti yang telah disebutkan @stockholmux , Anda seharusnya dapat menghapus sejumlah kunci tanpa memblokir Redis.

@dirkbonhomme Terima kasih banyak atas bantuan Anda, saya sangat menghargai itu.

Saya mengikuti saran Anda dan menggunakan ioredis dan membuat fungsi-fungsi berikut, bisakah Anda memberi tahu saya untuk proyek-proyek besar berikut ini cara paling efisien untuk melakukannya atau tidak:

//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 terlihat baik bagi saya. Satu-satunya masalah yang mungkin adalah Anda akan memuat semua kunci yang cocok ke dalam memori sekaligus. Jika itu masalah, Anda dapat menghapusnya dalam batch segera setelah mereka masuk:

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

@dirkbonhomme dan @MohammedAl-Mahdawi Metode ini memiliki masalah atom yang dapat menggigit Anda dalam produksi.

@stockholmux Terima kasih atas bantuan Anda, jadi apa solusi yang tepat untuk masalah ini?

Bagi siapa saja yang mencari hasil akhir yang sampai sekarang kami capai dan percaya itu adalah cara yang paling efisien adalah sebagai berikut:

//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);
        }
    });
}

Kode di atas adalah untuk ioredis .
Tolong jika Anda adalah seseorang yang tahu cara yang lebih baik untuk melakukannya, jangan ragu untuk berbagi.

@MohammedAl-Mahdawi ,
saya mendapatkan kesalahan ini, ada ide tentang hal yang sama
basis kode:

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

adakah yang memberikan solusi sempurna di sini?

@siddhkadam1881 Perintah unlink hanya tersedia sejak Redis 4 https://redis.io/commands/unlink
Anda mungkin menjalankan versi yang lebih lama. Coba del sebagai gantinya.

Saya ingin memahami bagaimana pemindaian dilakukan?. Saya pikir dalam solusi oleh @MohammedAl-Mahdawi jika penghapusan terjadi secara berkelompok, apakah ada kemungkinan bahwa kunci baru yang ditambahkan pada waktu itu yang tidak ingin kami hapus, akan dipindai dan dihapus. Bagaimana dengan skrip lua?

Adakah yang punya ide mengapa solusi ini tidak berfungsi pada server ElastiCache 1 instance yang sangat sederhana, tetapi apakah berfungsi secara lokal? Saya dapat menghapus kunci secara normal, tetapi jika saya mencoba menggunakan implementasi aliran, itu tidak pernah mengembalikan kunci apa pun pada ElastiCache.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

yuany picture yuany  ·  4Komentar

strumwolf picture strumwolf  ·  4Komentar

jackycchen picture jackycchen  ·  4Komentar

ghost picture ghost  ·  3Komentar

michaelwittig picture michaelwittig  ·  3Komentar