Todos os produtos
Search
Central de documentação

Tair (Redis® OSS-Compatible):Implement distributed leaderboards by using exZset

Última atualização: Jun 26, 2026

Quando uma única chave de sorted set contém centenas de milhares de membros, ela se torna uma hot key e uma large key — ambas degradam o desempenho. O cliente TairJedis fornece a classe DistributedLeaderBoard, que distribui os dados do leaderboard de forma transparente entre múltiplos sub-leaderboards. Uma chave lógica se expande em N sub-leaderboards; as consultas de classificação agregam os resultados de todos eles e somam as classificações por sub-leaderboard para produzir a classificação final de cada membro. Isso permite criar leaderboards com mais de 100.000 membros sem gerenciar o sharding de dados manualmente.

Como funciona a classificação precisa

O exZset oferece dois métodos para calcular classificações em um leaderboard distribuído: classificação precisa (recomendada) e interpolação linear (ainda não implementada no exZset).

A classificação precisa distribui os membros entre N sub-leaderboards usando um hash de Verificação de Redundância Cíclica (CRC) da chave de cada membro. Para obter a classificação do membro x, FindRank(x) consulta cada sub-leaderboard e soma as classificações retornadas. Por exemplo, com três sub-leaderboards e 3.000 membros no total, se as classificações por sub-leaderboard do membro x forem 124, 183 e 156, a classificação final será 463. As classificações são exatas, e a complexidade de tempo para recuperar uma classificação é m × O(log(N)), onde m é o número de sub-leaderboards.

A interpolação linear divide os dados em segmentos de pontuação, registra a contagem de membros e a classificação mais alta de cada segmento, e estima as classificações por interpolação. Obter uma classificação tem complexidade O(m), mas os resultados são aproximados.

Use a classificação precisa, a menos que seu caso de uso tolere classificações estimadas. Para mais informações sobre os comandos exZset utilizados neste tópico, consulte comandos do exZset.

Pré-requisitos

Antes de começar, certifique-se de ter:

  • O endpoint, a porta e a senha de uma instância Tair

  • Ambiente de desenvolvimento Java com Maven

Defina o leaderboard

Etapa 1: Adicione a dependência Maven

Adicione o seguinte ao seu pom.xml:

<dependency>
    <groupId>com.aliyun.tair</groupId>
    <artifactId>alibabacloud-tairjedis-sdk</artifactId>
    <version>5.3.1</version>
</dependency>

Etapa 2: Configure e execute o leaderboard

O exemplo a seguir cria um leaderboard distribuído, adiciona seis membros com pontuações multidimensionais (contagens de medalhas de ouro, prata e bronze) e recupera a classificação de um membro e o top três geral.

import io.valkey.JedisPool;
import io.valkey.JedisPoolConfig;
import com.aliyun.tair.tairzset.*;

public class DistributedLeaderBoardExample {
    // Instance connection settings
    private static final int DEFAULT_CONNECTION_TIMEOUT = 5000;
    private static final int DEFAULT_SO_TIMEOUT = 2000;
    private static final String HOST = "<r-bp1mx0ydsivrbp****.redis.rds.aliyuncs.com>";
    private static final int PORT = 6379;
    private static final String PASSWORD = "<Pass****word>";
    private static final JedisPoolConfig config = new JedisPoolConfig();

    // Leaderboard settings
    private static final int shardKeySize = 10;          // Number of sub-leaderboards
    private static final int pageSize = 10;              // Members per page
    private static final boolean reverse = true;         // true = descending order (highest score first)
    private static final boolean useZeroIndexForRank = false; // false = ranks start from 1

    public static void main(String[] args) {
        JedisPool jedisPool = new JedisPool(config, HOST, PORT, DEFAULT_CONNECTION_TIMEOUT,
                DEFAULT_SO_TIMEOUT, PASSWORD, 0, null);

        // Create the distributed leaderboard
        DistributedLeaderBoard dlb = new DistributedLeaderBoard("distributed_leaderboard", jedisPool,
            shardKeySize, pageSize, reverse, useZeroIndexForRank);

        // Add members with multi-dimensional scores: gold, silver, bronze
        // Members are sorted by gold first, then silver, then bronze
        dlb.addMember("A", 32, 21, 16);
        dlb.addMember("B", 25, 29, 21);
        dlb.addMember("C", 20,  7, 12);
        dlb.addMember("D", 14,  4, 16);
        dlb.addMember("E", 13, 21, 18);
        dlb.addMember("F", 13, 17, 14);

        // Get the rank of member A
        System.out.println(dlb.rankFor("A")); // 1

        // Get the top 3 members
        System.out.println(dlb.top(3));
        // [{"member":"A","score":"32#21#16","rank":1},
        //  {"member":"B","score":"25#29#21","rank":2},
        //  {"member":"C","score":"20#7#12","rank":3}]
    }
}

