Implémentation d'algorithmes de sharding personnalisés avec ShardingSphere Proxy

Ce guide technique présente la configuration d'algorithmes de sharding personnalisés via l'interface Standard de ShardingSphere Proxy. L'approche permet une flexibilité totale dans la définition des règles de distribution des données entre plusieurs bases de données physiques.

Diagramme de l'architecture ShardingSphere

Prérequis et configuration initiale

Avant d'implémenter vos propres algorithmes, assurez-vous d'avoir créé les bases de données physiques nécessaires. Chaque base doit contenir la colonne utilisée pour le sharding, mais les autres éléments de schéma restent à votre discrétion.

# Création des bases de données exemple
CREATE DATABASE ds_37;
CREATE DATABASE ds_45;

Ajoutez la dépendance ShardingSphere dans votre fichier Maven :

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-core</artifactId>
    <version>4.0.0-RC1</version>
</dependency>

Implémentation de l'algorithme de sharding précis

L'algorithme précis gère les opérations de filtrage par égalité ou clause IN. Créez une classe implémentant l'interface PreciseShardingAlgorithm et redéfinissez la méthode de calcul du routage.

package com.sharding.algorithms;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Algorithme de sharding précis pour la table des régions
 * Version simplifiée pour démonstration
 */
public class RegionPreciseSharding implements PreciseShardingAlgorithm<String> {
    
    private static final String DATABASE_PREFIX = "ds_";
    private static final Map<String, String> REGION_MAPPING = new HashMap<>();
    
    static {
        REGION_MAPPING.put("420216", "370201");
        REGION_MAPPING.put("510100", "510000");
    }
    
    /**
     * Route la requête vers la base de données cible
     * @param availableDatabases Liste des bases disponibles
     * @param shardingValue Valeur de la colonne de sharding
     * @return Nom de la base de données cible
     */
    @Override
    public String doSharding(Collection<String> availableDatabases, 
                            PreciseShardingValue<String> shardingValue) {
        System.out.println("[PRECISE] Traitement du sharding pour : " + shardingValue.getValue());
        
        String regionCode = shardingValue.getValue();
        
        // Application du mapping personnalisé si disponible
        if (REGION_MAPPING.containsKey(regionCode)) {
            regionCode = REGION_MAPPING.get(regionCode);
        }
        
        // Calcul de l'identifiant de base
        int databaseId = Integer.parseInt(regionCode) / 10000;
        String targetDatabase = DATABASE_PREFIX + databaseId;
        
        // Vérification de l'existence de la base cible
        for (String database : availableDatabases) {
            if (database.equals(targetDatabase)) {
                return database;
            }
        }
        
        throw new IllegalArgumentException(
            "Base de données non trouvée pour le code région : " + regionCode);
    }
}

Implémentation de l'algorithme de sharding par intervalle

Pour les requêtes impliquant des plages de valeurs (BETWEEN, comparaisons), implémentez l'interface RangeShardingAlgorithm. Cet algorithme peut retourner plusieurs bases de données cibles.

package com.sharding.algorithms;

import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Algorithme de sharding par intervalle pour les requêtes de plage
 */
public class RegionRangeSharding implements RangeShardingAlgorithm<String> {
    
    private static final String DATABASE_PREFIX = "ds_";
    private static final List<String> SPECIAL_RANGES = new ArrayList<>();
    
    static {
        SPECIAL_RANGES.add("379999");
        SPECIAL_RANGES.add("459999");
    }
    
    /**
     * Calcule les bases de données intersectant avec l'intervalle demandé
     * @param availableDatabases Bases disponibles
     * @param shardingValue Plage de valeurs à sharder
     * @return Collection des bases de données concernées
     */
    @Override
    public Collection<String> doSharding(Collection<String> availableDatabases,
                                         RangeShardingValue<String> shardingValue) {
        System.out.println("[RANGE] Traitement intervalle : " + shardingValue.getValueRange());
        
        Range<String> valueRange = shardingValue.getValueRange();
        List<String> matchedDatabases = new ArrayList<>();
        
        // Évaluation de chaque code région spécial
        for (String regionCode : SPECIAL_RANGES) {
            if (valueRange.contains(regionCode)) {
                String targetDatabase = DATABASE_PREFIX + Integer.parseInt(regionCode) / 10000;
                
                if (availableDatabases.contains(targetDatabase)) {
                    matchedDatabases.add(targetDatabase);
                }
            }
        }
        
        if (matchedDatabases.isEmpty()) {
            throw new IllegalStateException(
                "Aucune base disponible pour l'intervalle spécifié");
        }
        
        return matchedDatabases;
    }
}

Déploiement et configruation

Compilez votre projet et placez le fichier JAR dans le répertoire lib de ShardingProxy. La configuration s'effectue ensuite dans le fichier de configuraton YAML :

# Configuration avec algorithme précis uniquement
databaseStrategy:
  standard:
    shardingColumn: CODE_REGION
    preciseAlgorithmClassName: com.sharding.algorithms.RegionPreciseSharding

# Configuration avec algorithme d'intervalle uniquement
databaseStrategy:
  standard:
    shardingColumn: CODE_REGION
    rangeAlgorithmClassName: com.sharding.algorithms.RegionRangeSharding

# Configuration combinée (recommandée)
databaseStrategy:
  standard:
    shardingColumn: CODE_REGION
    preciseAlgorithmClassName: com.sharding.algorithms.RegionPreciseSharding
    rangeAlgorithmClassName: com.sharding.algorithms.RegionRangeSharding

Bonnes pratiques d'implémentation

Voici quelques recommandations pour optimiser vos implémentations :

Premièrement, validez systématiquement les entrées de la colonne de sharding pour éviter les erreurs de routage. Deuxièmement, implémentez une journalisation détaillée pour faciliter le débogage des problèmes de distribution. Troisièmement, considérez la mise en cache des mappings pour améliorer les performances lors de forte charge.

L'algorithme précis est appelé pour les requêtes avec conditions d'égalité (WHERE column = ?), tandis que l'algorithme d'intervalle gère les plages (WHERE column BETWEEEN ? AND ?). Les deux peuvent cohabiter sans conflit dans une même stratégie.

Étiquettes: ShardingSphere apache-shardingsphere database-sharding Java standard-algorithm

Publié le 26 septembre à 06h05