BigQuery存储API。Avro

303 阅读3分钟

BigQuery存储API。Avro

发布者::Emmanouil Gkatziouras inEnterprise Java June 30th, 2021 0 Views

之前我们对BigQuery存储API进行了介绍,我们使用Arrow格式读取数据。在本教程中,我们将使用Avro格式读取数据。

上一个教程中的内容也适用于此。

我们将创建一个BigQuery存储客户端,使用Avro格式创建一个ReadSession,并在每个流上迭代数据。

让我们从导入依赖性开始,我们需要导入Avro库。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>20.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-bigquerystorage</artifactId>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>

我们的下一步将是为我们的行创建一个Avro数据阅读器,这些行的模式是col1:string, col2:int。在我们的例子中,我们将通过sys.out打印数据

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.gkatzioura.bigquery.storage.api.avro;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.BinaryDecoder;
import org.apache.avro.io.DecoderFactory;
import com.google.cloud.bigquery.storage.v1.AvroSchema;
import com.google.protobuf.ByteString;
public class AvroReader {
private final GenericDatumReader<GenericRecord> datumReader;
public AvroReader(AvroSchema arrowSchema) {
Schema schema =new Schema.Parser().parse(arrowSchema.getSchema());
this.datumReader =new GenericDatumReader<>(schema);
}
public void processRows(ByteString avroRows)throws IOException {
try(InputStream inputStream =new ByteArrayInputStream(avroRows.toByteArray())) {
BinaryDecoder decoder =DecoderFactory.get().binaryDecoder(inputStream,null);
while (!decoder.isEnd()) {
GenericRecord item = datumReader.read(null, decoder);
System.out.println(item.get("col1")+","+item.get("col2"));
}
}
}
}

然后到我们的主类,这是一个有任何BigQuery逻辑需要的类。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.gkatzioura.bigquery.storage.api.avro;
import org.apache.arrow.util.Preconditions;
import com.google.api.gax.rpc.ServerStream;
import com.google.cloud.bigquery.storage.v1.BigQueryReadClient;
import com.google.cloud.bigquery.storage.v1.CreateReadSessionRequest;
import com.google.cloud.bigquery.storage.v1.DataFormat;
import com.google.cloud.bigquery.storage.v1.ReadRowsRequest;
import com.google.cloud.bigquery.storage.v1.ReadRowsResponse;
import com.google.cloud.bigquery.storage.v1.ReadSession;
public class AvroMain {
public static void main(String[] args)throws Exception {
String projectId = System.getenv("PROJECT_ID");
try (BigQueryReadClient client = BigQueryReadClient.create()) {
String parent = String.format("projects/%s", projectId);
String srcTable =
String.format(
"projects/%s/datasets/%s/tables/%s",
projectId, System.getenv("DATASET"), System.getenv("TABLE"));
ReadSession.Builder sessionBuilder =
ReadSession.newBuilder()
.setTable(srcTable)
.setDataFormat(DataFormat.AVRO);
CreateReadSessionRequest.Builder builder =
CreateReadSessionRequest.newBuilder()
.setParent(parent)
.setReadSession(sessionBuilder)
.setMaxStreamCount(1);
ReadSession session = client.createReadSession(builder.build());
Preconditions.checkState(session.getStreamsCount() >0);
String streamName = session.getStreams(0).getName();
ReadRowsRequest readRowsRequest =
ReadRowsRequest.newBuilder().setReadStream(streamName).build();
ServerStream<ReadRowsResponse> stream = client.readRowsCallable().call(readRowsRequest);
for (ReadRowsResponse response : stream) {
new AvroReader(session.getAvroSchema()).processRows(response.getAvroRows().getSerializedBinaryRows());
}
}
}
}

一个BigQuery客户端被创建。然后,我们创建一个具有最大数据流数量的会话请求。我们指定要使用的格式是Avro。
一旦我们得到一个响应,该响应将包含发起的会话、Avro模式和我们将用于检索数据的流。
对于每个流,必须有一个ReadRowsRequest,以便获取数据。
然后我们把数据传给我们的Avro解码器。

就这样,我们使用Avro和Arrow从BigQuery存储API中读取数据。

由我们JCG项目的合伙人Emmanouil Gkatziouras授权发表在Java Code Geeks上。在此查看原文。BigQuery存储API。Avro

Java Code Geeks撰稿人所表达的观点属于他们自己。

大数据 2021-06-30

Emmanouil Gkatziouras