O MaxCompute suporta tabelas externas do OSS que mapeiam diretórios do Object Storage Service (OSS). Use essas tabelas para ler dados não estruturados ou gravar dados no OSS.
Observações de uso
As tabelas externas do OSS não suportam a propriedade de cluster.
O tamanho de um único arquivo não pode exceder 2 GB. Divida arquivos maiores que esse limite.
O MaxCompute e o OSS devem estar na mesma região.
Métodos de acesso
As plataformas a seguir permitem criar e usar tabelas externas do OSS.
Método | Plataforma |
MaxCompute SQL | |
Visualização |
Pré-requisitos
Você já criou um projeto do MaxCompute.
-
Prepare um bucket e um diretório no OSS. Criar um bucket e Gerenciar diretórios.
O MaxCompute pode criar diretórios do OSS automaticamente. Se uma instrução SQL incluir tabelas externas e UDFs, será possível ler ou gravar na tabela externa e executar a UDF em uma única instrução. A criação manual de diretórios também é suportada.
Como o MaxCompute está implantado apenas em algumas regiões, a conectividade de rede entre regiões pode ser um problema. Mantenha seu bucket na mesma região do seu projeto do MaxCompute.
-
Autorização
Obtenha permissões para acessar o OSS. Uma conta Alibaba Cloud, um usuário RAM ou uma função RAM podem acessar tabelas externas do OSS. Consulte Autorização STS para OSS.
Obtenha a permissão CreateTable em seu projeto do MaxCompute. Consulte Permissões do MaxCompute.
Criar uma tabela externa do OSS
-
Tabelas particionadas e não particionadas:
Escolha com base em como seus arquivos de dados estão armazenados no OSS. Use uma tabela particionada se os arquivos estiverem em caminhos particionados; caso contrário, use uma tabela não particionada.
As tabelas externas do OSS suportam operações de partição.
Nome de domínio de rede: Use o nome de domínio da rede clássica para o OSS. O MaxCompute não garante conectividade de rede para nomes de domínio da rede pública.
Uma tabela externa do OSS registra apenas o mapeamento para um diretório do OSS. Excluir a tabela externa não remove os arquivos de dados no diretório mapeado.
Se um arquivo de dados do OSS for um objeto arquivado, você deve primeiro restaurar o objeto.
A sintaxe CREATE EXTERNAL TABLE varia conforme o formato do arquivo de dados. Adapte a sintaxe e os parâmetros ao formato dos seus dados. Configurações incorretas causam falhas de leitura e gravação.
Sintaxe
Criar uma tabela externa usando o analisador de dados de texto integrado
Sintaxe | Formato do arquivo de dados | Exemplo |
| Formatos de arquivo de dados suportados para leitura ou gravação no OSS:
|
Criar uma tabela externa usando um analisador de dados open source integrado
Sintaxe | Formato do arquivo de dados | Exemplo |
| Formatos de arquivo de dados suportados para leitura ou gravação no OSS:
|
Criar uma tabela externa usando um analisador personalizado
Sintaxe | Formato do arquivo de dados | Exemplo |
| Formatos de arquivo de dados suportados para leitura ou gravação no OSS: Arquivos de dados em formatos diferentes dos listados acima. |
Parâmetros
Os parâmetros a seguir são comuns a todos os formatos de tabela externa. Para parâmetros específicos de cada formato, consulte a documentação correspondente.
-
Parâmetros básicos de sintaxe
Parâmetro
Obrigatório
Descrição
mc_oss_extable_name
Sim
Nome da tabela externa do OSS a ser criada.
Os nomes das tabelas não diferenciam maiúsculas de minúsculas e não podem ser forçados a um formato específico.
col_name
Sim
Nome de uma coluna na tabela externa do OSS.
O esquema da tabela externa deve corresponder ao esquema do arquivo de dados do OSS. Caso contrário, a leitura dos dados falhará.
data_type
Sim
Tipo de dados de uma coluna na tabela externa do OSS.
O tipo de dados de cada coluna deve corresponder à coluna equivalente no arquivo de dados do OSS. Caso contrário, a leitura dos dados falhará.
table_comment
Não
Comentário da tabela. Deve ser uma string válida com no máximo 1.024 bytes. Caso contrário, um erro será reportado.
partitioned by (col_name data_type, ...)
Não
Se os arquivos de dados no OSS estiverem armazenados em um caminho particionado, inclua este parâmetro para criar uma tabela particionada.
col_name: Nome da coluna da chave de partição.
data_type: Tipo de dados da coluna da chave de partição.
'<(tb)property_name>'='<(tb)property_value>'
Sim
Propriedades estendidas da tabela externa. Consulte a documentação específica do formato para obter detalhes.
oss_location
Sim
Caminho do OSS onde os arquivos de dados estão localizados. Por padrão, todos os arquivos de dados neste caminho são lidos.
O formato é
oss://<oss_endpoint>/<Bucket name>/<OSS directory name>/.oss_endpoint:
Nome de domínio do OSS. Você deve usar o endpoint da rede clássica fornecido pelo OSS, que contém
-internal.Exemplo:
oss://oss-cn-beijing-internal.aliyuncs.com/xxx.Os nomes de domínio da rede clássica do OSS estão listados em Regiões e endpoints.
Mantenha a região do OSS onde os arquivos de dados estão armazenados igual à região do seu projeto do MaxCompute. Se estiverem em regiões diferentes, poderão ocorrer problemas de conectividade de rede.
Se você não especificar um endpoint, o sistema usará o endpoint da região onde o projeto atual está localizado.
Este método não é recomendado, pois o armazenamento de arquivos entre regiões pode causar problemas de conectividade de rede.
Bucket name: Nome do bucket do OSS. O nome do bucket deve seguir o
oss_endpoint.Exemplo:
oss://oss-cn-beijing-internal.aliyuncs.com/your_bucket/path/.Visualize os nomes dos buckets em Listar buckets.
Directory name: Nome do diretório do OSS. Não especifique um nome de arquivo após o diretório.
Exemplo:
oss://oss-cn-beijing-internal.aliyuncs.com/oss-mc-test/Demo1/.Exemplos incorretos:
-- Conexões HTTP não são suportadas. http://oss-cn-shanghai-internal.aliyuncs.com/oss-mc-test/Demo1/ -- Conexões HTTPS não são suportadas. https://oss-cn-shanghai-internal.aliyuncs.com/oss-mc-test/Demo1/ -- Endereço de conexão incorreto. oss://oss-cn-shanghai-internal.aliyuncs.com/Demo1 -- Não especifique um nome de arquivo. oss://oss-cn-shanghai-internal.aliyuncs.com/oss-mc-test/Demo1/vehicle.csvEspecificação de permissão (RamRole):
Especificar explicitamente (Recomendado): Crie uma função personalizada, anexe uma política de acesso e use seu ARN. Consulte Autorização STS.
Usar Padrão (Não recomendado): Use o ARN da função
aliyunodpsdefaultrole.
-
Atributos WITH serdeproperties
property_name
Cenário
property_value
Valor padrão
odps.properties.rolearn
Adicione esta propriedade ao usar autorização STS.
Especifique o ARN da função RAM que tem permissões para acessar o OSS.
Obtenha o ARN nos detalhes da função no Console RAM. Exemplo:
acs:ram::xxxxxx:role/aliyunodpsdefaultrole.Se os proprietários do MaxCompute e do OSS forem a mesma conta:
Se você não especificar
odps.properties.rolearnna instrução de criação da tabela, o ARN da funçãoaliyunodpsdefaultroleserá usado por padrão. Você deve primeiro criar a funçãoaliyunodpsdefaultroleusando autorização STS.Para usar um ARN de função personalizada, crie primeiro a função personalizada. Consulte Autorização STS para OSS (autorização personalizada).
Se os proprietários do MaxCompute e do OSS forem contas diferentes, você deve especificar o ARN de uma função personalizada. Para mais informações, consulte Autorização STS para OSS (autorização personalizada).
Ler dados do OSS
Observações
Após criar uma tabela externa do OSS, leia dados do OSS através dela. Para tipos de arquivos de dados suportados e sintaxe de criação, consulte Sintaxe.
Se uma instrução SQL envolver tipos de dados complexos, adicione
set odps.sql.type.system.odps2=true;antes e envie-as juntas. Consulte Versões de tipos de dados.Para tabelas externas do OSS que mapeiam dados open source, defina
set odps.sql.hive.compatible=true;no nível de sessão antes de ler dados do OSS. Caso contrário, um erro será reportado.O OSS possui limites de largura de banda. Se o tráfego de leitura/gravação exceder o limite de largura de banda da instância em um curto período, o desempenho da tabela externa será degradado. Consulte Limites e métricas de desempenho.
Sintaxe
<select_statement> FROM <from_statement>;
select_statement: A cláusula
SELECT, que consulta os dados a serem inseridos na tabela de destino a partir da tabela de origem.from_statement: A cláusula
FROM, que especifica a fonte de dados, como o nome da tabela externa.
Dados não particionados
Dados não particionados
Após criar uma tabela externa do OSS não particionada, leia dados do OSS usando um dos seguintes métodos:
-
Método 1 (Recomendado): Importe os dados de formato open source do OSS para uma tabela interna do MaxCompute e, em seguida, leia os dados.
Ideal para cálculos repetidos ou cenários de alto desempenho. Crie uma tabela interna com o mesmo esquema da tabela externa, importe os dados e execute consultas complexas. O armazenamento interno se beneficia da otimização do MaxCompute. Comando de exemplo:
CREATE TABLE <table_internal> LIKE <mc_oss_extable_name>; INSERT OVERWRITE TABLE <table_internal> SELECT * FROM <mc_oss_extable_name>; -
Método 2: Leia dados diretamente do OSS, de forma semelhante às operações em tabelas internas do MaxCompute.
Indicado para cenários de baixo desempenho. Cada consulta lê dados diretamente do OSS em vez do armazenamento interno.
Dados particionados
Dados particionados
O MaxCompute realiza uma varredura completa de todos os dados no diretório do OSS, incluindo subdiretórios. Para grandes conjuntos de dados, isso causa E/S desnecessária e aumenta o tempo de processamento. Duas soluções estão disponíveis.
-
Método 1 (Recomendado): Armazene dados no OSS usando um caminho particionado padrão ou um caminho particionado personalizado.
Especifique a partição e o oss_location na instrução de criação da tabela. Caminhos particionados padrão são recomendados.
-
Método 2: Planeje vários caminhos de armazenamento de dados.
Crie várias tabelas externas, cada uma apontando para um subconjunto de dados do OSS. Este método é trabalhoso e não recomendado.
Formato de caminho particionado padrão
oss://<oss_endpoint>/<Bucket name>/<directory name>/<partitionKey1=value1>/<partitionKey2=value2>/...
Exemplo: Uma empresa armazena arquivos de log diários em formato CSV no OSS e processa os dados diariamente usando o MaxCompute. O caminho particionado padrão para armazenar dados do OSS deve ser definido da seguinte forma.
oss://oss-odps-test/log_data/year=2016/month=06/day=01/logfile
oss://oss-odps-test/log_data/year=2016/month=06/day=02/logfile
oss://oss-odps-test/log_data/year=2016/month=07/day=10/logfile
oss://oss-odps-test/log_data/year=2016/month=08/day=08/logfile
...
Formato de caminho particionado personalizado
Um formato de caminho particionado personalizado contém apenas valores de colunas de partição, não nomes de colunas de partição. Exemplo:
oss://oss-odps-test/log_data_customized/2016/06/01/logfile
oss://oss-odps-test/log_data_customized/2016/06/02/logfile
oss://oss-odps-test/log_data_customized/2016/07/10/logfile
oss://oss-odps-test/log_data_customized/2016/08/08/logfile
...
Se os dados do OSS usarem um caminho particionado não padrão, vincule subdiretórios a partições manualmente.
Após criar a tabela externa, use alter table ... add partition ... location ... para vincular subdiretórios a partições. Exemplo:
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '06', day = '01')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket_name/oss-odps-test/log_data_customized/2016/06/01/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '06', day = '02')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket_name/oss-odps-test/log_data_customized/2016/06/02/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '07', day = '10')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket_name/oss-odps-test/log_data_customized/2016/07/10/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '08', day = '08')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket_name/oss-odps-test/log_data_customized/2016/08/08/';
Otimização de consulta
Coleta dinâmica de estatísticas
Coleta dinâmica de estatísticas
Dados externos carecem de estatísticas pré-existentes, fazendo com que o otimizador de consultas use uma estratégia conservadora e de baixa eficiência. A coleta dinâmica de estatísticas permite que o otimizador colete estatísticas da tabela durante a execução da consulta para identificar tabelas pequenas, habilitando Hash Join, ordem de junção otimizada, menos shuffles e pipelines de execução mais curtos.
Os parâmetros a seguir não se aplicam a tabelas externas Paimon, Hudi ou Delta Lake.
SET odps.meta.exttable.stats.onlinecollect=true;
SELECT * FROM <tablename>;
Otimização de divisão de tabela externa
Otimização de divisão de tabela externa
Ajuste o tamanho da divisão para controlar a quantidade de dados que cada tarefa concorrente processa.
Se o volume de dados for grande e o tamanho da divisão for muito pequeno, divisões excessivas causam alto paralelismo e a instância passa a maior parte do tempo aguardando recursos.
Se o volume de dados for pequeno e o tamanho da divisão for muito grande, poucas divisões causam concorrência insuficiente e recursos ociosos.
-- You can use either of the following parameters.
-- Unit: MiB. Default value: 256 MiB. Applies to internal or external tables.
SET odps.stage.mapper.split.size=<value>;
SELECT * FROM <tablename>;
-- Unit: MiB. Default value: 256 MiB. Applies only to external tables.
SET odps.sql.unstructured.data.split.size=<value>;
SELECT * FROM <tablename>;
Controle de DOP
Controlar paralelismo com DOP
Defina o parâmetro odps.sql.split.dop para ajustar o grau de paralelismo ao ler dados. Este parâmetro tem prioridade maior que odps.sql.mapper.split.size.
Se o valor dop for maior que o número de arquivos no diretório do OSS, a concorrência real poderá diferir significativamente do valor dop configurado.
Se o valor dop for muito pequeno, ele não terá efeito. Use o parâmetro
odps.input.file.num.limitpara alterar o número máximo de arquivos que uma única instância pode processar.
Sintaxe
-- Syntax for the two-tier model: set odps.sql.split.dop={"project.table": xxx};
-- Syntax for the three-tier model: set odps.sql.split.dop={"project.schema.table": xxx};
SET odps.sql.split.dop={
"project.schema.table1": xxx,
"project.schema.table2": yyy
};
SET odps.sql.common.table.planner.ext.hive.bridge=FALSE;
SELECT * FROM <your_table>;
Exemplo de uso
Problema e solução para distorção de DOP causada por muitos arquivos pequenos
O MaxCompute limita uma única instância a processar no máximo 240 arquivos. Se um diretório de tabela externa do OSS contiver 3.449 arquivos, o grau mínimo de paralelismo será 3.449 / 240 ≈ 15. Se você definir o DOP com um valor menor que 15, a configuração será ignorada.
Para resolver isso, defina odps.input.file.num.limit para alterar o número máximo de arquivos que uma única instância pode processar.
SET odps.sql.split.dop = {"lakehouse47_3.tpch_1t_parquet_snappy.lineitem": 2};
SET odps.input.file.num.limit = 5000;
Uma única instância pode processar até 5.000 arquivos do OSS. Como o número de arquivos na tabela lineitem está bem abaixo desse limite, o grau real de paralelismo corresponde ao valor DOP configurado.
Gravar dados no OSS
O MaxCompute pode gravar dados de tabelas internas ou tabelas externas processadas no OSS. Para limites, consulte Escopo.
Grave dados no OSS usando um analisador de dados de texto ou open source integrado: Analisador de texto integrado, Analisador open source integrado.
Grave dados no OSS usando um analisador personalizado: Exemplo: Criar uma tabela externa do OSS usando um analisador personalizado.
Grave dados no OSS usando o recurso de upload multipart do OSS: Gravar dados no OSS usando o recurso de upload multipart do OSS.
Sintaxe
INSERT {INTO|OVERWRITE} TABLE <table_name> PARTITION (<ptcol_name>[, <ptcol_name> ...])
<select_statement> FROM <from_statement>;
|
Parâmetro |
Obrigatório |
Descrição |
|
table_name |
Sim |
Nome da tabela externa onde os dados serão gravados. |
|
select_statement |
Sim |
A cláusula |
|
from_statement |
Sim |
A cláusula |
Para inserir dados em partições dinâmicas, consulte Inserir ou sobrescrever dados em partições dinâmicas (DYNAMIC PARTITION) .
Observações
Se a operação
INSERT OVERWRITE ... SELECT ... FROM ...;alocar 1.000 mappers na tabela de origem from_tablename, 1.000 arquivos TSV ou CSV serão gerados.-
Controle o número de arquivos gerados usando configurações fornecidas pelo MaxCompute.
Se o outputter estiver em um mapper: Use
odps.stage.mapper.split.sizepara controlar o número de mappers concorrentes, ajustando assim o número de arquivos gerados.Se o outputter estiver em um reducer ou joiner: Use
odps.stage.reducer.numeodps.stage.joiner.numrespectivamente para ajustar o número de arquivos gerados.
Risco de gravações inconsistentes: Ao usar uma instrução INSERT OVERWRITE em uma tabela externa do OSS ou usar o comando UNLOAD para exportar arquivos para o OSS, os dados no subdiretório do local especificado do OSS ou no local correspondente à partição são excluídos antes que novos dados sejam gravados. Se o diretório de localização contiver dados importantes gravados diretamente no OSS por outros mecanismos externos, esses dados também serão excluídos antes da gravação dos novos dados. Portanto, garanta que os arquivos existentes no diretório de localização da tabela externa tenham backup ou que o diretório UNLOAD esteja vazio. Para outros riscos de gravações inconsistentes, consulte Escopo.
Gravar dados no OSS usando o recurso de upload multipart do OSS
Para gravar dados no OSS em formato open source, crie uma tabela externa com um analisador de dados open source e ative o recurso de upload multipart do OSS.
Para ativar o recurso de upload multipart do OSS, configure o seguinte:
Cenário | Comando |
Definir no nível do projeto | Entra em vigor para todo o projeto. |
Definir no nível da sessão | Entra em vigor apenas para a tarefa atual. |
O valor padrão de odps.sql.unstructured.oss.commit.mode é false. Os dois modos funcionam da seguinte forma:
|
Valor |
Princípio |
|
false |
Os dados são armazenados em uma pasta .odps sob o diretório LOCATION, com um arquivo .meta para consistência dos dados. O conteúdo de .odps só pode ser processado corretamente pelo MaxCompute. Outros mecanismos podem falhar ao analisá-lo. |
|
true |
O MaxCompute usa o recurso de upload multipart para ser compatível com outros mecanismos de processamento de dados. Ele utiliza um método de |
Gerenciar arquivos exportados
Parâmetros
Adicione um prefixo, sufixo ou extensão aos arquivos de dados de saída usando os seguintes parâmetros.
property_name | Cenário | Descrição | property_value | Valor padrão |
odps.external.data.output.prefix (Compatível com odps.external.data.prefix) | Adicione esta propriedade quando precisar adicionar um prefixo personalizado aos arquivos de saída. |
| Uma combinação de caracteres permitidos, como 'mc_' | Nenhum |
odps.external.data.enable.extension | Adicione esta propriedade quando precisar exibir a extensão dos arquivos de saída. | True indica que a extensão do arquivo de saída é exibida. False indica que ela não é exibida. |
| False |
odps.external.data.output.suffix | Adicione esta propriedade quando precisar adicionar um sufixo personalizado aos arquivos de saída. | Contém apenas dígitos, letras e sublinhados (a-z, A-Z, 0-9, _). | Uma combinação de caracteres permitidos, como '_hangzhou' | Nenhum |
odps.external.data.output.explicit.extension | Adicione esta propriedade quando precisar adicionar uma extensão personalizada aos arquivos de saída. |
| Uma combinação de caracteres permitidos, como "jsonl" | Nenhum |
Exemplos
-
Defina o prefixo personalizado para arquivos gravados no OSS como
test06_. O DDL é o seguinte:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- Add a custom prefix. 'odps.external.data.output.prefix'='test06_') ; -- Write data to the external table. INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');A figura a seguir mostra os arquivos gerados após a operação de gravação.

