天天看點

MaxCompute通路TableStore(OTS) 資料

原文連結:http://click.aliyun.com/m/13884/

免費開通大資料服務:https://www.aliyun.com/product/odps

MaxCompute作為阿裡雲大資料平台的核心計算元件,承擔了集團内外大部分的分布式計算需求。而MaxCompute SQL作為分布式資料處理的主要入口,為快速友善處理/存儲EB級别的離線資料提供了強有力的支援。 随着大資料業務的不斷擴充,新的資料使用場景在不斷産生,在這樣的背景下,MaxCompute計算架構也在不斷的演化,原來主要面對内部特殊格式資料的強大計算能力,也正在一步步的開放給不同的外部資料。 之前我們介紹了怎樣在MaxCompute上處理存儲在OSS上面的非結構化資料,在這裡我們将進一步介紹如何将來自TableStore(OTS)的資料納入MaxCompute上的計算生态,實作多種資料源之間的無縫連接配接。

對于線上服務等應用場景,NoSQL KV Store(e.g., BigTable, HBase)相比傳統資料庫,具有schema靈活,易擴充,實時性強等優點。阿裡雲TableStore(OTS) 是在阿裡飛天分布式系統之上實作的大規模的NoSQL資料存儲服務,提供海量KV資料的存儲和實時通路。 在集團内部各BU以及外部阿裡雲生态圈中具有廣泛的應用。 尤其是TableStore在行級别上的實時更新和可覆寫性寫入等特性,相對于MaxCompute内置表append-only批量操作,提供了一個很好的補充。 但是TableStore作為一個偏存儲的服務,對于存儲在其上的海量資料,在大規模批量并行處理的計算能力有所欠缺。 在這樣的背景下,打通MaxCompute的計算和TableStore存儲之間的資料鍊路就顯得尤其重要。

首先要說明的是MaxCompute新一代的2.0計算架構還在灰階上線的過程中,預設設定下許多功能沒有打開,是以要使用新引進的非結構化資料處理架構,**需要申請MaxCompute 2.0試用**,具體開通使用方法請參見 如何申請試用MaxCompute 2.0, 簡單來說就是在開通2.0非結構化功能的前提下,在每個SQL query執行時必須帶上如下setting:

下面的範例中就不再重複了,**但是本文介紹的所有功能均基于以上假設**,當然這些特殊設定在2.0計算架構完全上線後就可以省略了。

如果對于TableStore不熟悉或者對于整個KV table的概念比較陌生同學,可以通過TableStore的文檔來先了解一些基本概念(比如主鍵,分區鍵,屬性列等),這裡的讨論不對這些基本概念做深入的解釋和探讨。 同時對于MaxCompute非結構化架構的整體介紹可以參見之前在MaxCompute上處理存儲在OSS上面的非結構化資料的介紹文章,包括External Table, StorageHandler的概念以及SERDEPROPERTIES的使用等。

MaxCompute與TableStore是兩個獨立的大資料計算以及大資料存儲服務,是以兩者之間的網絡必須保證連通性。 對于MaxCompute公共雲服務通路TableStore存儲,推薦使用TableStore**私網**位址,例如<code>tablestore://odps-ots-dev.cn-shanghai.ots-internal.aliyuncs.com</code>。

需要首先指出的是,MaxCompute計算服務要通路TableStore資料需要有一個安全的授權通道。 在這個問題上,MaxCompute結合了阿裡雲的通路控制服務(RAM)和令牌服務(STS)來實作對資料的安全反問:

首先需要在RAM中授權MaxCompute通路OSS的權限。登入RAM控制台,建立角色<code>AliyunODPSDefaultRole</code>,并将政策内容設定為:

然後編輯該角色的授權政策,将權限<code>AliyunODPSRolePolicy</code>授權給該角色。

如果覺得這些步驟太麻煩,還可以登入阿裡雲賬号點選此處完成一鍵授權。

與處理OSS資料的使用方法類似,MaxCompute通過EXTERNAL TABLE的方式來對接TableStore的資料:使用者通過一個CREATE EXTERNAL TABLE的DDL語句,把對TableStore表資料的描述引入到MaxCompute的meta系統内部後,即可如同使用一個普通TABLE一樣來實作對TableStore資料的處理。 這裡先提供一個最簡單的使用範例,并且通過該範例來讨論ODPS對接TableStore的一些概念和實作。

這個DDL語句将一個TableStore表映射到了MaxCompute的一個External Table上。 在這個基礎上,後繼對TableStore資料的操作可以直接通過External Table進行。 這裡先對上面這個CREATE EXTERNAL TABLE的DDL語句做一些解釋:

