Estou usando o comando scan em golang para obter chaves do Redis por meio de um padrão fornecido. Estou usando um cluster do Redis e, portanto, para evitar chaves perdidas, uso o ForEachMaster. Este é o código que uso:
func deleteCacheKeys(ctx context.Context, pattern string, count int64, retries int) error {
redisClient := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{redisCluster},
})
if err := redisClient.Ping(ctx).Err(); err != nil {
return err
}
var cursor uint64
err = redisClient.ForEachMaster(ctx, func(ctx context.Context, nodeClient *redis.Client) error {
for {
keys, cursor := nodeClient.Scan(ctx, cursor, pattern, count).Val()
if len(keys) > 0 {
cmd := nodeClient.Del(ctx, keys...)
if cmd.Err() != nil {
return cmd.Err()
}
}
if cursor == 0 {
break
}
}
return nil
})
return err
}
Nesta função, a parte complicada é a contagem usada em cada comando de varredura do cliente do nó. Quando a defino como 1000000, tudo funciona bem. Mas quando uso um valor menor, como 100 ou mesmo 100000, este código trava em um loop infinito (o máximo que esperei foram 30 minutos). Ao usar 1000000 como contagem, geralmente leva segundos para excluir o padrão.
Mas estávamos bem usando 1 milhão até que nosso conjunto de dados do Redis ficou tão grande que o loop infinito aconteceu com essa contagem também. Atualmente, estou procurando uma maneira segura de excluir esses padrões sem me preocupar com essa contagem. E eu realmente quero saber o motivo pelo qual isso acontece.
Tentei defini-lo como -1, mas ainda trava. Também tentei usar o comando Unlink em vez do comando Del, mas o resultado é o mesmo.