-
Para personalizar o sufixo dos arquivos gravados no OSS como
_beijing, o DDL é o seguinte:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- Add a custom suffix. 'odps.external.data.output.suffix'='_beijing') ; -- Write data to the external table. INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');A figura a seguir mostra os arquivos gerados após a operação de gravação.

-
Para gerar automaticamente uma extensão de arquivo para os arquivos de saída, use o seguinte DDL:
CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- Automatically generate a file extension. 'odps.external.data.enable.extension'='true') ; -- Write data to the external table. INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');A figura a seguir mostra os arquivos gerados após a operação de gravação.
-
Para personalizar a extensão do arquivo como
jsonlpara arquivos gravados no OSS, o DDL é o seguinte:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- Add a custom file extension. 'odps.external.data.output.explicit.extension'='jsonl') ; -- Write data to the external table. INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');A figura a seguir mostra os arquivos gerados após a operação de gravação.

-
Para arquivos gravados no OSS, defina o prefixo como
mc_, o sufixo como_beijinge a extensão do arquivo comojsonl. O DDL é o seguinte:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- Add a custom prefix. 'odps.external.data.output.prefix'='mc_', -- Add a custom suffix. 'odps.external.data.output.suffix'='_beijing', -- Add a custom file extension. 'odps.external.data.output.explicit.extension'='jsonl') ; -- Write data to the external table. INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');A figura a seguir mostra os arquivos gerados após a operação de gravação.