<code>com.aliyun.odps.TableStoreStorageHandler</code> 是MaxCompute内置的處理TableStore資料的StorageHandler, 定義了MaxCompute和TableStore的互動,相關邏輯由MaxCompute實作。

<code>SERDEPROPERITES</code>可以了解成提供參數選項的接口,在使用TableStoreStorageHandler時,有兩個必須指定的選項,分别是下面介紹的<code>tablestore.columns.mapping</code>和<code>tablestore.table.name</code>。 更多的可選選項将在後面其他例子中提及。

<code>tablestore.columns.mapping</code>選項:必需選項,用來描述對需要MaxCompute将通路的TableStore表的列,包括主鍵和屬性列。 這其中以<code>:</code>打頭的用來表示TableStore主鍵,例如這個例子中的<code>:o_orderkey</code>和<code>:o_orderdate</code>。 其他的均為屬性列。 TableStore支援最少1個,最多4個主鍵,主鍵類型為<code>bigint</code>或<code>string</code>,其中第一個主鍵為分區鍵。 在指定映射的時候,使用者必須提供指定TableStore表的**所有**主鍵,對于屬性列則沒有必要全部提供,可以隻提供需要通過MaxCompute來通路的屬性列。

<code>tablestore.table.name</code>:需要通路的TableStore表名。 如果指定的TableStore表名錯誤(不存在),則會報錯,MaxCompute不會主動去建立TableStore表。

LOCATION clause用來指定TableStore的具體資訊,包括instance名字,endpoint等。 值得注意的是這裡對TableStore資料的安全通路是建立在前文介紹的RAM/STS授權的前提上的。

在用上述DDL建立出External Table之後,TableStore的資料就引入到了MaxCompute的生态中,我們現在就可以通過正常的MaxCompute SQL文法來通路TableStore資料了,比如:

可以看到,在上面的這個例子,直接使用的就是我們所熟悉的MaxCompute SQL文法,通路TableStore的所有細節由MaxCompute内部處理。 這包括在列名的選擇上:可以看到,在這個SQL裡面,使用的列名是<code>odps_orderkey</code>,<code>odps_totalprice</code>等,而不是原始TableStore裡面的主鍵名<code>o_orderkey</code>或屬性列名<code>o_totalprice</code>了,因為我們在建立External Table的DDL語句裡,已經做了對應的mapping。 當然因為具體的mapping是每個使用者可以自己控制的,是以如果在建立External Table的時候保留原始的TableStore主鍵/列名也是可以的。

在底層的實作上,MaxCompute架構針對TableStore資料的存儲特點做了各種優化,包括并發讀取,SQL語句的filtering操作轉義等。 舉個例子,有filtering操作(比如上面的WHERE語句)時,MaxCompute會判斷filtering key是否為TableStore表格的主鍵,來決定如何用TableStore的GetRange API來讀取最小量資料,而不是無條件讀取全量資料讀到MaxCompute計算節點再做過濾操作。 當然這些實作的優化使用者均無需感覺,由MaxCompute計算架構負責來提高高效的實作。

另外如果需要對一份資料做**多次計算**,相較每次從TableStore去遠端讀資料,一個更高效的辦法是先一次性把需要的資料導入到MaxCompute内部成為一個MaxCompute(内部)表,比如:

現在<code>internal_orders</code>就是一個我們熟悉的MaxCompute表了,也擁有所有MaxCompute内部表的特性:包括高效的壓縮列存儲資料格式,完整的内部宏資料以及統計資訊等。 同時因為存儲在MaxCompute内部,通路速度會比通路外部的TableStore更快,尤其适用于需要進行多次計算的熱點資料。

打通MaxCompute和TableStore的資料生态,除了将TableStore作為批量資料處理的資料來源以外,一個另外的重要場景是将MaxCompute的資料處理結果輸出到TableStore,利用TableStore可實時更新和可單行覆寫等特點,迅速的将離線計算的結果回報給線上應用。 這種對TableStore的資料輸出可以使用MaxCompute SQL的INSERT OVERWRITE來實作。

需要再次強調的是,MaxCompute不會主動建立外部的TableStore表,是以在對TableStore表進行資料輸出之前,必須保證該表已經在TableStore上建立過(否則将報錯)。 這樣的設計是因為TableStore建表的過程可能涉及到CU的設定,計費,資料生命周期等一系列選項,這些必須由資料的所有者來決定: MaxCompute不擁有這些**外部資料**,也無法做出這些選擇。

緊接上面的例子,假設我們已經使用上面的DDL語句建立了<code>ots_table_external</code>這個外部表來打通MaxCompute與TableStoreb資料表<code>ots_tpch_orders</code>的鍊路, 而且我們還有一份存儲在在MaxCompute内部有一個名為<code>internal_orders</code>的資料,現在希望對<code>internal_orders</code>中的資料進行一定處理後再寫回TableStore上,那麼可以直接通過對外部表做**INSERT OVERWITE TABLE**的操作來實作:

