Tous les produits
Search
Centre de documentation

Lindorm:Séparer le stockage des données chaudes et froides en fonction des horodatages

Dernière mise à jour :Aug 11, 2026

LindormTable achemine automatiquement les données entre le stockage chaud et le stockage froid en fonction de leur ancienneté. Définissez une limite temporelle au niveau d'une table ou d'une famille de colonnes : les données plus récentes que cette limite restent dans le stockage chaud, tandis que les données plus anciennes sont archivées dans le stockage froid lors de la compaction.

Fonctionnement

Lorsque vous écrivez des données dans une table, elles sont stockées dans le stockage chaud (type Standard ou Performance). Lindorm exécute périodiquement une opération de compaction en arrière-plan. Pendant cette opération, Lindorm compare l'horodatage de chaque ligne à la limite configurée (COLD_BOUNDARY pour HBase Shell et l'API Java, ou CHS pour Lindorm SQL). Les lignes dont l'horodatage dépasse cette limite sont déplacées vers le stockage froid.

L'archivage est asynchrone : les données ne sont pas déplacées instantanément dès qu'elles dépassent la limite. Pour forcer un transfert immédiat, exécutez manuellement la commande major_compact.

Par défaut, l'horodatage d'une ligne correspond à l'heure système au moment de l'écriture des données. Si vous utilisez l'API ApsaraDB for HBase pour Java, vous pouvez spécifier un horodatage personnalisé. Consultez la section Considérations opérationnelles pour comprendre l'impact des horodatages personnalisés sur le routage du stockage.

Prérequis

Avant de commencer, assurez-vous d'avoir :

Définir la limite entre les données chaudes et froides

Choisissez la méthode correspondant à votre client.

Utiliser Apache HBase Shell

Étape 1 : Créer une table avec une limite

HBase(main):002:0> create 'chsTable', {NAME=>'f', COLD_BOUNDARY=>'86400'}
Paramètre Description
NAME Famille de colonnes à configurer.
COLD_BOUNDARY Limite exprimée en secondes. Les données stockées depuis plus longtemps que cette valeur sont archivées dans le stockage froid lors de la compaction. Par exemple, 86400 équivaut à un jour. Pour désactiver la séparation des données chaudes et froides, définissez la valeur sur "" (chaîne vide).

Étape 2 (facultative) : Modifier la limite

Important

Après modification de la limite, les données sont transférées entre le stockage froid et le stockage chaud lors de la prochaine compaction. Pour déclencher un transfert immédiat, exécutez major_compact 'chsTable'.

HBase(main):005:0> alter 'chsTable', {NAME=>'f', COLD_BOUNDARY=>'42300'}

Étape 3 (facultative) : Désactiver la séparation des données chaudes et froides

Important

Après désactivation de la séparation des données chaudes et froides, les données retournent du stockage froid vers le stockage chaud lors de la prochaine compaction. Pour déclencher un transfert immédiat, exécutez major_compact 'chsTable'.

HBase(main):004:0> alter 'chsTable', {NAME=>'f', COLD_BOUNDARY=>""}

Utiliser l'API ApsaraDB for HBase pour Java

Étape 1 : Créer une table avec une limite

Admin admin = connection.getAdmin();
TableName tableName = TableName.valueOf("chsTable");
HTableDescriptor descriptor = new HTableDescriptor(tableName);
HColumnDescriptor cf = new HColumnDescriptor("f");
cf.setValue(AliHBaseConstants.COLD_BOUNDARY, "86400");
descriptor.addFamily(cf);
admin.createTable(descriptor);

Étape 2 (facultative) : Modifier la limite

Important

Après modification de la limite, les données sont transférées entre le stockage froid et le stockage chaud lors de la prochaine compaction.

HTableDescriptor descriptor = admin
    .getTableDescriptor(tableName);
HColumnDescriptor cf = descriptor.getFamily("f".getBytes());
cf.setValue(AliHBaseConstants.COLD_BOUNDARY, "86400");
admin.modifyTable(tableName, descriptor);

Étape 3 (facultative) : Désactiver la séparation des données chaudes et froides

Important

Après désactivation de la séparation des données chaudes et froides, les données retournent du stockage froid vers le stockage chaud lors de la prochaine compaction.

