Este tópico descreve como usar o Hive ou o HadoopMR para acessar tabelas no Tablestore.
Preparação de dados
Crie uma tabela de dados chamada pet no Tablestore. A coluna name é a única coluna de chave primária. A tabela a seguir apresenta dados de exemplo.
Não grave dados nas células vazias. O Tablestore usa uma estrutura de armazenamento sem esquema. Não é necessário gravar NULL em uma célula sem valor.
|
name |
owner |
species |
sex |
birth |
death |
|
Fluffy |
Harold |
cat |
f |
1993-02-04 |
|
|
Claws |
Gwen |
cat |
m |
1994-03-17 |
|
|
Buffy |
Harold |
dog |
f |
1989-05-13 |
|
|
Fang |
Benny |
dog |
m |
1990-08-27 |
|
|
Bowser |
Diane |
dog |
m |
1979-08-31 |
1995-07-29 |
|
Chirpy |
Gwen |
bird |
f |
1998-09-11 |
|
|
Whistler |
Gwen |
bird |
1997-12-09 |
||
|
Slim |
Benny |
snake |
m |
1996-04-29 |
|
|
Puffball |
Diane |
hamster |
f |
1999-03-30 |
Exemplo de acesso via Hive
-
Adicione HADOOP_HOME e HADOOP_CLASSPATH ao arquivo /etc/profile. Exemplo:
export HADOOP_HOME=${YourHadoopInstallationDirectory} export HADOOP_CLASSPATH=emr-tablestore-1.4.2.jar:tablestore-4.3.1-jar-with-dependencies.jar:joda-time-2.9.4.jar -
Execute o comando
bin/hivepara iniciar o Hive e crie uma tabela externa. Exemplo:CREATE EXTERNAL TABLE pet (name STRING, owner STRING, species STRING, sex STRING, birth STRING, death STRING) STORED BY 'com.aliyun.openservices.tablestore.hive.TableStoreStorageHandler' WITH SERDEPROPERTIES( "tablestore.columns.mapping"="name,owner,species,sex,birth,death") TBLPROPERTIES ( "tablestore.endpoint"="YourEndpoint", "tablestore.access_key_id"="YourAccessKeyId", "tablestore.access_key_secret"="YourAccessKeySecret", "tablestore.table.name"="pet");A tabela a seguir descreve os itens de configuração.
Item de configuração Descrição WITH SERDEPROPERTIES Configuração de mapeamento de campos que inclui a opção
tablestore.columns.mapping.
Por padrão, os nomes dos campos da tabela externa correspondem aos nomes das colunas da tabela no Tablestore, sejam elas colunas de chave primária ou de atributo. Se os nomes dos campos da tabela externa não coincidirem com os nomes das colunas da tabela (por exemplo, ao lidar com diferenciação entre maiúsculas e minúsculas ou conjuntos de caracteres), especifiquetablestore.columns.mapping. Esse parâmetro é uma string separada por vírgulas. Não adicione espaços entre as vírgulas. Cada item representa um nome de coluna da tabela, e a ordem dos itens deve corresponder à ordem dos campos na tabela externa.NotaOs nomes das colunas do Tablestore podem conter caracteres de espaço em branco. Um caractere de espaço em branco é considerado parte do nome da coluna.
TBLPROPERTIES Configuração de propriedades da tabela. Inclui as seguintes opções:
tablestore.endpoint(Obrigatório): endpoint usado para acessar o Tablestore. Visualize o endpoint de uma instância no console do Tablestore. Para mais informações sobre endpoints, consulte Endpoints.tablestore.instance(Opcional): nome da instância do Tablestore. Se você deixar esse parâmetro em branco, o primeiro segmento detablestore.endpointserá usado. Para mais informações sobre instâncias, consulte Instances.tablestore.access_key_id(Obrigatório): AccessKey ID da sua conta Alibaba Cloud ou usuário do Resource Access Management (RAM). Para mais informações, consulte Obtain an AccessKey pair. Para usar o Security Token Service (STS) no acesso temporário a recursos, defina esse parâmetro como o AccessKey ID da credencial de acesso temporário.tablestore.access_key_secret(Obrigatório): AccessKey secret da sua conta Alibaba Cloud ou usuário RAM. Para mais informações, consulte Obtain an AccessKey pair. Para usar o STS no acesso temporário a recursos, defina esse parâmetro como o AccessKey secret da credencial de acesso temporário.tablestore.sts_token(Opcional): token de segurança da credencial de acesso temporário. Defina esse parâmetro apenas ao usar o STS para acessar recursos temporariamente. Para mais informações, consulte Use a RAM policy to grant permissions to a RAM user.tablestore.table.name(Obrigatório): nome da tabela correspondente no Tablestore.
-
Consulte os dados na tabela.
-
Execute o comando
SELECT * FROM pet;para consultar todas as linhas da tabela.O comando retorna o seguinte resultado:
Bowser Diane dog m 1979-08-31 1995-07-29 Buffy Harold dog f 1989-05-13 NULL Chirpy Gwen bird f 1998-09-11 NULL Claws Gwen cat m 1994-03-17 NULL Fang Benny dog m 1990-08-27 NULL Fluffy Harold cat f 1993-02-04 NULL Puffball Diane hamster f 1999-03-30 NULL Slim Benny snake m 1996-04-29 NULL Whistler Gwen bird NULL 1997-12-09 NULL Time taken: 5.045 seconds, Fetched 9 row(s) -
Execute o comando
SELECT * FROM pet WHERE birth > "1995-01-01";para consultar as linhas em que o valor da coluna birth é posterior a 1995-01-01.O comando retorna o seguinte resultado:
Chirpy Gwen bird f 1998-09-11 NULL Puffball Diane hamster f 1999-03-30 NULL Slim Benny snake m 1996-04-29 NULL Whistler Gwen bird NULL 1997-12-09 NULL Time taken: 1.41 seconds, Fetched 4 row(s)
-
Exemplo de acesso via HadoopMR
O exemplo a seguir mostra como usar um programa HadoopMR para contar as linhas na tabela de dados pet.
-
Crie mappers e reducers.
public class RowCounter { public static class RowCounterMapper extends Mapper<PrimaryKeyWritable, RowWritable, Text, LongWritable> { private final static Text agg = new Text("TOTAL"); private final static LongWritable one = new LongWritable(1); @Override public void map( PrimaryKeyWritable key, RowWritable value, Context context) throws IOException, InterruptedException { context.write(agg, one); } } public static class IntSumReducer extends Reducer<Text,LongWritable,Text,LongWritable> { @Override public void reduce( Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException { long sum = 0; for (LongWritable val : values) { sum += val.get(); } context.write(key, new LongWritable(sum)); } } }O método map() do mapper é chamado sempre que a fonte de dados lê uma linha do Tablestore. Os parâmetros PrimaryKeyWritable e RowWritable correspondem, respectivamente, à chave primária e ao conteúdo da linha. Chame PrimaryKeyWritable.getPrimaryKey() e RowWritable.getRow() para obter o objeto de chave primária e o objeto de linha definidos pelo SDK Java do Tablestore.
-
Configure o Tablestore como fonte de dados do mapper.
private static RangeRowQueryCriteria fetchCriteria() { RangeRowQueryCriteria res = new RangeRowQueryCriteria("YourTableName"); res.setMaxVersions(1); List<PrimaryKeyColumn> lower = new ArrayList<PrimaryKeyColumn>(); List<PrimaryKeyColumn> upper = new ArrayList<PrimaryKeyColumn>(); lower.add(new PrimaryKeyColumn("YourPkeyName", PrimaryKeyValue.INF_MIN)); upper.add(new PrimaryKeyColumn("YourPkeyName", PrimaryKeyValue.INF_MAX)); res.setInclusiveStartPrimaryKey(new PrimaryKey(lower)); res.setExclusiveEndPrimaryKey(new PrimaryKey(upper)); return res; } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "row count"); job.addFileToClassPath(new Path("hadoop-connector.jar")); job.setJarByClass(RowCounter.class); job.setMapperClass(RowCounterMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); job.setInputFormatClass(TableStoreInputFormat.class); TableStoreInputFormat.setEndpoint(job, "https://YourInstance.Region.ots.aliyuncs.com/"); TableStoreInputFormat.setCredential(job, "YourAccessKeyId", "YourAccessKeySecret"); TableStoreInputFormat.addCriteria(job, fetchCriteria()); FileOutputFormat.setOutputPath(job, new Path("output")); System.exit(job.waitForCompletion(true) ? 0 : 1); }Neste exemplo,
job.setInputFormatClass(TableStoreInputFormat.class)define o Tablestore como fonte de dados. Execute também as seguintes operações:Implante hadoop-connector.jar no cluster e adicione-o ao classpath. Use addFileToClassPath() para especificar o caminho local de hadoop-connector.jar. Este exemplo considera que hadoop-connector.jar está no caminho atual.
Especifique o endpoint e a identidade necessários para acessar o Tablestore. Use
TableStoreInputFormat.setEndpoint()eTableStoreInputFormat.setCredential()para definir o endpoint e as informações de AccessKey necessárias para o acesso ao Tablestore.Especifique a tabela a ser contada.
NotaCada chamada a addCriteria() adiciona um objeto RangeRowQueryCriteria (definido pelo SDK Java) à fonte de dados. É possível chamar addCriteria() várias vezes. O objeto RangeRowQueryCriteria está sujeito aos mesmos limites do objeto RangeRowQueryCriteria usado pela operação GetRange do SDK Java do Tablestore.
Use setFilter() e addColumnsToGet() de RangeRowQueryCriteria para filtrar linhas e colunas desnecessárias diretamente no servidor do Tablestore. Essa prática reduz o volume de dados acessados, diminui custos e melhora o desempenho.
Para realizar uma operação de união em várias tabelas, adicione vários objetos RangeRowQueryCriteria correspondentes a cada tabela.
Para dividir os dados de forma mais uniforme, adicione vários objetos RangeRowQueryCriteria para a mesma tabela. O conector Tablestore-Hadoop divide o intervalo especificado em intervalos menores com base em políticas específicas.
Exemplo de execução do programa
-
Defina HADOOP_CLASSPATH.
HADOOP_CLASSPATH=hadoop-connector.jar bin/hadoop jar row-counter.jar -
Execute o comando
find output -type fpara localizar todos os arquivos no diretório output.O comando retorna o seguinte resultado:
output/_SUCCESS output/part-r-00000 output/._SUCCESS.crc output/.part-r-00000.crc -
Execute o comando
cat output/part-r-00000para visualizar o número de linhas no resultado da execução.TOTAL 9
Notas sobre conversão de tipos
Os tipos de dados compatíveis com o Tablestore não são exatamente iguais aos tipos de dados compatíveis com o Hive ou Spark.
A tabela a seguir descreve a compatibilidade de conversão dos tipos de dados do Tablestore (linhas) para os tipos de dados do Hive ou Spark (colunas).
|
Conversão de tipo |
TINYINT |
SMALLINT |
INT |
BIGINT |
FLOAT |
DOUBLE |
BOOLEAN |
STRING |
BINARY |
|
INTEGER |
Compatível, com perda de precisão |
Compatível, com perda de precisão |
Compatível, com perda de precisão |
Compatível |
Compatível, com perda de precisão |
Compatível, com perda de precisão |
Não compatível |
Não compatível |
Não compatível |
|
DOUBLE |
Compatível, com perda de precisão |
Compatível, com perda de precisão |
Compatível, com perda de precisão |
Compatível, com perda de precisão |
Compatível, com perda de precisão |
Compatível |
Não compatível |
Não compatível |
Não compatível |
|
BOOLEAN |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Compatível |
Não compatível |
Não compatível |
|
STRING |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Compatível |
Não compatível |
|
BINARY |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Não compatível |
Compatível |