Condividi tramite


Connettore Spark di Azure Cosmos DB: controllo della velocità effettiva

SI APPLICA A: NoSQL

Il connettore Spark consente di comunicare con Azure Cosmos DB usando Apache Spark. Questo articolo descrive il funzionamento della funzionalità di controllo della velocità effettiva. Vedere gli esempi di Spark in GitHub per iniziare a usare il controllo della velocità effettiva.

Questo articolo illustra l'uso dei gruppi di controllo della velocità effettiva globale nel connettore Spark di Azure Cosmos DB, ma la funzionalità è disponibile anche in Java SDK. Nell'SDK è possibile usare gruppi di controllo della velocità effettiva globale e locale per limitare il consumo di unità richiesta (UR) nel contesto di una singola istanza di connessione client. Ad esempio, è possibile applicare questo approccio a operazioni diverse all'interno di un singolo microservizio o ad un singolo programma di caricamento dati. Per altre informazioni, vedere come usare il controllo della velocità effettiva in Java SDK.

Avviso

Il controllo velocità effettiva non è supportato per la modalità gateway. Attualmente, per gli account Azure Cosmos DB serverless, il tentativo di usare targetThroughputThreshold per definire una percentuale genera un errore. È possibile specificare solo un valore assoluto per la velocità effettiva/UR di destinazione usando spark.cosmos.throughputControl.targetThroughput.

Perché il controllo della velocità effettiva è importante?

Il controllo della velocità effettiva consente di isolare le esigenze di prestazioni delle applicazioni eseguite su un contenitore. Il controllo della velocità effettiva limita la quantità di UR che un client Spark specifico può utilizzare.

Diversi scenari avanzati traggono vantaggio dal controllo della velocità effettiva lato client:

  • Diverse operazioni e attività hanno priorità diverse: può essere necessario impedire che le normali transazioni vengano limitate a causa dell'inserimento dati o delle attività di copia. Alcune operazioni o attività non sono sensibili alla latenza e sono più tolleranti rispetto ad altre.
  • Fornire equità/isolamento a utenti o tenant diversi: un'applicazione ha in genere molti utenti. Alcuni utenti potrebbero inviare troppe richieste, che utilizzano tutta la velocità effettiva disponibile e causano la limitazione di altri utenti.
  • Bilanciamento del carico della velocità effettiva tra client Azure Cosmos DB diversi: in alcuni casi d'uso è importante assicurarsi che tutti i client ottengano una condivisione equa (uguale) della velocità effettiva.

Il controllo della velocità effettiva consente di limitare la velocità delle UR a livello più granulare in base alle esigenze.

Come funziona il controllo della velocità effettiva?

Per configurare il controllo della velocità effettiva per il connettore Spark, creare prima di tutto un contenitore che definisce i metadati del controllo della velocità effettiva. La chiave di partizione è groupId e ttl è abilitata. In questo caso, si crea questo contenitore usando Spark SQL e lo ThroughputControlsi chiama :

    %sql
    CREATE TABLE IF NOT EXISTS cosmosCatalog.`database-v4`.ThroughputControl 
    USING cosmos.oltp
    OPTIONS(spark.cosmos.database = 'database-v4')
    TBLPROPERTIES(partitionKeyPath = '/groupId', autoScaleMaxThroughput = '4000', indexingPolicy = 'AllProperties', defaultTtlInSeconds = '-1');

L'esempio precedente crea un contenitore con scalabilità automatica. Se si preferisce il provisioning standard, è possibile sostituire autoScaleMaxThroughput con manualThroughput.

Importante

La chiave di partizione deve essere definita come /groupId e ttl deve essere abilitata per il funzionamento della funzionalità di controllo della velocità effettiva.

All'interno della configurazione Spark di un'applicazione specifica, è quindi possibile specificare i parametri per il carico di lavoro. Nell'esempio seguente il controllo velocità effettiva viene impostato su enabled. L'esempio definisce un parametro del gruppo name di controllo della velocità effettiva e un targetThroughputThreshold parametro. È anche possibile definire i database parametri e container in cui viene gestito il gruppo di controllo della velocità effettiva:

    "spark.cosmos.throughputControl.enabled" -> "true",
    "spark.cosmos.throughputControl.name" -> "SourceContainerThroughputControl",
    "spark.cosmos.throughputControl.targetThroughputThreshold" -> "0.95", 
    "spark.cosmos.throughputControl.globalControl.database" -> "database-v4", 
    "spark.cosmos.throughputControl.globalControl.container" -> "ThroughputControl"

