Ricerca nel sito web

Controlla l'algoritmo del tuo database di partizionamento orizzontale


Questa dimostrazione di ShardingSphere 5.2.0 approfondisce la logica di implementazione per il controllo dello sharding dei dati con esempi SQL specifici.

Grazie alla continua revisione e al feedback della comunità ShardingSphere per sviluppare funzionalità come il partizionamento dei dati e la suddivisione in lettura/scrittura, il nostro team ha scoperto che alcuni utenti creano molti shard quando utilizzano la funzionalità di partizionamento dei dati.

In questi casi, possono esserci 1.000 tabelle fisiche corrispondenti a una tabella logica di sharding, il che disturba gli utenti.

Ad esempio, un'istruzione SELECT * FROM t_order porterà a un percorso completo, il che ovviamente non è il caso di OLTP. Questo SQL può essere inserito in un altro proxy per evitare di bloccare altre richieste.

Tuttavia, se gli utenti non hanno familiarità con Proxy o come scrivere una condizione where e non sanno che lo sharding non è supportato in questa condizione, è comunque necessario un percorso completo.

Un percorso completo può ridurre le prestazioni del proxy e persino comportare il fallimento di una richiesta ragionevole. Immagina che ci siano 1.000 frammenti in un database fisico. Se vengono eseguiti in parallelo sono necessarie 1.000 connessioni e se in seriale la richiesta può portare a un timeout. Per questo motivo gli utenti della community si sono chiesti se la richiesta irragionevole potesse essere intercettata direttamente.

Il nostro team ha considerato la questione per un po'. Un'opzione è semplicemente bloccare l'operazione sull'intero percorso. Per fare ciò è necessario controllare il codice e aggiungere un'opzione al file di configurazione. D'altra parte, se in seguito l'utente ha bisogno di impostare una tabella in sola lettura o richiede che l'operazione di aggiornamento contenga un limit, significa che il codice e la configurazione cambiano nuovamente? Questo approccio ovviamente va contro la logica collegabile di Proxy.

In risposta ai problemi di cui sopra, Apache ShardingSphere 5.2.0 recentemente rilasciato fornisce agli utenti il controllo della funzione di sharding SQL. L'audit può essere un'operazione di intercettazione o un'operazione statistica. Similmente agli algoritmi di sharding e di generazione di chiavi univoche, l'algoritmo di controllo è orientato ai plug-in, definito dall'utente e configurabile.

[ Leggi correlate 5 nuovi miglioramenti in Apache ShardingSphere ]

Successivamente, elaborerò la logica di implementazione per il controllo dello sharding dei dati con esempi SQL specifici.

Controllo dell'interfaccia di partizionamento orizzontale

L'ingresso all'audit di Apache ShardingSphere è nella classe org.apache.shardingsphere.infra.executor.check.SQLCheckEngine, che invocherà il metodo check di SQLChecker interfaccia. Attualmente, l'audit ShardingSphere contiene un controllo per l'autorizzazione (verifica nome utente e password) e un controllo per lo sharding.

Questo esempio si concentra sull'interfaccia principale implementata nello ShardingAuditChecker dell'audit per lo sharding.

(Yacine Si Tayeb, CC BY-SA 4.0)

Puoi apprendere rapidamente i suoi principi di funzionamento visualizzando il codice check di org.apache.shardingsphere.sharding.checker.audit.ShardingAuditChecker.

public interface ShardingAuditAlgorithm extends ShardingSphereAlgorithm {
    
    /**
     * Sharding audit algorithm SQL check.
     *
     * @param sqlStatementContext SQL statement context
     * @param parameters SQL parameters
     * @param grantee grantee
     * @param database database
     * @return SQL check result
     */
    SQLCheckResult check(SQLStatementContext<?> sqlStatementContext, List<Object> parameters, Grantee grantee, ShardingSphereDatabase database);
}

Questo metodo ottiene le strategie di controllo di tutte le tabelle di partizionamento orizzontale coinvolte e richiama gli algoritmi di controllo configurati in ciascuna strategia di controllo della tabella di partizionamento orizzontale. Se un algoritmo di controllo non riesce a passare, viene visualizzata un'eccezione all'utente.

Alcuni utenti potrebbero chiedersi cosa fa disableAuditNames qui. Il controllo dello sharding consente inoltre agli utenti di saltare questo processo. In alcuni casi, gli utenti potrebbero dover eseguire SQL che avrebbe dovuto essere bloccato dal controllo e sono consapevoli dell'impatto di questo SQL.