Substitua os seguintes placeholders pelos valores reais:

Placeholder

Descrição

Exemplo

<r-bp1mx0ydsivrbp****.redis.rds.aliyuncs.com>

Endpoint da instância

r-bp1example.redis.rds.aliyuncs.com

<Pass****word>

Senha da instância

A senha da sua instância

Nota

O campo score na resposta de top() codifica valores multidimensionais separados por #. Para o membro A, "score":"32#21#16" significa 32 medalhas de ouro, 21 de prata e 16 de bronze.

Parâmetros

Parâmetro

Tipo

Descrição

Padrão

shardKeySize

int

Número de sub-leaderboards. Defina este valor antecipadamente — ele não pode ser dimensionado dinamicamente após a criação do leaderboard.

10

pageSize

int

Número de membros por página.

10

reverse

boolean

Ordem de classificação. true ordena em ordem decrescente (maior pontuação primeiro). false ordena em ordem crescente.

false

useZeroIndexForRank

boolean

Indexação de classificação. true inicia as classificações a partir de 0. false inicia as classificações a partir de 1.

true

Para a lista completa de métodos disponíveis, consulte a classe com.aliyun.tair.tairzset.DistributedLeaderBoard no Javadoc do alibabacloud-tairjedis-sdk.

Apêndice: Leaderboards convencionais vs. distribuídos

A tabela a seguir compara a complexidade de tempo para operações comuns entre um leaderboard convencional (chave exZset única) e um leaderboard distribuído (m sub-leaderboards).

Nota

Na coluna distribuído, m é o número de sub-leaderboards e N é o número de membros em um sub-leaderboard.

Operação Leaderboard convencional Leaderboard distribuído
Implementação convencional Complexidade convencional Implementação distribuída Complexidade distribuída
Inserir um membro EXZADD O(log(N)) Calcule o sub-leaderboard de destino com crc(key) & m, depois EXZADD O(log(N))
Atualizar a pontuação de um membro EXZINCRBY O(log(N)) Calcule o sub-leaderboard de destino com crc(key) & m, depois EXZINCRBY O(log(N))
Remover um membro EXZREM O(M\*log(N)) Calcule o sub-leaderboard de destino com crc(key) & m, depois EXZREM O(log(N))
Contar todos os membros EXZCARD O(1) EXZCARD em cada sub-leaderboard e, depois, soma O(m)
Contar o total de páginas EXZCARD ÷ tamanho da página O(1) EXZCARD em cada sub-leaderboard, soma e divisão pelo tamanho da página O(m)
Contar membros em um intervalo de pontuação EXZCOUNT O(log(N)) EXZCOUNT em cada sub-leaderboard e, depois, mescla os resultados m × O(log(N))
Remover membros em um intervalo de pontuação EXZREMRANGEBYSCORE O(log(N)+M) EXZREMRANGEBYSCORE em cada sub-leaderboard m × O(log(N))
Obter a pontuação de um membro EXZSCORE O(1) Calcule o sub-leaderboard de destino com crc(key) & m, depois EXZSCORE O(1)
Obter a classificação de um membro EXZRANK O(log(N)) EXZRANKBYSCORE em cada sub-leaderboard e, depois, soma m × O(log(N))
Obter a pontuação e a classificação de um membro EXZSCORE + EXZRANK O(log(N)) 1. Calcule o sub-leaderboard de destino com crc(key) & m, depois EXZSCORE. 2. Execute EXZRANKBYSCORE em cada sub-leaderboard e, depois, soma. m × O(log(N))
Obter os i primeiros membros EXZRANGE O(log(N)+M) EXZRANGE dos i primeiros de cada sub-leaderboard e, depois, mescla m × O(log(N))
Obter a página i do leaderboard EXZRANGE O(log(N)) Recupere todos os membros anteriores à página de destino de cada sub-leaderboard e, depois, ordene m × O(log(N))
Definir um tempo de expiração EXPIRE O(1) EXPIRE em cada sub-leaderboard O(m)
Excluir o leaderboard DEL O(N) DEL em cada sub-leaderboard m × O(N)