Nell'esempio precedente il targetThroughputThreshold parametro è definito come 0.95. La limitazione della frequenza si verifica (e le richieste vengono ritentate) quando i client utilizzano più del 95% (+/- 5-10%) della velocità effettiva allocata al contenitore. Questa configurazione viene archiviata come documento nel contenitore di velocità effettiva, simile all'esempio seguente:

    {
        "id": "ZGF0YWJhc2UtdjQvY3VzdG9tZXIvU291cmNlQ29udGFpbmVyVGhyb3VnaHB1dENvbnRyb2w.info",
        "groupId": "database-v4/customer/SourceContainerThroughputControl.config",
        "targetThroughput": "",
        "targetThroughputThreshold": "0.95",
        "isDefault": true,
        "_rid": "EHcYAPolTiABAAAAAAAAAA==",
        "_self": "dbs/EHcYAA==/colls/EHcYAPolTiA=/docs/EHcYAPolTiABAAAAAAAAAA==/",
        "_etag": "\"2101ea83-0000-1100-0000-627503dd0000\"",
        "_attachments": "attachments/",
        "_ts": 1651835869
    }

Il controllo velocità effettiva non esegue il precalcolazione delle UR di ogni operazione. Tiene invece traccia degli utilizzi delle UR dopo l'operazione in base all'intestazione della risposta. Di conseguenza, il controllo della velocità effettiva si basa su un'approssimazione e non garantisce che la quantità di velocità effettiva sia disponibile per il gruppo in un determinato momento.

Per questo motivo, se l'UR configurata è così bassa che una singola operazione può usarla tutte, il controllo della velocità effettiva non può evitare che le UR superino il limite configurato. Il controllo velocità effettiva funziona meglio quando il limite configurato è superiore a qualsiasi singola operazione che può essere eseguita da un client nel gruppo di controllo specifico.

Quando si legge tramite query o feed di modifiche, è necessario configurare le dimensioni della pagina in spark.cosmos.read.maxItemCount (impostazione predefinita 1000) in modo da essere una quantità modesta. In questo modo, il controllo velocità effettiva del client può essere ricalcolato con una frequenza più elevata e riflesso in modo più accurato in qualsiasi momento specifico. Quando si usa il controllo della velocità effettiva per un processo di scrittura tramite operazioni bulk, il numero di documenti eseguiti in una singola richiesta viene ottimizzato automaticamente in base alla velocità di limitazione per consentire l'avvio del controllo della velocità effettiva il prima possibile.

Avviso

Il targetThroughputThreshold parametro non è modificabile. Se si modifica il valore soglia della velocità effettiva di destinazione, viene creato un nuovo gruppo di controllo della velocità effettiva. Se si usa la versione 4.10.0 o successiva, può avere lo stesso nome. È necessario riavviare tutti i processi Spark che usano il gruppo se si vuole assicurarsi che tutti usino immediatamente la nuova soglia. In caso contrario, rilevano la nuova soglia dopo il successivo riavvio.

Per ogni client Spark che usa il gruppo di controllo della velocità effettiva, viene creato un record nel ThroughputControl contenitore, con alcuni ttl secondi. Di conseguenza, i documenti svaniscono rapidamente se un client Spark non è più in esecuzione. Ecco un esempio:

    {
        "id": "Zhjdieidjojdook3osk3okso3ksp3ospojsp92939j3299p3oj93pjp93jsps939pkp9ks39kp9339skp",
        "groupId": "database-v4/customer/SourceContainerThroughputControl.config",
        "_etag": "\"1782728-w98999w-ww9998w9-99990000\"",
        "ttl": 10,
        "initializeTime": "2022-06-26T02:24:40.054Z",
        "loadFactor": 0.97636377638898,
        "allocatedThroughput": 484.89444487847,
        "_rid": "EHcYAPolTiABAAAAAAAAAA==",
        "_self": "dbs/EHcYAA==/colls/EHcYAPolTiA=/docs/EHcYAPolTiABAAAAAAAAAA==/",
        "_etag": "\"2101ea83-0000-1100-0000-627503dd0000\"",
        "_attachments": "attachments/",
        "_ts": 1651835869
    }

In ogni record client, l'attributo loadFactor rappresenta il carico sul client specifico, rispetto ad altri client nel gruppo di controllo della velocità effettiva. L'attributo allocatedThroughput mostra il numero di UR attualmente allocate a questo client. Il connettore Spark regola la velocità effettiva allocata per ogni client in base al carico. In questo modo, ogni client ottiene una condivisione della velocità effettiva disponibile proporzionale al carico. Tutti i client insieme non utilizzano più del totale allocato per il gruppo di controllo della velocità effettiva a cui appartengono.