本文將進一步為您介紹如何將來自Tablestore(原OTS)的資料納入MaxCompute上的計算生態,實現多種資料來源之間的無縫串連。
背景資訊
Table Store(Tablestore)是構建在阿里雲飛天分布式系統之上的NoSQL資料存放區服務,提供海量結構化資料的儲存和即時訪問,詳情請參見Tablestore文檔。
您可以通過DataWorks配合MaxCompute對外部表格進行可視化的建立、搜尋、查詢、配置、加工和分析。詳情請參見外部表格。
注意事項
MaxCompute與Tablestore是兩個獨立的巨量資料計算和儲存服務,所以兩者之間的網路必須保證連通性。MaxCompute公用雲端服務訪問Tablestore儲存時,推薦您使用Tablestore私網地址,即Host名以ots-internal.aliyuncs.com作為結尾的地址,例如tablestore://odps-ots-dev.cn-shanghai.ots-internal.aliyuncs.com。
Tablestore與MaxCompute都有其自身的類型系統。在MaxCompute處理Tablestore資料時,兩者之間的資料類型對應關係如下所示。
MaxCompute Type
Tablestore Type
STRING
STRING
BIGINT
INTEGER
DOUBLE
DOUBLE
BOOLEAN
BOOLEAN
BINARY
BINARY
Tablestore外部表格不支援cluster屬性。
前提條件
已授權訪問OTS的許可權。具體授權操作詳情,請參見OTS的STS模式授權。
已建立Tablestore執行個體、表和資料。具體操作,請參見通過控制台使用寬表模型。
建立外部表格
MaxCompute通過建立外部表格,把對Tablestore表資料的描述引入到MaxCompute的meta系統內部後,即可實現對Tablestore資料的處理。本節通過下述樣本為您說明MaxCompute對接Tablestore的一些概念和實現。
建立外部表格語句樣本如下。
DROP TABLE IF EXISTS ots_table_external;
CREATE EXTERNAL TABLE IF NOT EXISTS ots_table_external
(
odps_orderkey bigint,
odps_orderdate string,
odps_custkey bigint,
odps_orderstatus string,
odps_totalprice double,
odps_createdate timestamp
)
STORED BY 'com.aliyun.odps.TableStoreStorageHandler'
WITH SERDEPROPERTIES (
'tablestore.columns.mapping'=':o_orderkey,:o_orderdate,o_custkey,o_orderstatus,o_totalprice',
'tablestore.table.name'='ots_tpch_orders',
'odps.properties.rolearn'='acs:ram::xxxxx:role/aliyunodpsdefaultrole',
'tablestore.read.mode'='permissive',
'tablestore.corrupt.column'='ColumnName',
'tablestore.timestamp.ticks.unit'='seconds',
'tablestore.column.odps_createdate.timestamp.ticks.unit'='millis',
'tablestore.table.put.row'='true'
)
LOCATION 'tablestore://odps-ots-dev.cn-shanghai.ots-internal.aliyuncs.com';
上述建表語句重點參數介紹如下表所示。
參數 | 是否必填 | 說明 |
com.aliyun.odps.TableStoreStorageHandler | 是 | 是MaxCompute內建的處理Tablestore資料的StorageHandler,定義了MaxCompute和Tablestore的互動,相關邏輯由MaxCompute實現。 |
tablestore.columns.mapping | 是 | 描述MaxCompute將訪問的Tablestore表的列,包括主鍵和屬性列。
|
tablestore.table.name | 是 | 需要訪問的Tablestore表名稱。本文以 |
odps.properties.rolearn | 是 | RAM中AliyunODPSDefaultRole的ARN資訊。您可以通過RAM控制台中的RAM角色管理進行擷取。 |
tablestore.timestamp.ticks.unit | 否 | 表層級時間類型設定。用以指定該外部表格中所有Integer的欄位都處於同一個時間類型。取值如下:
|
tablestore.column.<col1_name>.timestamp.ticks.unit | 否 | 列層級時間類型設定。用以指定該外部表格中欄欄位的時間類型。取值如下:
說明 tablestore.timestamp.ticks.unit和tablestore.column.<col1_name>.timestamp.ticks.unit都配置時,tablestore.column.<col1_name>.timestamp.ticks.unit參數的優先順序更高。 |
tablestore.table.put.row | 否 | 支援指定PutRow的寫入方式。取值說明如下:
說明 可以通過設定以下Flag的參數值指定PutRow的寫入方式,預設值為False。詳情請參見Flag參數列表。
|
tablestore.read.mode | 否 | 當遇到髒資料時行為定義欄位,取值說明如下:
關於髒資料處理樣本,詳情請參見髒資料處理樣本。 |
tablestore.corrupt.column | 否 | 指定髒資料寫入列。
關於髒資料處理樣本,詳情請參見髒資料處理樣本。 |
LOCATION | 是 | 用來指定Tablestore的Instance名、Endpoint等具體資訊。這裡的Tablestore資料的安全訪問建立在前文介紹的RAM/STS授權的前提上。 說明 如果您使用公網地址報錯,顯示網路不同,可嘗試更換為經典網地址。 |
您可以執行如下語句,查看建立好的外部表格結構資訊。
desc extended <table_name>;
在返回的資訊裡,除了包含和內部表一樣的基礎資訊,Extended Info還包含外部表格StorageHandler、Location等資訊。
查詢外部表格
建立完外部表格後,Tablestore的資料便引入到了MaxCompute生態中,即可通過正常的MaxCompute SQL文法訪問Tablestore資料,如下所示。
SELECT odps_orderkey, odps_orderdate, SUM(odps_totalprice) AS sum_total
FROM ots_table_external
WHERE odps_orderkey > 5000 AND odps_orderkey < 7000 AND odps_orderdate >= '1996-05-03' AND odps_orderdate < '1997-05-01'
GROUP BY odps_orderkey, odps_orderdate
HAVING sum_total> 400000.0;
在查詢表或欄位時,無需區分大小寫,且不支援強制轉換大小寫。
使用常見的MaxCompute SQL語句訪問Tablestore時,所有的操作細節(例如列名的選擇)是在MaxCompute內部處理完成的。上述SQL樣本中,使用的列名是odps_orderkey、odps_totalprice等,而不是原始Tablestore中的主鍵名o_orderkey或屬性列名o_totalprice。這是因為在建立外部表格的DDL語句中,已經完成了對應的Mapping。您也可以在建立外部表格時,按需選擇保留原始的Tablestore主鍵/列名。
如果您需要對一份資料做多次計算,相比每次從Tablestore去遠程讀資料,更高效的方法是先一次性把需要的資料匯入到MaxCompute內部成為一個MaxCompute(內部)表,樣本如下。
CREATE TABLE internal_orders AS
SELECT odps_orderkey, odps_orderdate, odps_custkey, odps_totalprice
FROM ots_table_external
WHERE odps_orderkey > 5000 ;
現在internal_orders就是一個MaxCompute表了,也擁有所有MaxCompute內部表的特性,包括高效的壓縮列儲存資料格式、完整的內部宏資料以及統計資訊等。同時因為表格儲存體在MaxCompute內部,所以訪問速度會比訪問外部的Tablestore更快。這種方法非常適用於需要進行多次計算的熱點資料。
MaxCompute匯出資料到Tablestore
MaxCompute不會主動建立外部的Tablestore表,所以在對Tablestore表進行資料輸出之前,必須保證該表已經在Tablestore上完成建立(否則將報錯)。
根據上面的操作,您已建立了外部表格ots_table_external來打通MaxCompute與Tablestore資料表ots_tpch_orders的鏈路,同時還有一份儲存在MaxCompute內部表internal_orders的資料。現在,如果您需要對internal_orders中的資料進行處理後再寫回Tablestore,則可通過對外部表格執行insert overwrite table
操作實現,樣本如下。
INSERT OVERWRITE TABLE ots_table_external
SELECT odps_orderkey, odps_orderdate, odps_custkey, CONCAT(odps_custkey, 'SHIPPED'), CEIL(odps_totalprice)
FROM internal_orders;
如果MaxCompute表內資料本身有一定的順序,例如已經按照Primary Key做過一次排序,則在寫入到OTS表時,會導致壓力集中在一個OTS分區上面,無法充分利用分布式寫入的特點。因此,當出現這種情況時,建議您通過distribute by rand()
先將資料打散,樣本如下。
INSERT OVERWRITE TABLE ots_table_external
SELECT odps_orderkey, odps_orderdate, odps_custkey, CONCAT(odps_custkey, 'SHIPPED'), CEIL(odps_totalprice)
FROM (SELECT * FROM internal_orders DISTRIBUTE BY rand()) t;
對於Tablestore這種KV資料的NoSQL儲存介質,MaxCompute的輸出將隻影響相對應主鍵所在的行,例如樣本中隻影響所有odps_orderkey + odps_orderdate這兩個主索引值對應行上的資料。而且在這些Tablestore行上,也只會更新在建立外部表格(ots_table_external)時指定的屬性列,而不會修改未在外部表格中出現的資料列。
將MaxCompute中的資料寫入OTS時一次不能超過4MB,否則需要使用者剔除掉超巨量資料再寫入。此時可能會產生報錯。
ODPS-0010000:System internal error - Output to TableStore failed with exception: TableStore BatchWrite request id XXXXX failed with error code OTSParameterInvalid and message:The total data size of BatchWriteRow request exceeds the limit
將資料批量寫入或分行寫入,都算一次操作。詳細描述請參考BatchWriteRow。因此如果批量寫入資料量太大,也可以分行寫入。
將資料批量寫入時請注意不要有重複行,否則可能產生如下報錯。
ErrorCode: OTSParameterInvalid, ErrorMessage: The input parameter is invalid
由於Tablestore是KV儲存,使用
insert overwrite table
寫入資料到Tablestore表,不會清空目標Tablestore表的全部內容,只會覆蓋目標表中Key一致的Value值。
髒資料處理樣本
準備Tablestore表
mf_ots_test
和資料。具體操作,請參見通過控制台使用寬表模型。預設Tablestore的表格式資料如下所示。
+----+------+------+ | id | name | desc | +----+------+------+ | 1 | 張三 | 張三的描述 | +----+------+------+
建立MaxCompute外部表格。
CREATE EXTERNAL TABLE IF NOT EXISTS mf_ots_external_permi ( id string, name bigint, desc string, corrupt_col string ) STORED BY 'com.aliyun.odps.TableStoreStorageHandler' WITH SERDEPROPERTIES ( 'tablestore.columns.mapping'=':id,name,desc', 'tablestore.table.name'='mf_ots_test', 'tablestore.read.mode'='permissive', 'tablestore.corrupt.column'='corrupt_col', 'odps.properties.rolearn'='acs:ram::139699392458****:role/aliyunodpsdefaultrole' ) LOCATION 'tablestore://santie-doc.cn-shanghai.ots-internal.aliyuncs.com';
執行以下代碼,查詢MaxCompute外部表格資料。
---查詢資料 select * from mf_ots_external_permi;
返回結果如下,錯誤欄位會以JSON格式寫入至
corrupt_col
列中。-- +------------+------------+------------+-------------+ | id | name | desc | corrupt_col | +------------+------------+------------+-------------+ | 1 | NULL | 張三的描述 | {"name": "\"張三\""} | +------------+------------+------------+-------------+
說明若tablestore.read.mode未配置或配置為permissive,但未配置tablestore.corrupt.column指定髒資料存入列,查詢外表時會報錯
“Columns not match with columns mapping and corrupt column”
。