HTableDescriptor descriptor = admin
    .getTableDescriptor(tableName);
HColumnDescriptor cf = descriptor.getFamily("f".getBytes());
cf.setValue(AliHBaseConstants.COLD_BOUNDARY, null);
admin.modifyTable(tableName, descriptor);

Utiliser lindorm-cli (Lindorm SQL)

Étape 1 : Créer une table avec une limite

Utilisez l'instruction CREATE TABLE :

CREATE TABLE dt (
  p1 integer, p2 integer, c1 varchar, c2 bigint,
  constraint pk primary key(p1 desc))
WITH (COMPRESSION = 'ZSTD', CHS = '86400', CHS_L2 = 'storagetype=COLD');

Ou activez la séparation des données chaudes et froides sur une table existante à l'aide de ALTER TABLE :

-- Enable hot and cold data separation on an existing table.
-- The table was created without CHS:
-- CREATE TABLE dt (p1 integer, p2 integer, c1 varchar, c2 bigint,
--   constraint pk primary key(p1 desc)) WITH (COMPRESSION = 'ZSTD');

ALTER TABLE dt SET 'CHS' ='86400', 'CHS_L2' = 'storagetype=COLD';
Paramètre Description
CHS Limite exprimée en secondes. Les données stockées depuis plus longtemps que cette valeur sont archivées dans le stockage froid lors de la compaction. Par exemple, 86400 équivaut à un jour. Pour désactiver la séparation des données chaudes et froides, définissez la valeur sur '' (chaîne vide).
CHS_L2 Attribut de stockage de niveau 2. Définissez la valeur sur storagetype=COLD.
COMPRESSION Algorithme de compression appliqué à toutes les données de la table. La valeur n'est pas sensible à la casse. Valeur par défaut : NONE.

Étape 2 (facultative) : Modifier la limite

Important

Après modification de la limite, les données sont transférées entre le stockage froid et le stockage chaud lors de la prochaine compaction. Pour déclencher un transfert immédiat, exécutez major_compact sur la table. Pour connaître la syntaxe, consultez la page ALTER TABLE.

ALTER TABLE dt SET 'CHS'='1000';

Étape 3 (facultative) : Désactiver la séparation des données chaudes et froides

Important

Après désactivation de la séparation des données chaudes et froides, les données retournent du stockage froid vers le stockage chaud lors de la prochaine compaction. Pour déclencher un transfert immédiat, exécutez major_compact sur la table.

ALTER TABLE dt SET 'CHS'='', 'CHS_L2' = '';

Écrire des données

Écrivez des données dans une table avec séparation chaud/froid de la même manière que dans une table large standard. Les données sont toujours écrites d'abord dans le stockage chaud, puis déplacées vers le stockage froid lors de la prochaine compaction une fois la limite configurée dépassée.

Si vous utilisez l'API ApsaraDB for HBase pour Java, vous pouvez définir un horodatage personnalisé pour chaque ligne. C'est cet horodatage qui détermine le niveau de stockage dans lequel la ligne sera placée, et non l'heure réelle de l'opération d'écriture. Consultez la section Comportement des horodatages personnalisés pour plus de détails.

Interroger des données

LindormTable stocke les données chaudes et froides dans la même table ; toutes les données sont donc accessibles via une seule requête. Par défaut, une requête sans plage de temps peut lire le stockage froid, et le débit est limité par les spécifications du stockage froid.

Pour limiter une requête au stockage chaud, utilisez l'une des options suivantes :

  • Le paramètre HOT_ONLY (Apache HBase Shell et API Java)

  • L'indicateur _l_hot_only_ (Lindorm SQL)

  • Le paramètre TimeRange , défini sur une plage incluse dans la fenêtre des données chaudes

Important

Si un champ d'une ligne située dans le stockage froid est mis à jour, le champ modifié est stocké dans le stockage chaud tandis que les données d'origine restent dans le stockage froid. Une requête utilisant HOT_ONLY ou une plage TimeRange étroite ne renvoie que le champ mis à jour, et non la ligne complète. Pour obtenir la ligne entière, effectuez la requête sans HOT_ONLY et assurez-vous que TimeRange couvre la période allant de l'insertion initiale à la dernière mise à jour. Évitez de mettre à jour les données stockées dans le stockage froid.