Gravar arquivos grandes usando partições dinâmicas
Cenário de negócios
Exporte resultados de cálculo de uma tabela ancestral para o OSS como partições, gravando-os como arquivos grandes (por exemplo, 4 GB). Configure o parâmetro odps.adaptive.shuffle.desired.partition.size (em MB) com partições dinâmicas.
Vantagem: Controle o tamanho desejado do arquivo de saída configurando o valor do parâmetro.
Desvantagem: O tempo total de execução é maior porque a gravação de arquivos grandes reduz o grau de paralelismo, o que, por sua vez, aumenta o tempo de execução.
Descrições de métricas
-- The service.mode must be turned off.
SET odps.service.mode=off;
-- The dynamic partition capability must be enabled.
SET odps.sql.reshuffle.dynamicpt=true;
-- Set the desired data consumption for each reducer. Assume you want each file to be 4 GB.
SET odps.adaptive.shuffle.desired.partition.size=4096;
Exemplo
Grave um arquivo JSON de aproximadamente 4 GB no OSS.
Prepare os dados de teste. Use a tabela de conjunto de dados público
bigdata_public_dataset.tpcds_1t.web_sales, que tem cerca de 30 GB. Os dados são armazenados em formato compactado no MaxCompute, portanto, o tamanho aumenta após a exportação.-
Crie uma tabela externa JSON.
-- Sample table name: json_ext_web_sales CREATE EXTERNAL TABLE json_ext_web_sales( c_int INT , c_string STRING ) PARTITIONED BY (pt STRING) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo-test/'; -
Sem definir nenhum parâmetro, grave a tabela de teste na tabela externa JSON em formato de partição dinâmica.
-- The service.mode must be turned off. set odps.service.mode=off; -- Enable the Layer 3 syntax switch. SET odps.namespace.schema=true; -- Write to the JSON external table in a dynamic partition format. INSERT OVERWRITE json_ext_web_sales PARTITION(pt) SELECT CAST(ws_item_sk AS INT) AS c_int, CAST(ws_bill_customer_sk AS string) AS c_string , COALESCE(CONCAT(ws_bill_addr_sk %2, '_', ws_promo_sk %3),'null_pt') AS pt FROM bigdata_public_dataset.tpcds_1t.web_sales;Os arquivos armazenados no OSS são mostrados na figura a seguir:

