本文介紹如何將來自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的許可權。具體授權操作詳情,請參見訪問外部資料源授權方案。
已建立Tablestore執行個體、表和資料。具體操作,請參見寬表模型快速入門。
許可權說明
訪問 Tablestore 外部表格時,無論使用阿里雲帳號(主帳號)、RAM 使用者還是 RAM Role 身份,均通過
odps.properties.rolearn參數指定角色的許可權訪問 Tablestore 資料。因此,需要建立 RAM 角色並授予其訪問 Tablestore 的許可權,再將該角色的 ARN 配置到odps.properties.rolearn參數中。建立角色支援一鍵授權和自訂授權兩種方式,詳情請參見OSS/OTS的RAM普通角色授權。
odps.properties.rolearn參數的詳細說明請參見參數說明。
建立外部表格
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/<role_name>',
'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中Role(具有訪問OSS許可權)的ARN資訊,通過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”。
常見問題
基於Tablestore外部表格執行SQL作業時,運行慢,如何解決?
查詢外部表格Tablestore資料慢
問題現象
查詢外部表格Tablestore的資料慢,同樣的業務資料,1個即時寫入Tablestore,1個定時寫入MaxCompute,兩個表結構和資料量一樣。查詢MaxCompute內部表耗時遠小於查詢Tablestore外部表格。
解決措施
這種情況可能是對1份資料進行了多次計算,導致速度慢。相比每次從Tablestore遠程讀取資料,更高效快速的方法是先一次性把需要的資料匯入到MaxCompute內部,轉為MaxCompute內部表,再進行查詢。
使用SDK搜尋MaxCompute外部表格資料速度慢
問題現象
使用SDK搜尋MaxCompute外部表格資料速度慢。
解決措施
外部表格僅支援全量搜尋,所以較慢,建議您改用MaxCompute內部表。