Todos os produtos
Search
Central de documentação

Tair (Redis® OSS-Compatible):Implementar leaderboards multidimensionais com exZset

Última atualização: Jun 26, 2026

Os conjuntos ordenados nativos do Redis classificam membros por uma única pontuação, o que dificulta a implementação de tabelas de medalhas, rankings por janela de tempo e outros leaderboards multidimensionais sem soluções alternativas. O exZset (também chamado TairZset) ordena pontuações do tipo double em até 256 dimensões, eliminando a necessidade de concatenação complexa de pontuações e permitindo incrementos atômicos em todas as dimensões.

Use o exZset quando precisar:

  • Classificar participantes por vários critérios simultaneamente (por exemplo, contagem de medalhas de ouro, prata e bronze)

  • Consultar leaderboards em diferentes janelas de tempo — horária, diária, semanal ou mensal — a partir de uma única chave

  • Dimensionar cargas de trabalho de leaderboard para shards adicionais quando o armazenamento ou a computação estiverem limitados

Para obter a referência completa de comandos, consulte comandos exZset.

Por que usar exZset em vez do Zset nativo

O Conjunto Ordenado nativo do Redis (Zset) suporta classificação por uma única pontuação do tipo double. Uma solução alternativa comum é concatenar pontuações usando o padrão IEEE 754, mas essa abordagem apresenta três desvantagens: implementação complexa, precisão reduzida e impossibilidade de usar o comando ZINCRBY.

O exZset resolve todos esses problemas:

Recurso

Zset nativo

Solução alternativa IEEE 754

exZset

Dimensões de classificação

1

Múltiplas (com perda de precisão)

Até 256

Incremento atômico

ZINCRBY

Não suportado

EXZINCRBY

Compatibilidade de API

—

—

Semelhante ao Zset nativo

Leaderboards distribuídos

Não

Não

Sim

Cliente Java

—

—

Open source TairJedis

Como as pontuações são comparadas

O exZset usa # como separador de dimensões e compara as pontuações da esquerda para a direita: avalia primeiro a dimensão mais à esquerda e só avança para a direita quando os valores são iguais. Se todas as dimensões forem idênticas, os membros são classificados pela ordem ASCII.

Para uma pontuação score1#score2#score3:

  1. Compare score1. Se houver diferença, isso define a classificação.

  2. Se score1 for igual, compare score2. Valores distintos determinam o ranking.

  3. Se score2 também for igual, compare score3.

Considere # como um ponto decimal: 0#99 < 99#90 < 99#99 — a dimensão mais à esquerda sempre tem prioridade.

Crie uma tabela de medalhas

Uma tabela de medalhas classifica os participantes primeiramente pelo ouro, depois pela prata e, por fim, pelo bronze. Com o exZset, codifique a contagem de medalhas de cada participante como uma pontuação tridimensional (gold#silver#bronze). Assim, a lógica de classificação fica incorporada na própria estrutura de dados, sem necessidade de ordenação no nível da aplicação.

Dados de exemplo:

Classificação

Participante

**金牌 Ouro**

**银牌 Prata**

**铜牌 Bronze**

1

A

32

21

16

2

B

25

29

21

3

C

20

7

12

4

D

14

4

16

5

E

13

21

18

6

F

13

17

14

Os participantes E e F possuem ambos 13 medalhas de ouro. E ocupa uma posição superior porque tem 21 medalhas de prata contra 17 de F.

Pré-requisitos

Antes de começar, verifique se você tem:

  • Endpoint, porta e senha de uma instância Tair

  • SDK TairJedis adicionado ao seu projeto

Adicionar a dependência do TairJedis

Adicione o seguinte trecho ao arquivo pom.xml:

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

Inserir e consultar dados do leaderboard

O exemplo abaixo usa a classe LeaderBoard do SDK TairJedis. O construtor recebe o nome da chave, o pool de conexões, o tamanho da página e as opções de ordenação.

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

public class LeaderBoardExample {
    // Replace with your instance endpoint and credentials.
    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();

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

        // Create a leaderboard named "leaderboard".
        LeaderBoard lb = new LeaderBoard("leaderboard", jedisPool, 10, true, false);

        // Add members with three-dimensional scores: gold, silver, bronze.
        lb.addMember("A",  32, 21, 16);
        lb.addMember("B",  25, 29, 21);
        lb.addMember("C",  20,  7, 12);
        lb.addMember("D",  14,  4, 16);
        lb.addMember("E",  13, 21, 18);
        lb.addMember("F",  13, 17, 14);

        // Get the rank of A (1-indexed).
        System.out.println(lb.rankFor("A"));
        // 1

        // Get the top 3.
        System.out.println(lb.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}]

        // Get the full leaderboard.
        System.out.println(lb.allLeaders());
        // [{"member":"A","score":"32#21#16","rank":1},
        //  {"member":"B","score":"25#29#21","rank":2},
        //  {"member":"C","score":"20#7#12","rank":3},
        //  {"member":"D","score":"14#4#16","rank":4},
        //  {"member":"E","score":"13#21#18","rank":5},
        //  {"member":"F","score":"13#17#14","rank":6}]
    }
}

