AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79003549
Accepted
mark
mark
Asked: 2024-09-20 00:20:21 +0800 CST2024-09-20 00:20:21 +0800 CST 2024-09-20 00:20:21 +0800 CST

Por que o Redis SCAN retornaria um resultado vazio quando o mesmo padrão usado com KEYS retorna algo?

  • 772

O comando KEYS retorna alguns resultados:

> keys Types/*/*BackgroundJob.json
1) "Types/Xyz.Data/Xyz.Data.BackgroundJobEngine.BackgroundJob.json"
2) "Types/Xyz.Web.SystemAdmin/Xyz.Web.SystemAdmin.Models.Encryption.EncryptionMethodByBackgroundJob.json"
3) "Types/BackgroundJobs/SharpTop.Engine.BackgroundJobs.AutofillBackgroundJob.json"
4) "Types/Quartz.Server/BJE.UDT.BackgroundJob.json"
5) "Types/DFControllersTest.Compensation/DFControllersTest.Compensation.SubmitCompensationPublishBackgroundJob.json"
6) "Types/SpecFlowTest.Architecture.Base/SpecFlowTest.Architecture.Base.Model.IntStudioConfigBackgroundJob.json"
7) "Types/SpecFlowTest.Benefits.UI/SpecFlowTest.Benefits.UI.Base.Services.BackgroundJobsService+BackgroundJob.json"
8) "Types/Xyz.WFM.ExpressionService.Client/Xyz.WFM.ExpressionService.Client.BackgroundJob.ExpressionManagerBackgroundJob.json"
9) "Types/DFControllersTest.Compensation/DFControllersTest.Compensation.SubmitGenerateBudgetWorksheetBackgroundJob.json"
10) "Types/DFControllersTest.Compensation/DFControllersTest.Compensation.SubmitCompensationUnPublishBackgroundJob.json"
11) "Types/IntegrationStudio/IntegrationStudio.DAL.Entities.IntStudioConfigBackgroundJob.json"
12) "Types/IntegrationStudio/IntegrationStudio.DAL.Entities.BackgroundJob.json"

Mas o SCAN usando o mesmo padrão não retorna nenhum:

> scan 0 match Types/*/*BackgroundJob.json
1) "1966080"
2) (empty list or set)

Tentei seguir o valor do cursor retornado por várias iterações, mas sem um script para verificá-lo, parece uma série interminável de resultados vazios.

O que está acontecendo?

Editar 1

Finalmente decidi codificá-lo:

private async IAsyncEnumerable<string> QueryRedisAsync(string pattern, [EnumeratorCancellation] CancellationToken ct = default)
{
    var db = connection.GetDatabase();
    var cursor = "0";
    int count = 0;
    do
    {
        ++count;
        ct.ThrowIfCancellationRequested();

        var tmp = await db.ExecuteAsync("SCAN", cursor, "MATCH", pattern, "COUNT", "1000");
        var scanResult = (RedisResult[])tmp;
        cursor = scanResult[0].ToString();
        var keys = (RedisKey[])scanResult[1];

        foreach (var key in keys)
        {
            yield return key.ToString();
        }
    } 
    while (cursor != "0");
    Console.WriteLine(count);
}

O código executou 1058 (!) iterações onde exatamente uma correspondência foi encontrada em alguma iteração, a saber:

  1. 173
  2. 189
  3. 242
  4. 351
  5. 416
  6. 473
  7. 590
  8. 912
  9. 975
  10. 983
  11. 998
  12. 1027

Então, eu usei SCANpara ser "legal" e isso causou 1058 viagens de ida e volta para o servidor.

Estou fazendo algo errado?

Possível duplicado

Não acho que isso seja uma duplicata de redis scan returns empty results but nonzero cursor . Não parece razoável fazer mais de 1K round-trips para o servidor para obter apenas alguns resultados.

redis
  • 1 1 respostas
  • 26 Views

1 respostas

  • Voted
  1. Best Answer
    for_stack
    2024-09-20T10:02:18+08:002024-09-20T10:02:18+08:00

    O KEYScomando se comporta de forma totalmente diferente do SCANcomando.

    KEYScommand itera todas as chaves no Redis e filtra chaves que correspondem ao seu padrão fornecido. É por isso que uma única viagem de ida e volta fornece a resposta. No entanto, ao executar KEYScommand, o Redis bloqueia e não consegue processar outro command. Portanto, é uma má ideia usar KEYScommand no ambiente de produção, especialmente quando você tem um grande conjunto de dados.

    SCANO comando também itera as chaves no Redis. No entanto, para cada varredura, ele verifica apenas algumas chaves (você pode usar o countparâmetro para controlar o número de chaves), filtra as chaves que correspondem ao seu padrão e retorna. Portanto, você precisa fazer várias viagens de ida e volta para iterar todas as chaves no Redis. Como cada operação de varredura verifica apenas algumas chaves, ela não bloqueará o Redis por muito tempo. E essa é a maneira recomendada de escanear o espaço de chaves.

    O código executou 1058 (!) iterações onde exatamente uma correspondência foi encontrada em alguma iteração, a saber

    Porque você tem um grande conjunto de dados e há apenas algumas chaves que correspondem ao seu padrão (uma pequena proporção). As primeiras 1057 varreduras não obtêm uma chave que corresponda ao padrão.

    Então, usei o SCAN para ser "legal" e isso causou 1058 viagens de ida e volta para o servidor. Estou fazendo algo errado?

    SIM, SCANé melhor que KEYS, especialmente quando você precisa escanear todas as chaves no Redis (nenhum padrão especificado ou uma grande parte das chaves corresponde ao padrão).

    No entanto, no seu caso, uma solução melhor é criar um índice secundário para as chaves que correspondem ao padrão. Digamos que você pode salvar essas chaves em um Redis SET e escanear o SET para obter as chaves.

    • 0

relate perguntas

  • O redis despeja subchaves de um mapa ao atingir o limite máximo de memória?

  • Qual é a vantagem do Redis Pool?

  • Como definir os valores da lista Redis atomicamente?

  • É possível armazenar os mesmos dados-chave (iguais) no redis?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve