Conector do Spark do Azure Cosmos DB: controle de taxa de transferência
APLICA-SE A: NoSQL
O conector do Spark permite que você se comunique com o Azure Cosmos DB usando o Apache Spark. Este artigo descreve como funciona o recurso de controle de taxa de transferência. Confira nossos Exemplos do Spark em GitHub para começar a usar o controle de taxa de transferência.
Este artigo documenta o uso de grupos de controle de taxa de transferência global no conector do Spark do Azure Cosmos DB, mas a funcionalidade também está disponível no SDK do Java. No SDK, é possível usar grupos globais e locais de controle de taxa de transferência para limitar o consumo de RU (unidade de solicitação) no contexto de uma única instância de conexão de cliente. Por exemplo, você pode aplicar essa abordagem a diferentes operações em um único microsserviço ou talvez a um único programa de carregamento de dados. Para obter mais informações, confira como usar o controle de taxa de transferência no SDK do Java.
Aviso
Não há suporte para o controle de taxa de transferência para o modo de gateway. Atualmente, para contas do Azure Cosmos DB sem servidor, a tentativa de usar targetThroughputThreshold
para definir uma porcentagem resultará em falha. Você só pode fornecer um valor absoluto para a taxa de transferência/RU de destino usando spark.cosmos.throughputControl.targetThroughput
.
Por que o controle de taxa de transferência é importante?
O controle de taxa de transferência ajuda a isolar as necessidades de desempenho de aplicativos executados em um contêiner. O controle de taxa de transferência limita a quantidade de RUs que um cliente Spark específico pode consumir.
Vários cenários avançados se beneficiam do controle de taxa de transferência no lado do cliente:
- Operações e tarefas diferentes têm prioridades diferentes: pode ser necessário evitar que transações normais sejam limitadas por causa da ingestão de dados ou das atividades de cópia. Algumas operações ou tarefas não são sensíveis à latência e são mais tolerantes à limitação do que outras.
- Fornecer equidade/isolamento para diferentes usuários ou locatários: um aplicativo geralmente tem muitos usuários. Alguns usuários podem enviar muitas solicitações, que consomem toda a taxa de transferência disponível e fazem com que outros sejam limitados.
- Balanceamento de carga da taxa de transferência entre diferentes clientes do Azure Cosmos DB: em alguns casos de uso, é importante garantir que todos os clientes obtenham uma participação justa (igual) da taxa de transferência.
O controle de taxa de transferência permite a capacidade de limitação de taxa de RU de nível mais granular, conforme necessário.
Como funciona o controle de taxa de transferência?
Para configurar o controle de taxa de transferência para o conector do Spark, primeiro crie um contêiner que defina metadados de controle de taxa de transferência. A chave de partição é groupId
e ttl
está habilitada. Aqui, crie esse contêiner usando o Spark SQL e o chama de ThroughputControl
:
%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');
O exemplo anterior cria um contêiner com escala automática. Se preferir o provisionamento padrão, você poderá substituir autoScaleMaxThroughput
por manualThroughput
.
Importante
A chave de partição deve ser definida como /groupId
e ttl
deve estar habilitada para que o recurso de controle de taxa de transferência funcione.
Na configuração do Spark de um aplicativo específico, você pode especificar parâmetros para a carga de trabalho. O exemplo a seguir define o controle de taxa de transferência como enabled
. O exemplo define um parâmetro name
de grupo de controle de taxa de transferência e um parâmetro targetThroughputThreshold
. Você também define os parâmetros database
e container
nos quais o grupo de controle de taxa de transferência é mantido:
"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"
No exemplo anterior, o parâmetro targetThroughputThreshold
é definido como 0,95. A limitação de taxa ocorre (e as solicitações são repetidas) quando os clientes consomem mais de 95% (+/- 5-10%) da taxa de transferência alocada para o contêiner. Essa configuração é armazenada como um documento no contêiner de taxa de transferência, que se parece com este exemplo:
{
"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
}
O controle de taxa de transferência não faz o pré-cálculo de RU de cada operação. Em vez disso, ele controla os usos de RU após a operação com base no cabeçalho de resposta. Dessa forma, o controle de taxa de transferência baseia-se em uma aproximação e não garante que a quantidade de taxa de transferência esteja disponível para o grupo em um determinado momento.
Por esse motivo, se a RU configurada for tão baixa que uma única operação possa usá-la toda, o controle de taxa de transferência não poderá evitar que a RU ultrapasse o limite configurado. O controle de taxa de transferência funciona melhor quando o limite configurado é maior do que qualquer operação individual que um cliente no grupo de controle específico possa executar.
Ao ler por meio de consulta ou feed de alterações, você deve configurar o tamanho da página em spark.cosmos.read.maxItemCount
(padrão 1000) para ser uma quantidade modesta. Dessa forma, o controle de taxa de transferência do cliente pode ser recalculado com maior frequência e refletido com mais precisão em qualquer momento específico. Ao usar o controle de taxa de transferência para um trabalho de gravação em massa, o número de documentos executados em uma única solicitação é automaticamente ajustado com base na taxa de limitação para permitir que o controle de taxa de transferência comece o mais cedo possível.
Aviso
O parâmetro targetThroughputThreshold
é imutável. Se você alterar o valor do limite de taxa de transferência de destino, será criado um novo grupo de controle de taxa de transferência. (Se você usar a versão 4.10.0 ou posterior, ela poderá ter o mesmo nome.) Você precisa reiniciar todos os trabalhos do Spark que estão usando o grupo se quiser garantir que todos eles consumam o novo limite imediatamente. Caso contrário, eles atingirão o novo limite após a próxima reinicialização.
Para cada cliente Spark que usa o grupo de controle de taxa de transferência, um registro é criado no contêiner ThroughputControl
, com um ttl
de alguns segundos. Como resultado, os documentos desaparecerão rapidamente se um cliente Spark não estiver mais em execução ativamente. Veja um exemplo:
{
"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
}
Em cada registro de cliente, o atributo loadFactor
representa a carga no cliente específico, em relação a outros clientes no grupo de controle de taxa de transferência. O atributo allocatedThroughput
mostra quantas RUs estão alocadas atualmente para esse cliente. O conector do Spark ajusta a taxa de transferência alocada para cada cliente com base em sua carga. Dessa forma, cada cliente recebe uma parte da taxa de transferência disponível proporcional à sua carga. Todos os clientes juntos não consomem mais do que o total alocado para o grupo de controle de taxa de transferência ao qual pertencem.
Conteúdo relacionado
- Confira, Exemplos do Spark no GitHub.
- Saiba como gerenciar dados com o conector OLTP do Spark 3 do Azure Cosmos DB para a API para NoSQL.
- Saiba mais sobre o Apache Spark.