Para ver todos os métodos disponíveis da classe LeaderBoard, consulte o Javadoc do alibabacloud-tairjedis-sdk em com.aliyun.tair.tairzset.LeaderBoard.

Nota

Os exemplos acima usam Java com TairJedis. Para outras linguagens, chame diretamente os comandos exZset — veja comandos exZset.

Crie leaderboards por janela de tempo

É possível fornecer leaderboards horários, diários, semanais e mensais a partir de uma única chave codificando o tempo tanto na pontuação quanto no nome do membro. Essa estratégia aproveita a comparação da esquerda para a direita do exZset para filtrar entradas por intervalo de tempo usando EXZREVRANGEBYSCORE.

Design de chave e pontuação

Armazene todos os dados de um mês em uma única chave (por exemplo, julyZset). Cada entrada codifica o tempo em seis dimensões:

score format:  month#week#day#hour#minute#points
member format: month#week#day#hour#minute_username

Dimensão

Valor de exemplo

Significado

month

7

Julho

week

2

Segunda semana do mês

day

6

6º dia da semana

hour

16

16:00

minute

22

:22

points

100

Pontuação obtida naquele momento

O prefixo de tempo no nome do membro vincula cada entrada a um minuto específico. Como o exZset compara as dimensões da esquerda para a direita, defina as dimensões inferiores como 0 no comando EXZREVRANGEBYSCORE cria um limite inferior inclusivo para qualquer granularidade de tempo — as dimensões mais à esquerda funcionam como filtro principal.

Inserir dados com EXZINCRBY

Use EXZINCRBY para adicionar ou incrementar a pontuação de um membro atomicamente, sem ciclo de leitura-modificação-escrita.

EXZINCRBY julyZset 7#2#6#16#22#100 7#2#6#16#22_user1
EXZINCRBY julyZset 7#2#6#16#22#50  7#2#6#16#22_user2
EXZINCRBY julyZset 7#2#6#16#23#70  7#2#6#16#23_user1
EXZINCRBY julyZset 7#2#6#16#23#80  7#2#6#16#23_user1

Consultar leaderboards por janela de tempo

Todas as consultas de intervalo usam EXZREVRANGEBYSCORE com limites de pontuação correspondentes à janela de tempo desejada.

Leaderboard

Intervalo de pontuação

Comando

Saída

Horário em tempo real (15:23–16:23, hora atual 16:23)

Todas as entradas atualizadas nos últimos 60 minutos

EXZREVRANGEBYSCORE julyZset 7#2#6#16#23#0 7#2#6#15#23#0

7#2#6#16#22_user1, 7#2#6#16#22_user2

Hora específica (16:00–17:00)

Todas as entradas na janela 16:xx

EXZREVRANGEBYSCORE julyZset 7#2#6#17#0#0 7#2#6#16#0#0

7#2#6#16#22_user1, 7#2#6#16#22_user2

Diário (5 de julho)

Todas as entradas no dia 5 da semana 2

EXZREVRANGEBYSCORE julyZset 7#2#6#0#0#0 7#2#5#0#0#0

7#2#5#10#23_user1

Semanal (semana 2 de julho)

Todas as entradas na semana 2

EXZREVRANGEBYSCORE julyZset 7#3#0#0#0#0 7#2#0#0#0#0

7#2#6#16#22_user1, 7#2#6#16#22_user2, 7#2#5#10#23_user1

Mensal (julho)

Todas as entradas em julho

EXZREVRANGEBYSCORE julyZset 7#6#0#0#0#0 7#0#0#0#0#0

7#4#20#12#20_user1, 7#2#6#16#22_user1, 7#2#6#16#22_user2, 7#2#5#10#23_user1

Nota

Para rankings acessados frequentemente, como o leaderboard horário em tempo real, armazene os resultados em cache para reduzir consultas repetidas de intervalo.

Próximos passos