BigQuery連接S3內的json檔案作為外部table
BigQuery Omni
透過BigQuery Omni可直接在BigQuery中存取外部雲端平台的data store
例如AWS S3、Azure Blob Storage
好處
若有資料在別的雲端平台
不用透過定時搬移、複製等方式同步至GCP中
而是直接透過BigQuery即時存取跨雲平台的資料
設定AWS IAM Policy
依照官方文件設定即可
Policy JSON
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":[
"s3:ListBucket"
],
"Resource":[
"arn:aws:s3:::bucket-name"
]
},
{
"Effect":"Allow",
"Action":[
"s3:GetObject"
],
"Resource":[
"arn:aws:s3:::bucket-name",
"arn:aws:s3:::bucket-name/*"
]
}
]
}
建立AWS IAM Role
一樣依照官方文件設定即可
Trusted entity: Web Identity
Provider: Google
Audience: 先設定為00000就好
建立S3 Connection
建立External data source
在Console BigQuery頁面中點擊Explorer旁的"ADD DATA"按鈕
再點擊"Connections to external data"
設定BigLake on AWS
主要設定如下
- Connection type: BigLake on AWS
- Conection ID: 自行設定
- Connection location: 目前只支援一個region不用特別選
- AWS role id: 剛才上面設定的AWS IAM Role ARN
設定完成
設定完成之後會看到下方畫面
要將BigQuery Google Identity的值複製起來
後續需要在AWS設定上使用
為AWS IAM Role設定Trust Relationship
依照官方文件前往IAM Role
將Maximum session duration設定為12小時
設定Trust Relationship(Policy JSON如下)
accounts.google.com:sub要設定為前面開好的BigQuery external connection BigQuery Google Identity
{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Principal":{
"Federated":"accounts.google.com"
},
"Action":"sts:AssumeRoleWithWebIdentity",
"Condition":{
"StringEquals":{
"accounts.google.com:sub":"bigquery-google-identity"
}
}
}
]
}
建立dataset/table
建立一個dataset
region一定要選擇"aws-us-east-1"
建立table
主要設定如下
- Create table from: Amazon S3
- S3 path: s3://BUCKET_NAME/PATH
- File format: JSONL
- Connection ID: 選擇前面建立的Connection
Schema可使用Auto detect
建立的時候將會自動去抓符合的JSON把裡面的key全部設定為schema field
S3 Path wildcard支援
S3 Path可使用wildcard
例如: s3://my-bucket/folder1/*-data.json
BigQuery Omni會自動讀取folder1目錄底下所有檔名包含"-data.json"的檔案(可接受巢狀結構)
關於JSONL格式
JSONL(Newline delimited JSON)
透過換行來區分資料的JSON格式
一般JSON多筆紀錄範例格式
[
{"name": "A", "age": 30},
{"name": "B", "age": 40}
]
JSONL格式
{"name": "A", "age": 30}
{"name": "B", "age": 40}
支援的Region
BigQuery Omni支援的Region非常少
- AWS: aws-us-east-1
- Azure: azure-eastus2
限制
這邊提出幾個比較重要的限制
- 所有External Table的限制都包含
- 每次查詢結果大小最多10GB
- 每個project的一天的總查詢大小1TB
注意事項
JSON格式不可包含Schema不允許的field name規則
因為JSON的key會被拿來當schema field
所以JSON的key如果出現schema不允許的規則
就會出現"Invalid field name"錯誤
例如JSON使用一個"foo-bar"欄位
schema不允許dash符號
{"eventId": "event-10", "service": "ec2", "action": "ec2.instance.update", "foo-bar": "foobar" }
這時候就會出現這種錯誤
Schema不會自動更新
即使建立table的時候schema使用auto detect
若新匹配的json出現新的欄位
也不會出現在Query結果中
例如建立table的時候匹配的JSON格式只有"name"跟"age"
{"name": "A", "age": 30}
{"name": "B", "age": 40}
若後續新匹配的JSON出現新的欄位"city"
Query仍可以正常使用
但query中無法使用city欄位
即使用"SELECT *"SQL Query結果也不會顯示city欄位
必須要手動新增schema field才能使用city欄位
{"name": "C", "age": 29, "city": "Taipei"}
{"name": "D", "age": 35, "city": "Taichung"}
使用了非JSONL格式
將會出現"Fail to parse JSON"的錯誤
不正確使用換行
不OK, 換行規則不對(JSONL遇到換行就是要一筆新的資料)
{
"arr": ["A", "B", "C"]
}
OK
{ "arr": ["A", "B", "C"] }
呈現多筆的方式錯誤
不OK(使用了標準JSON多筆資料格式)
[
{ "element": "A"},
{ "element": "B"}
]
OK
{ "element": "A"}
{ "element": "B"}
總結
BigQuery Omni雖然可直接讀取S3很方便
但限制不少
適合的情境比較偏向不會太巨量的資料
在這種情況下使用BQ直接存取第三方的檔案的確是一種不錯的選擇