在這裡對表中的資料做了一些處理,并且把經過處理過的資料重新寫回到了TableStore裡。 對于TableStore這種KV資料的NoSQL存儲媒體,從MaxCompute的輸出将隻影響相對應主鍵所在的行:在上面這個例子中也就是隻影響所有<code>odps_orderkey</code> + <code>odps_orderdate</code> 這兩個主鍵值能對應行上的資料。 而且在這些TabeleStore行上面,也隻會去更新在建立External Table (<code>ots_table_external</code>)時指定的屬性列,而不會去修改未在External Table裡面出現的資料列。 關于MaxCompute外部表和TableStore表的對應關系,下文會更系統的介紹。

從本質上來看MaxCompute表是嚴格結構化的資料表,要求所有的行均遵從嚴格一緻的schema,而TableStore的表中存儲的是NoSQL的“半結構化”K-V資料。這些基本資料格式上的差別決定了在兩個系統的互動過程中,行為會有一些差別。 同時MaxCompute作為一個分布式計算系統,讀寫TableStore通過并發執行來實作,這就需要對TableStore的資料有一個切割的機制。 在預設情況下,MaxCompute會提供一個系統認為最合适的處理方法,來實作對TableStore資料的通路和計算,而這些實作也能滿足絕大部分使用者的需求。 但是與此同時,為了滿足一些對系統比較熟悉的進階使用者的特殊需求,MaxCompute也提供了更多的可配置選項,這裡做一些介紹。

MaxCompute外表與TableStore資料表是多對一(N:1)的關系。 也就是說可以有多個MaxCompute外表(External Table)來描述一張TableStore表。 這裡的N:1是兩個次元上的:

不同的MaxCompute外表可以描述一張TableStore表的不同屬性列子集,比如如果在TableStore的一個表有3個主鍵列,(up to)20個屬性列,那麼通過MaxComptue的外表,主鍵必須提供完備,但是屬性列則不必,比如可以隻提供一個屬性列,那麼通過MaxCompute外表進行的所有操作,都隻會基于主鍵和所提供的屬性列上的資料。

不同的MaxCompute外表可以描述一張TableStore表的不同range,在本文的例子裡都是一個外表對應一個TableStore表的全range,但實際使用的時候是可以通過額外選項來指定外表對應的range start和range end的, 這可以做到一個外表隻映射一個TableStore表的子range。 這個功能這裡不展開介紹,有需求的話可以聯系MaxCompute技術團隊。

TableStore是一個分布式KV資料存儲系統,每個資料表都可能存儲在多個後端server上,并且根據分區鍵進行分區,具體存儲上的分區政策由TableStore決定。 目前通過MaxCompute讀取TableStore資料,預設的并發度将與TableStore後端的分區數目相同。 唯一的例外是,在采用INTEGER64作為分區鍵,**且TableStore後端的分區數目大于1時**,MaxCompute會自動對并發度再做調整,在更高的并發度上讀取資料。 此外TableStore自身的系統也在不斷發展,以後将提供更強大的API接口給MaxCompute來使用,到時候将可以根據後端資料的大小,來準确的做出資料切割。 更準确的控制每個并發MaxCompute worker處理的資料量和計算時間。 這方面将在這些功能實作後再更新來做具體說明。

最後,如果使用者對自己存儲在TableStore資料有着非常好的了解,比如對于不同key range中的資料量都能做出很好的預估,MaxCompute還提供讓使用者自己指定并發度的選型:使用者的控制甚至可以細化到指定每個worker應該處理哪個range的資料。 有這個需求的使用者可以聯系MaxCompute技術團隊。

因為MaxCompute與TableStore是兩個分開的雲服務,是以在不同的部署叢集上的網絡連通性有可能影響MaxCompute通路TableStore的資料的可達性。 關于TableStore的節點,執行個體,服務位址等概念,可以參見TableStore相關介紹。

随着MaxCompute非結構化資料處理架構的上線,MaxCompute開放了處理外部資料的接口,包括之前介紹的通路OSS資料,以及本文描述的通路TableStore資料。 我們希望借此來實作整個阿裡雲計算與資料的生态融合: 在不同的項目上,我們已經看到了在MaxCompute上處理OSS上的海量視訊,圖像等非結構化資料的巨大潛力。 随着TableStore資料支援的加入,期待計算和更多資料的碰撞能打通更多的應用場景,讓OSS資料,TableStore資料以及MaxCompute内部存儲的資料,能在MaxCompute的核心計算引擎上産生更大的價值。