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