Les ensembles triés natifs de Redis classent les membres selon un score unique, ce qui complique la mise en œuvre de tableaux de médailles, de classements par fenêtre temporelle et d'autres classements multidimensionnels sans recourir à des solutions de contournement. exZset (également appelé TairZset) trie des scores de type double sur jusqu'à 256 dimensions, éliminant ainsi le besoin de concaténation complexe des scores et permettant des incréments atomiques sur toutes les dimensions.
Utilisez exZset lorsque vous devez :
Classer les participants selon plusieurs critères simultanément (par exemple, le nombre de médailles d'or, d'argent et de bronze)
Interroger des classements sur différentes fenêtres temporelles — horaires, quotidiennes, hebdomadaires ou mensuelles — à partir d'une seule clé
Mettre à l'échelle les charges de travail des classements vers des shards supplémentaires lorsque le stockage ou la puissance de calcul est limitée
Pour la référence complète des commandes, consultez les commandes exZset.
Pourquoi utiliser exZset plutôt que Zset natif
L'ensemble trié natif de Redis (Zset) prend en charge le tri selon un score unique de type double. Une solution de contournement courante consiste à concaténer les scores à l'aide de la norme IEEE 754, mais cette approche présente trois inconvénients : une implémentation complexe, une précision réduite et l'impossibilité d'utiliser la commande ZINCRBY.
exZset résout ces trois problèmes :
| Fonctionnalité | Zset natif | Solution de contournement IEEE 754 | exZset |
|---|---|---|---|
| Dimensions de tri | 1 | Multiples (avec perte de précision) | Jusqu'à 256 |
| Incrément atomique | ZINCRBY |
Non pris en charge | EXZINCRBY |
| Compatibilité API | — | — | Similaire au Zset natif |
| Classements distribués | Non | Non | Oui |
| Client Java | — | — | Open source TairJedis |
Comparaison des scores
exZset utilise # comme séparateur de dimension et compare les scores de gauche à droite : il compare d'abord la dimension la plus à gauche, puis passe à la suivante uniquement si les valeurs sont égales. Si toutes les dimensions sont égales, les membres sont triés selon l'ordre ASCII.
Pour un score score1#score2#score3 :
Comparez
score1. Si les valeurs diffèrent, cela détermine le classement.Si
score1est égal, comparezscore2. Si les valeurs diffèrent, cela détermine le classement.Si
score2est également égal, comparezscore3.
Considérez # comme une virgule décimale : 0#99 < 99#90 < 99#99 — la dimension la plus à gauche domine toujours.
Créer un tableau de médailles
Un tableau de médailles classe les participants d'abord par médailles d'or, puis d'argent, puis de bronze. Avec exZset, vous encodez le nombre de médailles de chaque participant sous forme de score tridimensionnel (gold#silver#bronze), de sorte que la logique de classement est intégrée à la structure de données elle-même — aucun tri au niveau de l'application n'est requis.
Exemple de données :
| Rang | Participant | ** |
** |
** |
|---|---|---|---|---|
| 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 |
Les participants E et F ont tous deux 13 médailles d'or. E est mieux classé car il possède 21 médailles d'argent contre 17 pour F.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
L'endpoint, le port et le mot de passe d'une instance Tair
Le SDK TairJedis ajouté à votre projet
Ajouter la dépendance TairJedis
Ajoutez les lignes suivantes à pom.xml :
<dependency>
<groupId>com.aliyun.tair</groupId>
<artifactId>alibabacloud-tairjedis-sdk</artifactId>
<version>5.3.1</version>
</dependency>
Insérer et interroger les données du classement
L'exemple suivant utilise la classe LeaderBoard du SDK TairJedis. Le constructeur accepte le nom de la clé, le pool de connexions, la taille de la page et les options de tri.
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}]
}
}
Pour toutes les méthodes disponibles de LeaderBoard, consultez la Javadoc alibabacloud-tairjedis-sdk sous com.aliyun.tair.tairzset.LeaderBoard.
Les exemples ci-dessus utilisent Java avec TairJedis. Pour les autres langages, appelez directement les commandes exZset — voir les commandes exZset.
Créer des classements par fenêtre temporelle
Vous pouvez proposer des classements horaires, quotidiens, hebdomadaires et mensuels à partir d'une seule clé en encodant le temps à la fois dans le score et dans le nom du membre. Cette approche utilise la comparaison de gauche à droite d'exZset pour filtrer les entrées par plage de temps à l'aide de EXZREVRANGEBYSCORE.
Conception de la clé et du score
Stockez toutes les données d'un mois dans une seule clé (par exemple, julyZset). Chaque entrée encode le temps sur six dimensions :
score format: month#week#day#hour#minute#points
member format: month#week#day#hour#minute_username
| Dimension | Valeur d'exemple | Signification |
|---|---|---|
month |
7 |
Juillet |
week |
2 |
Deuxième semaine du mois |
day |
6 |
6e jour de la semaine |
hour |
16 |
16 h 00 |
minute |
22 |
:22 |
points |
100 |
Score obtenu à ce moment-là |
Le préfixe temporel dans le nom du membre lie chaque entrée à une minute spécifique. Étant donné qu'exZset compare les dimensions de gauche à droite, la définition des dimensions inférieures sur 0 dans EXZREVRANGEBYSCORE crée une borne inférieure inclusive pour toute granularité temporelle — les dimensions les plus à gauche agissent comme filtre principal.
Insérer des données avec EXZINCRBY
Utilisez EXZINCRBY pour ajouter ou incrémenter atomiquement le score d'un membre — aucun cycle lecture-modification-écriture n'est requis.
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
Interroger les classements par fenêtre temporelle
Toutes les requêtes de plage utilisent EXZREVRANGEBYSCORE avec des bornes de score correspondant à la fenêtre temporelle souhaitée.
| Classement | Plage de scores | Commande | Sortie |
|---|---|---|---|
| Horaire en temps réel (15 h 23–16 h 23, heure actuelle 16 h 23) | Toutes les entrées mises à jour au cours des 60 dernières minutes | 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 |
| Heure spécifique (16 h 00–17 h 00) | Toutes les entrées dans la fenêtre 16 h 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 |
| Quotidien (5 juillet) | Toutes les entrées du 5e jour de la 2e semaine | EXZREVRANGEBYSCORE julyZset 7#2#6#0#0#0 7#2#5#0#0#0 |
7#2#5#10#23_user1 |
| Hebdomadaire (2e semaine de juillet) | Toutes les entrées de la 2e semaine | 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 |
| Mensuel (juillet) | Toutes les entrées de juillet | 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 |
Pour les classements fréquemment consultés, tels que le classement horaire en temps réel, mettez les résultats en cache pour réduire le nombre de requêtes de plage répétées.
Étapes suivantes
Commandes exZset — Référence complète des commandes pour exZset
alibabacloud-tairjedis-sdk — Code source du SDK TairJedis et exemples supplémentaires