Gli utenti possono utilizzare il Hint:disableAuditNames per saltare l'intercettazione dell'audit, che verrà descritto con esempi pratici più avanti. Gli amministratori proxy possono configurare allowHintDisable per controllare se consentire agli utenti di saltare questo processo. Il valore predefinito è true, a indicare che è consentito un salto basato su suggerimento.

Controllo dell'algoritmo di partizionamento orizzontale

Il controllo per l'interfaccia dell'algoritmo di sharding org.apache.shardingsphere.sharding.spi.ShardingAuditAlgorithm è ereditato dalla classe SPI ShardingSphereAlgorithm. Eredita le proprietà type e props e definisce il proprio metodo check. Se desideri personalizzare il tuo algoritmo di controllo, implementa semplicemente l'interfaccia e aggiungila a INF.services.

(Yacine Si Tayeb, CC BY-SA 4.0)

public interface ShardingAuditAlgorithm extends ShardingSphereAlgorithm {
    
    /**
     * Sharding audit algorithm SQL check.
     *
     * @param sqlStatementContext SQL statement context
     * @param parameters SQL parameters
     * @param grantee grantee
     * @param database database
     * @return SQL check result
     */
    SQLCheckResult check(SQLStatementContext<?> sqlStatementContext, List<Object> parameters, Grantee grantee, ShardingSphereDatabase database);
}

Apache ShardingSphere implementa un controllo generale per l'algoritmo di sharding org.apache.shardingsphere.sharding.algorithm.audit.DMLShardingConditionsShardingAuditAlgorithm, ovvero l'istruzione SQL sopra menzionata che intercetta l'intero percorso.

L'algoritmo prende decisioni determinando se la condizione di partizionamento orizzontale è null. Ovviamente non intercetterà le tabelle broadcast e le tabelle non-sharding.

public final class DMLShardingConditionsShardingAuditAlgorithm implements ShardingAuditAlgorithm {
    
    @Getter
    private Properties props;
    
    @Override
    public void init(final Properties props) {
        this.props = props;
    }
    
    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    public SQLCheckResult check(final SQLStatementContext<?> sqlStatementContext, final List<Object> parameters, final Grantee grantee, final ShardingSphereDatabase database) {
        if (sqlStatementContext.getSqlStatement() instanceof DMLStatement) {
            ShardingRule rule = database.getRuleMetaData().getSingleRule(ShardingRule.class);
            if (rule.isAllBroadcastTables(sqlStatementContext.getTablesContext().getTableNames())
                    || sqlStatementContext.getTablesContext().getTableNames().stream().noneMatch(rule::isShardingTable)) {
                return new SQLCheckResult(true, "");
            }
            ShardingConditionEngine shardingConditionEngine = ShardingConditionEngineFactory.createShardingConditionEngine(sqlStatementContext, database, rule);
            if (shardingConditionEngine.createShardingConditions(sqlStatementContext, parameters).isEmpty()) {
                return new SQLCheckResult(false, "Not allow DML operation without sharding conditions");
            }
        }
        return new SQLCheckResult(true, "");
    }
    
    @Override
    public String getType() {
        return "DML_SHARDING_CONDITIONS";
    }
}

Vorrei introdurre un altro controllo per l'algoritmo di sharding: LimitRequiredShardingAuditAlgorithm. Questo algoritmo può intercettare SQL senza portare un limit nelle operazioni update e delete.

Poiché questo algoritmo è meno universale, attualmente non è integrato in Apache ShardingSphere. Come puoi vedere, è molto semplice implementare un algoritmo personalizzato, motivo per cui è necessario il controllo del framework di sharding. Grazie alla sua architettura orientata ai plugin, ShardingSphere vanta una grande scalabilità.

public final class LimitRequiredShardingAuditAlgorithm implements ShardingAuditAlgorithm {
    
    @Getter
    private Properties props;
    
    @Override
    public void init(final Properties props) {
        this.props = props;
    }
    
    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    public SQLCheckResult check(final SQLStatementContext<?> sqlStatementContext, final List<Object> parameters, final Grantee grantee, final ShardingSphereDatabase database) {
        if (sqlStatementContext instanceof UpdateStatementContext && !((MySQLUpdateStatement) sqlStatementContext.getSqlStatement()).getLimit().isPresent()) {
            return new SQLCheckResult(false, "Not allow update without limit");
        }
        if (sqlStatementContext instanceof DeleteStatementContext && !((MySQLDeleteStatement) sqlStatementContext.getSqlStatement()).getLimit().isPresent()) {
            return new SQLCheckResult(false, "Not allow delete without limit");
        }
        return new SQLCheckResult(true, "");
    }
    