-
Adicione o parâmetro
odps.adaptive.shuffle.desired.partition.sizepara saída de arquivos grandes e grave a tabela de teste na tabela externa JSON em formato de partição dinâmica.-- The service.mode must be turned off. SET odps.service.mode=off; -- Enable the Layer 3 syntax switch. SET odps.namespace.schema=true; -- The dynamic partition capability must be enabled. SET odps.sql.reshuffle.dynamicpt=true; -- Set the desired data consumption for each reducer. Assume you want each file to be 4 GB. SET odps.adaptive.shuffle.desired.partition.size=4096; -- Write to the JSON external table in a dynamic partition format. INSERT OVERWRITE json_ext_web_sales PARTITION(pt) SELECT CAST(ws_item_sk AS INT) AS c_int, CAST(ws_bill_customer_sk AS string) AS c_string , COALESCE(CONCAT(ws_bill_addr_sk %2, '_', ws_promo_sk %3),'null_pt') AS pt FROM bigdata_public_dataset.tpcds_1t.web_sales;Os arquivos armazenados no OSS são mostrados na figura a seguir:

Operações de partição em tabelas externas do OSS
As tabelas externas do OSS suportam operações de partição. Consulte Operações de partição em tabelas externas do OSS e Operações de partição em tabelas internas. A tabela a seguir lista as operações suportadas.
|
Operação |
Suportado |
|
Adicionar partição |
|
|
Modificar hora de atualização da partição |
|
|
Modificar valor da partição |
|
|
Mesclar partições |
|
|
Listar partições |
|
|
Visualizar informações da partição |
|
|
Excluir partição |
|
|
Truncar partição |
|
Importar do ou exportar para o OSS
Comando LOAD: Importa dados de armazenamento externo, como o OSS, para uma tabela ou partição do MaxCompute.
Comando UNLOAD: Exporta dados de um projeto do MaxCompute para armazenamento externo, como o OSS, para uso por outros mecanismos de computação.
Apêndice: Preparar dados de amostra
-
Preparar diretórios do OSS
As informações dos dados de amostra fornecidos são as seguintes:
oss_endpoint:
oss-cn-hangzhou-internal.aliyuncs.com, que corresponde a China (Hangzhou).Nome do Bucket:
oss-mc-test.Nomes dos diretórios:
Demo1/,Demo2/,Demo3/eSampleData/.
-
Dados de tabela não particionada
O arquivo carregado no diretório
Demo1/é vehicle.csv, que contém os seguintes dados. O diretórioDemo1/é usado para mapear uma tabela não particionada criada com o analisador de dados de texto integrado.1,1,51,1,46.81006,-92.08174,9/14/2014 0:00,S 1,2,13,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,3,48,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,4,30,1,46.81006,-92.08174,9/14/2014 0:00,W 1,5,47,1,46.81006,-92.08174,9/14/2014 0:00,S 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00,S 1,7,53,1,46.81006,-92.08174,9/15/2014 0:00,N 1,8,63,1,46.81006,-92.08174,9/15/2014 0:00,SW 1,9,4,1,46.81006,-92.08174,9/15/2014 0:00,NE 1,10,31,1,46.81006,-92.08174,9/15/2014 0:00,N -
Dados de tabela particionada
O diretório
Demo2/contém cinco subdiretórios:direction=N/,direction=NE/,direction=S/,direction=SW/edirection=W/. Os arquivos carregados são vehicle1.csv, vehicle2.csv, vehicle3.csv, vehicle4.csv e vehicle5.csv, respectivamente. Esses arquivos contêm os seguintes dados. O diretórioDemo2/é usado para mapear uma tabela particionada criada com o analisador de dados de texto integrado.--vehicle1.csv 1,7,53,1,46.81006,-92.08174,9/15/2014 0:00 1,10,31,1,46.81006,-92.08174,9/15/2014 0:00 --vehicle2.csv 1,2,13,1,46.81006,-92.08174,9/14/2014 0:00 1,3,48,1,46.81006,-92.08174,9/14/2014 0:00 1,9,4,1,46.81006,-92.08174,9/15/2014 0:00 --vehicle3.csv 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00 1,5,47,1,46.81006,-92.08174,9/14/2014 0:00 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00 --vehicle4.csv 1,8,63,1,46.81006,-92.08174,9/15/2014 0:00 --vehicle5.csv 1,4,30,1,46.81006,-92.08174,9/14/2014 0:00 -
Dados compactados
O arquivo carregado no diretório
Demo3/é vehicle.csv.gz. O arquivo dentro do pacote compactado é vehicle.csv, que tem o mesmo conteúdo do arquivo no diretórioDemo1/. Ele é usado para mapear uma tabela externa do OSS com propriedades de compactação. -
Dados de analisador personalizado
O arquivo carregado no diretório
SampleData/é vehicle6.csv, que contém os seguintes dados. O diretórioSampleData/é usado para mapear uma tabela externa do OSS criada com um analisador de dados open source.1|1|51|1|46.81006|-92.08174|9/14/2014 0:00|S 1|2|13|1|46.81006|-92.08174|9/14/2014 0:00|NE 1|3|48|1|46.81006|-92.08174|9/14/2014 0:00|NE 1|4|30|1|46.81006|-92.08174|9/14/2014 0:00|W 1|5|47|1|46.81006|-92.08174|9/14/2014 0:00|S 1|6|9|1|46.81006|-92.08174|9/14/2014 0:00|S 1|7|53|1|46.81006|-92.08174|9/14/2014 0:00|N 1|8|63|1|46.81006|-92.08174|9/14/2014 0:00|SW 1|9|4|1|46.81006|-92.08174|9/14/2014 0:00|NE 1|10|31|1|46.81006|-92.08174|9/14/2014 0:00|N
Perguntas frequentes sobre tabelas externas do OSS
Como mesclar vários arquivos pequenos em um único arquivo usando uma tabela externa do OSS?
Como resolvo o erro "Couldn't connect to server" ao ler de uma tabela externa do OSS?
Como resolvo o erro "Network is unreachable (connect failed)" ao criar uma tabela externa do OSS?
Solução para o erro "table not found" ao acessar uma tabela externa do OSS a partir do Spark.
Como resolvo o erro "Inline data exceeds the maximum allowed size" ao processar dados do OSS usando uma tabela externa?
-
Problema
Ao processar dados do OSS, o erro
Inline data exceeds the maximum allowed sizeé reportado. -
Causa
O OSS Store tem um limite de tamanho para cada arquivo pequeno. Um erro é reportado se um arquivo exceder 3 GB.
-
Solução
Ajuste as duas propriedades a seguir para controlar o tamanho dos dados que cada reducer grava na tabela externa, mantendo os arquivos dentro do limite de 3 GB.
set odps.sql.mapper.split.size=256; # Adjusts the size of data read by each mapper, in MB. set odps.stage.reducer.num=100; # Adjusts the number of workers in the reduce stage.
Como resolvo um erro de estouro de memória que ocorre após carregar uma UDF para acessar uma tabela externa do OSS no MaxCompute, mesmo que a UDF tenha passado nos testes locais?
-
Problema
Ao acessar uma tabela externa do OSS no MaxCompute, uma UDF que passou nos testes locais retorna o seguinte erro após ser carregada.
FAILED: ODPS-0123131:User defined function exception - Traceback: java.lang.OutOfMemoryError: Java heap spaceApós definir os seguintes parâmetros, o tempo de execução aumenta, mas o erro persiste.
set odps.stage.mapper.mem = 2048; set odps.stage.mapper.jvm.mem = 4096; -
Causa
Existem muitos arquivos de objetos na tabela externa, o que causa uso excessivo de memória, e nenhuma partição foi definida.
-
Solução
Use uma quantidade menor de dados para a consulta.
Particione os arquivos de objetos para reduzir o uso de memória.
Como mesclar vários arquivos pequenos em um único arquivo usando uma tabela externa do OSS?
Verifique o log do Logview para ver se o último estágio no plano de execução SQL é um reducer ou um joiner.
Se for um reducer, execute a instrução
set odps.stage.reducer.num=1;Se for um joiner, execute a instrução
set odps.stage.joiner.num=1;
Como resolvo o erro "Couldn't connect to server" ao ler de uma tabela externa do OSS?
-
Problema
Ao ler dados de uma tabela externa do OSS, o erro
ODPS-0123131:User defined function exception - common/io/oss/oss_client.cpp(95): OSSRequestException: req_id: , http status code: -998, error code: HttpIoError, message: Couldn't connect to serveré reportado. -
Causa
Causa 1: Quando a tabela externa do OSS foi criada, um endpoint público foi usado para o
oss_endpointno endereço oss_location, em vez de um endpoint interno.Causa 2: Quando a tabela externa do OSS foi criada, o endpoint de outra região foi usado para o
oss_endpointno endereço oss_location.
-
Solução
-
Para a Causa 1:
Verifique se o
oss_endpointem oss_location é um endpoint interno. Se for um endpoint público, altere-o para um endpoint interno. Consulte Parâmetros.Por exemplo, se um usuário na região Indonésia (Jacarta) usou o endereço
oss://oss-ap-southeast-5.aliyuncs.com/<bucket>/....para criar uma tabela externa, ele deve ser alterado para o endereço interno correspondenteoss://oss-ap-southeast-5-internal.aliyuncs.com/<bucket>/..... -
Para a Causa 2:
Verifique se o
oss_endpointem oss_location corresponde à região que você deseja acessar. Os nomes de domínio da rede clássica do OSS estão listados em Regiões e endpoints.
-
Como resolvo o erro "Network is unreachable (connect failed)" ao criar uma tabela externa do OSS?
-
Problema
Ao criar uma tabela externa do OSS, o erro
ODPS-0130071:[1,1] Semantic analysis exception - external table checking failure, error message: Cannot connect to the endpoint 'oss-cn-beijing.aliyuncs.com': Connect to bucket.oss-cn-beijing.aliyuncs.com:80 [bucket.oss-cn-beijing.aliyuncs.com] failed: Network is unreachable (connect failed)é reportado. -
Causa
Quando a tabela externa do OSS foi criada, um endpoint público foi usado para o
oss_endpointno endereço oss_location, em vez de um endpoint interno. -
Solução
Verifique se o
oss_endpointem oss_location é um endpoint interno. Se for um endpoint público, altere-o para um endpoint interno. Consulte Parâmetros.Por exemplo, se um usuário na região China (Pequim) usou o endereço
oss://oss-cn-beijing.aliyuncs.com/<bucket>/....para criar uma tabela externa, ele deve ser alterado para o endereço interno correspondenteoss://oss-cn-beijing-internal.aliyuncs.com/<bucket>/.....
Como resolvo a execução lenta de jobs SQL em uma tabela externa do OSS?
-
Leitura lenta de arquivos compactados GZ em uma tabela externa do OSS
-
Sintomas
Um usuário criou uma tabela externa do OSS com uma fonte de dados de um arquivo compactado GZ de 200 GB no OSS. O processo de leitura de dados é lento.
-
Causa
A velocidade de processamento SQL é lenta porque poucos mappers estão executando a computação no estágio map.
-
Solução
-
Para dados estruturados, defina o seguinte parâmetro para ajustar a quantidade de dados lidos por um único mapper e acelerar a execução do SQL.
set odps.sql.mapper.split.size=256; # Adjusts the size of table data read by each mapper, in MB. Para dados não estruturados, verifique se há apenas um arquivo do OSS no caminho da tabela externa do OSS. Se houver apenas um, somente um mapper poderá ser gerado, pois dados não estruturados em formato compactado não podem ser divididos. Isso resulta em velocidade de processamento lenta. Recomendamos dividir o arquivo grande do OSS em arquivos menores no caminho correspondente da tabela externa no OSS. Isso aumenta o número de mappers gerados quando a tabela externa é lida e melhora a velocidade de leitura.
-
-
-
Pesquisa lenta de dados de tabela externa do MaxCompute usando um SDK
-
Sintomas
A pesquisa de dados de tabela externa do MaxCompute usando um SDK é lenta.
-
Solução
Tabelas externas suportam apenas varreduras completas de tabela, o que é lento. Use uma tabela interna do MaxCompute em vez disso.
-
-
Problema
Em um cenário de
insert overwrite, se o job falhar em casos extremos, o resultado pode ser inconsistente com o esperado. Os dados antigos são excluídos, mas os novos dados não são gravados. -
Causa
Os dados recém-gravados falham ao serem escritos na tabela de destino devido a uma probabilidade muito baixa de falha de hardware ou falha na atualização de metadados. A operação de exclusão no OSS não suporta rollback, portanto, os dados antigos excluídos não podem ser recuperados.
-
Solução
Se você estiver sobrescrevendo uma tabela externa do OSS com base em seus dados antigos, por exemplo,
insert overwrite table T select * from table T;, faça backup dos dados do OSS antecipadamente. Se o job falhar, você poderá então sobrescrever a tabela externa do OSS com base nos dados antigos do backup.Se o job
insert overwritepuder ser reenviado, simplesmente reenvie o job se ele falhar.
-
Problema
Ao usar o Spark para acessar uma tabela externa do OSS, a tarefa falha com um erro "table not found".
-
Solução
-
Adicione os seguintes parâmetros:
Ativar configuração de tabela externa:spark.sql.catalog.odps.enableExternalTable=true;
Configurar a região onde o OSS está localizado:spark.hadoop.odps.oss.region.default=cn-<region>
-
Se o erro persistir após adicionar os parâmetros acima, conforme mostrado abaixo:

Recrie a tabela externa do OSS e acesse-a novamente.
-
-
Formatos de tabela externa do OSS suportados:
Criar uma tabela externa do OSS e ler ou gravar no OSS usando um analisador personalizado: Analisadores personalizados.
Analisar um arquivo do OSS em um conjunto de dados com um esquema que suporta filtragem e processamento de colunas: Recurso especial: Schemaless Query.
Como resolvo o problema em que dados antigos são excluídos, mas novos dados não são gravados ao usar o recurso de upload multipart do OSS?
Solução para o erro "table not found" ao acessar uma tabela externa do OSS a partir do Spark