Requêtes GET

Apache HBase Shell

-- Query all data (may include cold storage)
HBase(main):013:0> get 'chsTable', 'row1'

-- Query only hot storage
HBase(main):015:0> get 'chsTable', 'row1', {HOT_ONLY=>true}

-- Query by time range (UNIX timestamp in milliseconds)
HBase(main):016:0> get 'chsTable', 'row1', {TIMERANGE => [0, 1568203111265]}

Le paramètre TimeRange accepte les horodatages UNIX en millisecondes depuis le 1er janvier 1970, 00:00:00 UTC. Lindorm compare TimeRange avec COLD_BOUNDARY pour déterminer les niveaux de stockage à lire.

API ApsaraDB for HBase pour Java

// Query all data (may include cold storage)
Get get = new Get("row1".getBytes());
System.out.println("result: " + table.get(get));

// Query only hot storage
get = new Get("row1".getBytes());
get.setAttribute(AliHBaseConstants.HOT_ONLY, Bytes.toBytes(true));

// Query by time range
get = new Get("row1".getBytes());
get.setTimeRange(0, 1568203111265);

Lindorm SQL

SELECT /*+ _l_hot_only_ */ * FROM dt WHERE pk IN (1, 2, 3);

Requêtes SCAN

Remarque

Seuls Apache HBase Shell et l'API ApsaraDB for HBase pour Java prennent en charge les requêtes SCAN par plage. Sans HOT_ONLY ni TimeRange couvrant uniquement les données chaudes, Lindorm lit les deux niveaux de stockage et fusionne les résultats.

Apache HBase Shell

-- Scan all data (may include cold storage)
Lindorm(main):017:0> scan 'chsTable', {STARTROW =>'row1', STOPROW=>'row9'}

-- Scan only hot storage
Lindorm(main):018:0> scan 'chsTable', {STARTROW =>'row1', STOPROW=>'row9', HOT_ONLY=>true}

-- Scan by time range
Lindorm(main):019:0> scan 'chsTable', {STARTROW =>'row1', STOPROW=>'row9', TIMERANGE => [0, 1568203111265]}

API ApsaraDB for HBase pour Java

TableName tableName = TableName.valueOf("chsTable");
Table table = connection.getTable(tableName);

// Scan all data (may include cold storage)
Scan scan = new Scan();
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
    System.out.println("scan result:" + result);
}

// Scan only hot storage
scan = new Scan();
scan.setAttribute(AliLindormConstants.HOT_ONLY, Bytes.toBytes(true));

// Scan by time range
scan = new Scan();
scan.setTimeRange(0, 1568203111265);

Prioriser les données chaudes dans les requêtes SCAN

Dans les requêtes SCAN qui récupèrent des données ordonnées, telles que toutes les commandes ou messages d'un utilisateur, LindormTable lit normalement à la fois le stockage chaud et le stockage froid, ce qui augmente le temps de réponse. Activez la priorisation des données chaudes avec COLD_HOT_MERGE pour analyser d'abord le stockage chaud. Le stockage froid n'est lu que si le nombre de lignes dans le stockage chaud est inférieur au nombre minimal de lignes de données à interroger.

Remarque

COLD_HOT_MERGE est disponible uniquement dans Apache HBase Shell et l'API ApsaraDB for HBase pour Java.

Apache HBase Shell

Lindorm(main):002:0> scan 'chsTable', {COLD_HOT_MERGE=>true}
Paramètre Valeur Description
COLD_HOT_MERGE true Analyse d'abord le stockage chaud. Le stockage froid n'est lu que si le nombre de lignes dans le stockage chaud est inférieur au nombre minimal de lignes de données à interroger.
COLD_HOT_MERGE false Désactive la priorisation des données chaudes.

API ApsaraDB for HBase pour Java

scan = new Scan();
scan.setAttribute(AliHBaseConstants.COLD_HOT_MERGE, Bytes.toBytes(true));
scanner = table.getScanner(scan);