    @Override
    public String getType() {
        return "LIMIT_REQUIRED";
    }
}

Utilizzare il controllo per lo sharding

Il controllo per lo sharding richiede la configurazione di una strategia di controllo per le tabelle logiche. Per aiutarti a iniziare rapidamente, la sua configurazione è la stessa dell'algoritmo di partizionamento orizzontale e del generatore di valori chiave di partizionamento orizzontale.

Sono disponibili una definizione dell'algoritmo e una definizione della strategia ed è supportata anche una strategia di audit predefinita. Se la strategia di controllo è configurata nella tabella logica, influisce solo su quella tabella logica.

Se defaultAuditStrategy è configurato nella tabella logica, ha effetto su tutte le tabelle logiche sotto la regola di partizionamento orizzontale. I revisori sono simili a ShardingAlgorithms, auditStrategy a databaseStrategy e defaultAuditStrategy a defaultDatabaseStrategy o defaultTableStrategy.

Fare riferimento al seguente esempio. Viene visualizzata solo la configurazione del controllo per lo sharding. È necessario configurare personalmente l'algoritmo di partizionamento orizzontale e l'origine dati.

rules:
  - !SHARDING
    tables:
      t_order:
        actualDataNodes: ds_${0..1}.t_order_${0..1}
        auditStrategy:
          auditorNames:
            - sharding_key_required_auditor
          allowHintDisable: true
    defaultAuditStrategy:
      auditorNames:
        - sharding_key_required_auditor
      allowHintDisable: true
    auditors:
      sharding_key_required_auditor:
        type: DML_SHARDING_CONDITIONS

Passaggio 1: esegui un'operazione di query. Viene visualizzato un errore quando viene configurata la strategia di controllo per intercettare l'intero percorso del database.

mysql> select * from t_order;
ERROR 13000 (44000): SQL check failed, error message: Not allow DML operation without sharding conditions

Passaggio 2: aggiungi HINT. Il nome di HINT è /* Suggerimento ShardingSphere: disattivaAuditNames */, e disableAuditNames è seguito da auditorsNames configurato nel comando precedente.

Se esistono più nomi, separarli con spazi come /* Suggerimento ShardingSphere: disattivaAuditNames=auditName1 auditName2*/. Dopo aver utilizzato HINT, puoi vedere che l'operazione SQL è stata eseguita con successo.

mysql> /* ShardingSphere hint: disableAuditNames=sharding_key_required_auditor */ select * from t_order;
+----------+---------+------------+--------+
| order_id | user_id | address_id | status |
+----------+---------+------------+--------+
|       30 |      20 |         10 | 20     |
|       32 |      22 |         10 | 20     |
+----------+---------+------------+--------+
2 rows in set (0.01 sec)

Nota: HINT richiede la modifica della configurazione server.yaml del proxy. Inoltre, se stai utilizzando il terminale MySQL per connetterti direttamente al Proxy, devi aggiungere la proprietà -c, altrimenti i commenti HINT verranno filtrati dal terminale MySQL e non verrà analizzato dal proxy sul backend.

rules:
  - !SQL_PARSER
    sqlCommentParseEnabled: true
    sqlStatementCache:
      initialCapacity: 2000
      maximumSize: 65535
    parseTreeCache:
      initialCapacity: 128
      maximumSize: 1024
props:
  proxy-hint-enabled: true
mysql -uroot -proot -h127.0.0.1 -P3307  -c

DistSQL con controllo per lo sharding

Come puoi vedere dalle note di rilascio, Apache ShardingSphere 5.2.0 supporta il seguente DistSQL con funzione di audit per lo sharding:

CREATE SHARDING AUDITOR
ALTER SHARDING AUDITOR
SHOW SHARDING AUDIT ALGORITHMS
The following DistSQL will be supported in future releases:

DROP SHARDING AUDITOR
SHOW UNUSED SHARDING AUDIT ALGORITHMS
CREATE SHARDING TABLE RULE # including AUDIT_STRATEGY

Questo post ha introdotto il funzionamento del controllo dello sharding con esempi specifici. Credo che tu abbia già una conoscenza di base di questa funzione e puoi usarla ogni volta che ne hai bisogno o utilizzare un algoritmo personalizzato.

Puoi anche inviare algoritmi generali alla comunità. Se hai idee per contribuire o riscontri problemi con ShardingSphere, sentiti libero di pubblicarle su GitHub.

Questo articolo è apparso originariamente su ShardingSphere 5.2.0: Audit for sharding intercetta richieste irragionevoli in scenari multi-shard ed è ripubblicato con autorizzazione.

Articoli correlati: