全部產品
Search
文件中心

MaxCompute:Tablestore外部表格

更新時間:Jun 19, 2024

本文將進一步為您介紹如何將來自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屬性。

前提條件

建立外部表格

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主鍵,例如樣本中的:o_orderkey:o_orderdate,其他的均為屬性列。

  • Tablestore支援1~4個主鍵,主鍵類型為STRINGINTEGERBINARY,其中第一個主鍵為分區鍵。

  • 在指定映射時,您必須提供指定Tablestore表的所有主鍵和需要通過MaxCompute訪問的屬性列。

tablestore.table.name

需要訪問的Tablestore表名稱。本文以ots_tpch_orders為例。

odps.properties.rolearn

RAM中AliyunODPSDefaultRole的ARN資訊。您可以通過RAM控制台中的RAM角色管理進行擷取。

tablestore.timestamp.ticks.unit

表層級時間類型設定。用以指定該外部表格中所有Integer的欄位都處於同一個時間類型。取值如下:

  • seconds(秒)

  • millis(毫秒)

  • micros(微秒)

  • nanos(納秒)

tablestore.column.<col1_name>.timestamp.ticks.unit

列層級時間類型設定。用以指定該外部表格中欄欄位的時間類型。取值如下:

  • seconds(秒)

  • millis(毫秒)

  • micros(微秒)

  • nanos(納秒)

說明

tablestore.timestamp.ticks.unittablestore.column.<col1_name>.timestamp.ticks.unit都配置時,tablestore.column.<col1_name>.timestamp.ticks.unit參數的優先順序更高。

tablestore.table.put.row

支援指定PutRow的寫入方式。取值說明如下:

  • True:開啟。

  • False(預設值):關閉。

說明

可以通過設定以下Flag的參數值指定PutRow的寫入方式,預設值為False。詳情請參見Flag參數列表

set odps.sql.unstructured.tablestore.put.row=true;

tablestore.read.mode

當遇到髒資料時行為定義欄位,取值說明如下:

  • permissive(預設值):當遇到髒資料時,可以跳過。

  • failfast:當遇到髒資料時,直接報錯。

關於髒資料處理樣本,詳情請參見髒資料處理樣本

tablestore.corrupt.column

指定髒資料寫入列。

  • 僅當tablestore.read.mode參數取值permissive時,需要配置此參數。

  • 指定的列名稱為MaxCompute外部表格列名稱,且只能是最後一列。

  • 不支援指定Tablestore主鍵列。

關於髒資料處理樣本,詳情請參見髒資料處理樣本

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 

    詳細描述請參見使用BatchWriteRow一次提交100條資料的時候報OTSParameterInvalid錯誤

  • 由於Tablestore是KV儲存,使用insert overwrite table寫入資料到Tablestore表,不會清空目標Tablestore表的全部內容,只會覆蓋目標表中Key一致的Value值。

髒資料處理樣本

  1. 準備Tablestore表mf_ots_test和資料。具體操作,請參見通過控制台使用寬表模型

    預設Tablestore的表格式資料如下所示。

    +----+------+------+
    | id | name | desc |
    +----+------+------+
    | 1  | 張三 | 張三的描述 |
    +----+------+------+
  2. 建立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';
  3. 執行以下代碼,查詢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”