Notes d'utilisation

  • L'ordre des clés de ligne n'est pas garanti. Lorsque COLD_HOT_MERGE est activé, les lignes chaudes sont renvoyées avant les lignes froides. L'ensemble de résultats contient des lignes chaudes et froides triées séparément par clé de ligne ; le résultat global n'est pas trié globalement par clé de ligne.

    // Normal scan (lexicographic order)
    HBase(main):001:0> scan 'chsTable'
    ROW                 COLUMN+CELL
     coldRow            column=f:value, timestamp=1560578400000, value=cold_value
     hotRow             column=f:value, timestamp=1565848800000, value=hot_value
    2 row(s)
    
    // With COLD_HOT_MERGE=true (hot rows first)
    HBase(main):002:0> scan 'chsTable', {COLD_HOT_MERGE=>true}
    ROW                 COLUMN+CELL
     hotRow             column=f:value, timestamp=1565848800000, value=hot_value
     coldRow            column=f:value, timestamp=1560578400000, value=cold_value
    2 row(s)

    Pour maintenir un ordre significatif dans votre application, concevez des clés de ligne qui encodent les informations de tri, par exemple une clé composite associant l'ID client et l'heure de création de la commande.

  • Les lignes avec des champs mis à jour apparaissent deux fois. Si une ligne du stockage froid a été partiellement mise à jour, elle s'étend sur les stockages chaud et froid. Avec COLD_HOT_MERGE activé, les résultats incluent deux entrées pour la même clé de ligne : une provenant du stockage chaud et l'autre du stockage froid.

Considérations opérationnelles

Comportement des horodatages personnalisés

L'horodatage que vous définissez sur une ligne détermine le niveau de stockage dans lequel elle atterrit, et non l'heure de l'écriture. Exemples :

  • Une ligne écrite avec un horodatage situé trois jours dans le futur sera archivée dans le stockage froid trois jours plus tard qu'une ligne écrite avec l'horodatage actuel.

  • Une ligne écrite avec un horodatage situé trois jours dans le passé, lorsque la limite est fixée à trois jours, sera archivée dans le stockage froid de manière asynchrone peu après l'écriture, et non après trois jours supplémentaires.

Utilisez les horodatages personnalisés avec précaution. Les lignes écrites avec des horodatages passés peuvent être déplacées vers le stockage froid immédiatement après la prochaine compaction, ce qui peut surprendre si vos modèles de requête supposent que les données récemment écrites se trouvent toujours dans le stockage chaud.

Données froides fréquemment consultées

Si les requêtes atteignent systématiquement le stockage froid, vérifiez si la valeur COLD_BOUNDARY (ou CHS) correspond à vos modèles d'accès réels. Le débit du stockage froid est limité par ses spécifications ; par conséquent, l'accès fréquent aux données froides dégrade les performances des requêtes.

FAQ

Après avoir mis à jour une ligne froide, reste-t-elle une donnée froide ?

Non. La mise à jour d'une ligne actualise son horodatage, de sorte que LindormTable la traite comme une donnée chaude.

J'ai défini HOT_ONLY, mais ma requête renvoie toujours des données froides. Pourquoi ?

Les données sont archivées dans le stockage froid de manière asynchrone lors de la compaction. Certaines lignes assez anciennes pour être considérées comme froides n'ont peut-être pas encore été archivées ; elles se trouvent donc toujours physiquement dans le stockage chaud et sont renvoyées par les requêtes.

Pour exclure ces données, spécifiez une plage de temps explicite en plus de HOT_ONLY. Utilisez les indicateurs _l_ts_min_ et _l_ts_max_ dans Lindorm SQL pour définir précisément la fenêtre :

-- _l_ts_min_: difference between current time and the hot/cold boundary
-- _l_ts_max_: current system time
-- Both values must use the same unit.
SELECT /*+ _l_hot_only_(true), _l_ts_min_(1000), _l_ts_max_(2001) */ * FROM test WHERE p1>1;

Ma requête expire même si j'ai spécifié HOT_ONLY et TimeRange. Pourquoi ?

Cela se produit généralement après avoir migré des données dans une table ou activé la séparation des données chaudes et froides pour la première fois. Une grande quantité de données froides se trouve toujours physiquement dans le stockage chaud car la compaction n'a pas encore été exécutée. Exécutez major compaction sur la table pour forcer le déplacement des données. Pour connaître la syntaxe, consultez la page ALTER TABLE.