透過 Redshift Spectrum,可以直接查詢 S3 資料湖中的資料,無需載入到 Redshift 叢集。設定過程包含建立 IAM 角色賦予 S3 和 AWS Glue 許可權,並將其附加到 Redshift 叢集。完成後,可建立外部表格和分割區,對應 S3 上的資料結構。為提升查詢效能,可將常用資料集載入本地 Redshift 表格,減少 Redshift Spectrum 查詢成本。文章示範瞭如何建立本地表格、載入資料,並使用 SQL 進行地理空間資料分析,例如計算房源與旅遊景點的距離。此方法有效結合了 S3 的儲存優勢和 Redshift 的查詢效能,提供更彈性的資料處理方案。
建立 Amazon Redshift Spectrum 的 IAM 角色與 Redshift 叢集
Amazon Redshift Spectrum 允許叢集直接讀取儲存在 Amazon S3 資料湖中的資料,而無需將資料載入叢集中。Redshift Spectrum 使用 AWS Glue 資料目錄,因此除了 Amazon S3 許可權外,還需要 AWS Glue 許可權。如果在 AWS Glue 不支援的區域操作,則 Redshift Spectrum 使用 Amazon Athena 目錄,因此需要 Amazon Athena 許可權。
建立具有 Redshift Spectrum 許可權的 IAM 角色
要建立具有所需 Redshift Spectrum 許可權的 IAM 角色,請遵循以下步驟:
導航至 AWS IAM 管理控制檯,點選左側的 Roles,然後點選 Create role。
確保為 Select type of trusted entity 選擇 AWS service,然後從服務清單中選擇 Redshift。對於 Select your use case,選擇 Redshift – Customizable。點選 Next: Permissions。
將以下三個策略附加到角色:
AmazonS3FullAccessAWSGlueConsoleFullAccessAmazonAthenaFullAccess
內容解密:
AmazonS3FullAccess:提供對 Amazon S3 的完整存取許可權。AWSGlueConsoleFullAccess:提供對 AWS Glue 控制檯的完整存取許可權。AmazonAthenaFullAccess:提供對 Amazon Athena 的完整存取許可權。
提供角色名稱,例如
AmazonRedshiftSpectrumRole。確保步驟 3 中列出的三個策略已包含在內,且 Trusted entities 設定為AWS service: redshift.amazonaws.com。確認後,點選 Create role。搜尋您剛建立的角色並點選角色名稱。在 Summary 畫面中,記錄 Role ARN,稍後將會用到。
建立 Redshift 叢集
建立具有 Redshift Spectrum 許可權的 IAM 角色後,我們可以繼續建立 Redshift 叢集並將 IAM 策略附加到叢集。
- 導航至 Amazon Redshift 控制檯,點選 Create cluster。
- 可以更改或保留預設的 Redshift 叢集名稱(
redshift-cluster-1),但請確保為 What are you planning to use this cluster for? 選擇 Free trial。 - 保留預設的管理員使用者名稱(
awsuser),但提供管理員使用者密碼。確保稍後可以回憶此密碼,因為在未來步驟中將會用到。點選 Create cluster。 - 等待直到您的叢集列出且狀態為 Available,然後點選叢集名稱。
將 IAM 角色附加到 Redshift 叢集
點選 Properties 索引標籤,向下滾動到 Cluster permissions 部分,然後點選 Attach IAM roles 按鈕。
選擇先前為 Redshift Spectrum 建立的角色(例如
AmazonRedshiftSpectrumRole),然後點選 Associate IAM role 按鈕。然後,點選 Save changes。內容解密:
- 將 IAM 角色附加到 Redshift 叢集,以授予叢集存取 S3 資料湖的許可權。
- 等待幾分鐘,讓許可權修改生效。
在 Redshift 控制檯左側點選 Editor,然後點選 Connect to database。
保留預設的 Create a new connection,並將 Authentication 設定為 Temporary credentials。確保您的叢集已從下拉清單中選取,然後輸入
dev作為 Database name 和awsuser作為 Database user。然後,點選 Connect。連線後,確保
dev已設定為 Select database,且public已設定為 Select schema。然後,在查詢編輯器中執行select * from sales limit 10,並點選 Run。
select * from sales limit 10;
內容解密:
- 此 SQL 查詢從
sales表格中選取前 10 行資料。 - 使用
limit子句限制結果集的大小。 - 此查詢用於測試 Redshift 連線和查詢功能。
重點整理
- 建立具有 Redshift Spectrum 許可權的 IAM 角色。
- 將 IAM 角色附加到 Redshift 叢集。
- 使用 Redshift 控制檯連線到資料函式庫並執行查詢。
在Amazon Redshift中載入資料並執行查詢
在建立並驗證Redshift叢集後,我們可以建立外部表格以查詢S3中的資料。
建立外部表格以查詢S3中的資料
要使用Redshift Spectrum查詢Amazon S3中的資料,我們需要定義資料函式庫、架構和表格。
Redshift與AWS Glue的術語差異
在Amazon Redshift中,資料函式庫是一個頂層容器,包含一個或多個架構,每個架構可以包含一個或多個表格。在AWS Glue中,沒有架構的概念,只有資料函式庫,表格直接在資料函式庫中建立。
建立外部架構和表格
- 在Redshift查詢編輯器中執行以下命令,建立一個名為
spectrum_schema的外部架構,並在Glue目錄中建立一個名為accommodations的資料函式庫。請確保將iam_roleARN替換為之前建立Redshift Spectrum角色時記錄的ARN:
create external schema spectrum_schema
from data catalog
database 'accommodation'
iam_role 'arn:aws:iam::1234567890:role/AmazonRedshiftSpectrumRole'
create external database if not exists;
建立外部表格
- 定義一個外部表格,該表格將在Glue資料目錄中的
accommodations資料函式庫下註冊。定義表格時,指定存在的欄位、分割資料的欄位(city)、檔案格式(文字、逗號分隔)以及上傳文字檔案的S3位置。請確保將S3位置的儲存桶名稱替換為您建立的儲存桶名稱:
CREATE EXTERNAL TABLE spectrum_schema.listings(
listing_id INTEGER,
name VARCHAR(100),
host_id INT,
host_name VARCHAR(100),
neighbourhood_group VARCHAR(100),
neighbourhood VARCHAR(100),
latitude Decimal(8,6),
longitudes Decimal(9,6),
room_type VARCHAR(100),
price SMALLINT,
minimum_nights SMALLINT,
number_of_reviews SMALLINT,
last_review DATE,
reviews_per_month NUMERIC(8,2),
calculated_host_listings_count SMALLINT,
availability_365 SMALLINT)
partitioned by(city varchar(100))
row format delimited
fields terminated by ','
stored as textfile
location 's3://dataeng-landing-zone-initials/listings/';
詳細解說:
此段程式碼的作用是建立一個名為listings的外部表格,並定義其欄位、分割欄位、檔案格式和S3位置。其中,partitioned by(city varchar(100))表示資料按照city欄位進行分割。
row format delimited fields terminated by ','表示檔案中的欄位是以逗號分隔的。stored as textfile表示資料儲存為文字檔案。location 's3://dataeng-landing-zone-initials/listings/'指定了S3中資料的位置。
- 驗證表格是否正確建立,方法是從左側下拉選單中選擇
spectrum_schema,然後展開listings表格以檢視定義的欄位。
新增分割區
- 執行以下兩個命令,在Redshift查詢編輯器中新增我們建立的特定分割區。請確保更新位置,以便參考您的儲存桶名稱:
alter table spectrum_schema.listings add
partition(city='jersey_city')
location 's3://dataeng-landing-zone-initials/listings/city=jersey_city/'
alter table spectrum_schema.listings add
partition(city='new_york_city')
location 's3://dataeng-landing-zone-initials/listings/city=new_york_city/'
詳細解說:
此段程式碼的作用是為listings表格新增兩個分割區,分別對應jersey_city和new_york_city。這樣可以提高查詢效率,因為查詢可以針對特定的分割區進行。
alter table spectrum_schema.listings add partition(city='jersey_city')新增了一個名為jersey_city的分割區。location 's3://dataeng-landing-zone-initials/listings/city=jersey_city/'指定了該分割區對應的S3位置。
- 在AWS Glue控制檯中驗證表格和分割區是否正確建立。開啟AWS Glue控制檯,點選左側導航選單中的資料函式庫。
- 點選我們先前建立的名為
accommodation的Glue資料函式庫,然後點選Tables in accommodation。 - 點選listings表格,將列出我們定義的欄位。
圖表說明
此圖示呈現了在AWS Glue控制檯中檢視listings表格的欄位定義。
8. 點選View Partitions按鈕以檢視已定義的分割區。
圖表說明
此圖示呈現了在AWS Glue控制檯中檢視listings表格的分割區。
驗證查詢結果
- 在Redshift查詢編輯器中執行以下查詢,以確認一切設定正確:
select * from spectrum_schema.listings limit 100;
- 開啟Amazon Athena控制檯,執行以下查詢:
select * from accommodation.listings limit 100;
現在,我們已經組態Redshift Spectrum能夠讀取上傳到Amazon S3的檔案,可以設計一個Redshift表格來在本機儲存所需的資料。
將資料載入 Amazon Redshift 叢集並執行查詢
為本地 Redshift 表建立結構描述
使用 Redshift Spectrum 時,每次查詢都會根據掃描的資料量收費。如果有經常查詢的熱門資料集,可以將需要的資料移到本地 Redshift 表中,以避免每次查詢都收費。根據查詢型別,還可能發現查詢本地儲存的資料比透過 Redshift Spectrum 查詢 Amazon S3 上的資料效能更好。
建立本地 Redshift 表
首先,建立新的 Redshift 結構描述來儲存本地表:
CREATE SCHEMA IF NOT EXISTS accommodation_local;
接著,建立新的本地表,包含所需的欄位:
CREATE TABLE dev.accommodation_local.listings(
listing_id INTEGER,
name VARCHAR(100),
neighbourhood_group VARCHAR(100),
neighbourhood VARCHAR(100),
latitude Decimal(8,6),
longitudes Decimal(9,6),
room_type VARCHAR(100),
price SMALLINT,
minimum_nights SMALLINT,
city VARCHAR(40))
DISTKEY(listing_id)
SORTKEY(price);
載入資料到本地表
使用以下查詢將資料從外部 Spectrum 表載入到新的本地表中:
INSERT INTO accommodation_local.listings
(SELECT
listing_id,
name,
neighbourhood_group,
neighbourhood,
latitude,
longitudes,
room_type,
price,
minimum_nights
FROM spectrum_schema.listings);
內容解密:
CREATE SCHEMA IF NOT EXISTS accommodation_local;:建立一個名為accommodation_local的結構描述,如果該結構描述不存在。CREATE TABLE dev.accommodation_local.listings...:在dev資料函式庫的accommodation_local結構描述中建立一個名為listings的表。定義了各個欄位,並指定listing_id為分佈鍵,price為排序鍵。INSERT INTO accommodation_local.listings...:將資料從spectrum_schema.listings表中選擇所需的欄位,並插入到accommodation_local.listings表中。
對資料執行複雜的 SQL 查詢
現在可以對剛剛載入資料的本地 listings 表執行一些進階查詢。目標是能夠輕鬆識別紐約市和澤西市地區靠近特定旅遊景點的 Airbnb 房源。
查詢步驟
- 建立臨時表
touristspots_raw和touristspots:
WITH touristspots_raw(name, lon, lat) AS (
(SELECT 'Freedom Tower', -74.013382, 40.712742) UNION
(SELECT 'Empire State Building', -73.985428, 40.748817)
),
touristspots(name, location) AS (
SELECT name, ST_Point(lon, lat) FROM touristspots_raw
)
SELECT name, location FROM touristspots;
內容解密:
WITH touristspots_raw(name, lon, lat) AS ...:建立一個臨時表touristspots_raw,包含紐約市兩個著名旅遊景點的名字、經度和緯度。touristspots(name, location) AS ...:將touristspots_raw中的經緯度轉換為點幾何(point geometry),以便進行距離計算。SELECT name, location FROM touristspots;:查詢touristspots表,取得旅遊景點的名字和位置。將住宿資料的經緯度轉換為點幾何:
WITH accommodation(listing_id, name, room_type, location) AS (
SELECT listing_id, name, room_type, ST_Point(longitudes, latitude)
FROM accommodation_local.listings
)
SELECT listing_id, name, room_type, location FROM accommodation;
內容解密:
WITH accommodation(listing_id, name, room_type, location) AS ...:建立一個臨時表accommodation,包含listings表中的資料,並將經緯度轉換為點幾何。SELECT listing_id, name, room_type, location FROM accommodation;:查詢accommodation表,取得房源的 ID、名字、房型和位置。結合前兩個查詢,計算房源與旅遊景點之間的距離:
WITH touristspots_raw(name, lon, lat) AS (
(SELECT 'Freedom Tower', -74.013382, 40.712742) UNION
(SELECT 'Empire State Building', -73.985428, 40.748817)
),
touristspots(name, location) AS (
SELECT name, ST_Point(lon, lat) FROM touristspots_raw
),
accommodation(listing_id, name, room_type, price, location) AS (
SELECT listing_id, name, room_type, price, ST_Point(longitudes, latitude)
FROM accommodation_local.listings
)
-- 這裡省略了最終的距離計算和排序部分,請參考原始查詢完成。
內容解密:
- 結合前兩個查詢,建立包含旅遊景點和房源位置的臨時表。
- 使用這些臨時表計算房源與旅遊景點之間的距離,並按距離排序,傳回最近的 100 個房源。
此圖示顯示了查詢的流程和各個部分的邏輯關係。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Redshift Spectrum 設定與資料查詢最佳化
package "資料庫架構" {
package "應用層" {
component [連線池] as pool
component [ORM 框架] as orm
}
package "資料庫引擎" {
component [查詢解析器] as parser
component [優化器] as optimizer
component [執行引擎] as executor
}
package "儲存層" {
database [主資料庫] as master
database [讀取副本] as replica
database [快取層] as cache
}
}
pool --> orm : 管理連線
orm --> parser : SQL 查詢
parser --> optimizer : 解析樹
optimizer --> executor : 執行計畫
executor --> master : 寫入操作
executor --> replica : 讀取操作
cache --> executor : 快取命中
master --> replica : 資料同步
note right of cache
Redis/Memcached
減少資料庫負載
end note
@enduml
此圖示說明瞭查詢過程中的主要步驟和它們之間的關係。