TairHash est une structure de données propriétaire étendue de Tair qui permet de spécifier une durée de vie (TTL) et un numéro de version pour chaque champ. Lorsqu'un utilisateur se connecte depuis plusieurs appareils, le stockage de chaque session sous forme de chaîne Redis impose de concaténer l'identifiant utilisateur et le type d'appareil en une seule clé — par exemple, User_1_phone. TairHash élimine cette contrainte en alignant la structure de session sur son modèle de données : définissez la key comme identifiant utilisateur, le field comme type d'appareil et la value comme jeton de session. Comme TairHash prend en charge les paramètres TTL pour les clés et les champs, les jetons expirent indépendamment pour chaque appareil sans logique applicative supplémentaire.
Limites des chaînes Redis standard
Les chaînes Redis conviennent aux sessions mono-appareil. Les sessions multi-appareils révèlent trois problèmes :
| Problème | Impact |
|---|---|
| Concaténation de chaînes | L'application doit construire et analyser des clés composites telles que user_1_phone à chaque lecture et écriture |
| Surcharge d'encodage | L'analyse répétée des clés augmente la consommation CPU et la complexité du code |
| Duplication du stockage | Le préfixe d'identifiant utilisateur est répété dans chaque clé spécifique à un appareil |
TairHash résout ces trois problèmes : une clé par utilisateur, un champ par appareil, un TTL par champ.

Cas d'utilisation
Le TTL au niveau du champ dans TairHash s'adapte à plusieurs modèles de gestion de session :
Gestion des jetons multi-appareils : stockez un jeton par appareil sous une seule clé utilisateur. Chaque jeton expire indépendamment en fonction de l'activité de session de cet appareil.
Suivi des sessions actives : utilisez
EXHGETALLpour répertorier toutes les sessions actives d'un utilisateur. Les champs expirés sont automatiquement exclus, de sorte que le résultat reflète toujours l'état actif actuel.Nettoyage automatique des sessions : définissez un court TTL sur les jetons lors de la connexion. Lorsqu'un utilisateur reste inactif sur un appareil plus longtemps que le TTL, cette session est supprimée sans tâche de nettoyage planifiée.
Commandes principales
| Objectif | Commande | Description |
|---|---|---|
| Écrire un jeton avec TTL | EXHSET key field value EX seconds |
Définit un TTL au niveau du champ en secondes |
| Lire tous les jetons actifs | EXHGETALL key |
Renvoie uniquement les champs qui n'ont pas expiré |
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Une instance Tair (Alibaba Cloud Redis avec les extensions Tair activées)
Python 3.8 ou version ultérieure
tair-py installé (
pip3 install tair) — source disponible à l'adresse github.com/alibaba/tair-py
Stocker et récupérer les jetons de session
L'exemple suivant stocke les jetons de deux utilisateurs sur plusieurs appareils, attend 6 secondes, puis récupère les jetons actifs restants. Au bout de 6 secondes, le jeton téléphonique de user1 (TTL = 5 s) a expiré et est exclu des résultats.
# -*- coding: utf-8 -*-
#!/usr/bin/env python
import os
import time
from tair import Tair
from tair import ResponseError
def get_tair() -> Tair:
# Connect to a Tair instance.
# host: endpoint of your Tair instance
# port: default is 6379
# username: leave blank to use the default account
# password: read from environment variable TAIR_PASSWORD
return Tair(
host="r-bp************.redis.rds.aliyuncs.com",
port=6379,
db=0,
username="",
password=os.environ.get("TAIR_PASSWORD"),
)
def add_user_token(tair: Tair, user_id: str, device: str, token: str, ttl_seconds: int) -> bool:
# Store a session token using EXHSET with a per-field TTL.
# key = user_id (groups all devices for one user)
# field = device (identifies the device type)
# value = token (the session token)
# ex = TTL in seconds
try:
result = tair.exhset(user_id, device, token, ex=ttl_seconds)
return result == 1
except ResponseError as e:
print(e)
return False
def print_active_tokens(tair: Tair, user_id: str):
# EXHGETALL returns only fields that have not yet expired.
for entry in tair.exhgetall(user_id):
print("{}:{}".format(user_id, entry))
if __name__ == "__main__":
tair = get_tair()
user_1 = "user1"
user_2 = "user2"
# Write four tokens with different TTLs.
add_user_token(tair, user_1, "phone", "token_123", 5) # expires in 5 s
add_user_token(tair, user_1, "pad", "token_124", 10) # expires in 10 s
add_user_token(tair, user_2, "pad", "token_456", 10) # expires in 10 s
add_user_token(tair, user_2, "pc", "token_457", 10) # expires in 10 s
# Wait 6 seconds. user1's phone token (TTL = 5 s) will have expired.
print("Waiting 6 seconds...")
time.sleep(6)
# Only 3 of the 4 tokens are returned; user1/phone has expired.
print_active_tokens(tair, user_1) # prints user1/pad only
print_active_tokens(tair, user_2) # prints user2/pad and user2/pc
Résultat attendu :
Waiting 6 seconds...
user1:{field: pad, value: token_124}
user2:{field: pad, value: token_456}
user2:{field: pc, value: token_457}
user1/phone est absent car son TTL de 5 secondes s'est écoulé avant la requête. Les trois autres jetons, chacun configuré avec un TTL de 10 secondes, sont toujours actifs.