# Kudu 集成 Apache Impala
原文鏈接 : [http://kudu.apache.org/docs/kudu_impala_integration.html](http://kudu.apache.org/docs/kudu_impala_integration.html)
譯文鏈接 : [http://cwiki.apachecn.org/pages/viewpage.action?pageId=10813620](http://cwiki.apachecn.org/pages/viewpage.action?pageId=10813620)
貢獻者 : [小瑤](/display/~chenyao) [ApacheCN](/display/~apachecn) [Apache中文網](/display/~apachechina)
## 使用Apache Kudu與Apache Impala(孵化)
**Kudu** 與 **Apache Impala** (孵化)緊密集成,允許您使用 **Impala** 使用 **Impala** 的 **SQL** 語法從 **Kudu tablets**?插入,查詢,更新和刪除數據,作為使用 **[Kudu API](/pages/viewpage.action?pageId=10813613)** 構建自定義 **Kudu** 應用程序的替代方法。此外,您可以使用 **JDBC** 或 **ODBC** 將使用任何語言,框架或商業智能工具編寫的現有或新應用程序與使用 **Impala** 作為代理的 **Kudu** 數據進行連接。
## 要求
* 此文檔特定于 **Impala** 的某些版本。描述的語法將僅在以下版本中運行:
*?**CDH 5.10** 附帶的 **Impala 2.7.0** 版本。 **SELECT VERSION()** 將報告?**impalad version 2.7.0-cdh5.10.0**?。
*?從源代碼編譯的 **Apache Impala 2.8.0** 版本。 **SELECT VERSION()** 將報告 **impalad version 2.8.0**。
較早版本的 **Impala 2.7**(包括以前提供的特殊 **IMPALA_KUDU** 版本)具有不兼容的語法。未來版本可能與此語法兼容,但我們建議您檢查這是與您安裝的相應版本相對應的最新可用文檔。
* 本文檔不描述 **Impala** 安裝過程。請參閱 **Impala** 文檔,并確保您可以在繼續之前對 **HDFS** 上的 **Impala** 表運行簡單查詢。
## 配置
**Kudu** 內不需要進行配置更改,從而可以訪問 **Impala** 。
雖然不是絕對必要的,但建議您配置 **Impala** 與 **Kudu Master servers** 的位置:
* 在 **Impala** 服務配置中設置 **--kudu_master_hosts = <master1> [:port]** , **<master2> [:port]** , **<master3> [:port]** 標志。如果您正在使用 **Cloudera Manager** ,請參閱相應的 **Cloudera Manager** 文檔。
如果在 **Impala** 服務中未設置此標志,則每次創建表格時都必須手動提供此配置,方法是在 **TBLPROPERTIES** 子句中指定 **kudu_master_addresses** 屬性。
本指南的其余部分假設配置已設置。
## 使用 Impala Shell
注意
這只是 **Impala Shell** 功能的一小部分。有關詳細信息,請參閱 **Impala Shell** 文檔。
* 使用 **impala-shell** 命令啟動 **Impala Shell** 。默認情況下, **impala-shell** 嘗試連接到端口 **21000** 上的 **localhost** 上的 **Impala** 守護程序。要連接到其他主機,請使用**?-i <host:port>** 選項。要自動連接到特定的 **Impala** 數據庫,請使用**?-d <database>** 選項。例如,如果您的所有 **Kudu** 表都位于 **Impala_kudu** 數據庫中的 **Impala** 中,請使用 **-d impala_kudu** 來使用此數據庫。
* 要退出 **Impala Shell**,請使用以下命令:**quit**;
### 內部和外部 Impala 表
使用 **Impala** 創建新的 **Kudu** 表時,可以將表創建為內部表或外部表。
#### Internal ( 內部 )
內部表由 **Impala** 管理,當您從 **Impala** 中刪除時,數據和表確實被刪除。當您使用 **Impala** 創建新表時,通常是內部表。
#### External ( 外部 )
外部表(由 **CREATE EXTERNAL TABLE** 創建)不受 **Impala** 管理,并且刪除此表不會將表從其源位置(此處為 **Kudu** )丟棄。相反,它只會去除 **Impala** 和 **Kudu** 之間的映射。這是 **Kudu** 提供的用于將現有表映射到 **Impala** 的語法。
有關內部和外部表的更多信息,請參閱 [Impala文檔](http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/impala_tables.html) 。
### 查詢 Impala 中現有的 Kudu 表
通過 **Kudu API** 或其他集成(如 **Apache** **Spark** )創建的表不會在 **Impala** 中自動顯示。要查詢它們,您必須先在 **Impala** 中創建外部表以將 **Kudu** 表映射到 **Impala** 數據庫中:
```
CREATE EXTERNAL TABLE my_mapping_table
STORED AS KUDU
TBLPROPERTIES (
'kudu.table_name' = 'my_kudu_table'
);
```
### 從 Impala 創建一個新的 Kudu 表
從 **Impala** 在 **Kudu** 中創建一個新表類似于將現有的 **Kudu** 表映射到 **Impala** 表,但您需要自己指定模式和分區信息。
使用以下示例作為指導。 **Impala** 首先創建表,然后創建映射。
```
CREATE TABLE my_first_table
(
id BIGINT,
name STRING,
PRIMARY KEY(id)
)
PARTITION BY HASH PARTITIONS 16
STORED AS KUDU;
```
在 **CREATE TABLE** 語句中,必須首先列出構成主鍵的列。此外,主鍵列隱式標記為 **NOT NULL** 。
創建新的 **Kudu** 表時,需要指定一個分配方案。請參閱 [分區表](/pages/viewpage.action?pageId=10813620)。為了簡單起見,上面的表創建示例通過散列 **id** 列分成 16 個分區。有關分區的指導,請參閱 [**Thumb** 的分區規則](/pages/viewpage.action?pageId=10813620)。
```
CREATE TABLE AS SELECT
```
您可以使用 **CREATE TABLE ... AS SELECT** 語句查詢 **Impala** 中的任何其他表或表來創建表。以下示例將現有表 **old_table** 中的所有行導入到 **Kudu** 表 **new_table** 中。 **new_table** 中的列的名稱和類型將根據 **SELECT** 語句的結果集中的列確定。請注意,您必須另外指定主鍵和分區。
```
CREATE TABLE new_table
PRIMARY KEY (ts, name)
PARTITION BY HASH(name) PARTITIONS 8
STORED AS KUDU
AS SELECT ts, name, value FROM old_table;
```
#### 指定?Tablet Partitioning ( Tablet 分區 )
表分為每個由一個或多個 **tablet servers** 提供的 **tablets** 。理想情況下,**tablets** 應該相對平等地拆分表的數據。 **Kudu** 目前沒有自動(或手動)拆分預先存在的 **tablets ?**的機制。在實現此功能之前,您必須在創建表時指定分區。在設計表格架構時,請考慮使用主鍵,您可以將表拆分成以類似速度增長的分區。使用 **Impala** 創建表時,可以使用 **PARTITION BY** 子句指定分區:
注意
**Impala** 關鍵字(如 **group** )在關鍵字意義上不被使用時,由背面的字符包圍。
```
CREATE TABLE cust_behavior (
_id BIGINT PRIMARY KEY,
salary STRING,
edu_level INT,
usergender STRING,
`group` STRING,
city STRING,
postcode STRING,
last_purchase_price FLOAT,
last_purchase_date BIGINT,
category STRING,
sku STRING,
rating INT,
fulfilled_date BIGINT
)
PARTITION BY RANGE (_id)
(
PARTITION VALUES < 1439560049342,
PARTITION 1439560049342 <= VALUES < 1439566253755,
PARTITION 1439566253755 <= VALUES < 1439572458168,
PARTITION 1439572458168 <= VALUES < 1439578662581,
PARTITION 1439578662581 <= VALUES < 1439584866994,
PARTITION 1439584866994 <= VALUES < 1439591071407,
PARTITION 1439591071407 <= VALUES
)
STORED AS KUDU;
```
如果您有多個主鍵列,則可以使用元組語法指定分區邊界:**('va',1),('ab',2)**。該表達式必須是有效的 **JSON** 。
#### Impala 數據庫和 Kudu
每個 **Impala** 表都包含在稱為數據庫的命名空間中。默認數據庫稱為默認數據庫,用戶可根據需要創建和刪除其他數據庫。
當從 **Impala** 中創建一個受管 **Kudu** 表時,相應的 **Kudu** 表將被命名為 **my_database :: table_name** 。
#### 不支持 Kudu 表的 Impala 關鍵字
創建 **Kudu** 表時不支持以下 **Impala** 關鍵字: **- PARTITIONED - LOCATION - ROWFORMAT**
### 優化評估 SQL 謂詞的性能
如果您的查詢的 **WHERE** 子句包含與 **operators =** , **<=** , **'\** , **'\'** , **> =** , **BETWEEN** 或 **IN** 的比較,則 **Kudu** 直接評估該條件,只返回相關結果。這提供了最佳性能,因為 **Kudu** 只將相關結果返回給 **Impala** 。對于謂詞 **!=** , **LIKE** 或 **Impala** 支持的任何其他謂詞類型, **Kudu** 不會直接評估謂詞,而是將所有結果返回給 **Impala** ,并依賴于 **Impala** 來評估剩余的謂詞并相應地過濾結果。這可能會導致性能差異,這取決于評估 WHERE 子句之前和之后的結果集的增量。
### 分區表
根據主鍵列上的分區模式將表格劃分為?**tablets?**。每個?**tablet?**由至少一臺?**tablet server?**提供。理想情況下,一張表應該分成多個?**tablets?**中分布的**?tablet servers**?,以最大化并行操作。您使用的分區模式的詳細信息將完全取決于您存儲的數據類型和訪問方式。關于 **Kudu** 模式設計的全面討論,請參閱 **[Schema Design](/pages/viewpage.action?pageId=10813632)**。
**Kudu** 目前沒有在創建表之后拆分或合并 **tablets** 的機制。創建表時,必須為表提供分區模式。在設計表格時,請考慮使用主鍵,這樣您就可以將表格分為以相同速率增長的 **tablets** 。
您可以使用 **Impala** 的 **PARTITION BY** 關鍵字對表進行分區,該關鍵字支持 **RANGE** 或 **HASH** 分發。分區方案可以包含零個或多個 **HASH** 定義,后面是可選的 **RANGE** 定義。 **RANGE** 定義可以引用一個或多個主鍵列。[基本](/pages/viewpage.action?pageId=10813620) 和 [高級分區](/pages/viewpage.action?pageId=10813620) 的示例如下所示。
#### 基本分區
**PARTITION BY RANGE ( 按范圍劃分?)**
您可以為一個或多個主鍵列指定范圍分區。 **Kudu** 中的范圍分區允許根據所選分區鍵的特定值或值的范圍拆分表。這樣可以平衡并行寫入與掃描效率。
假設您有一個具有列 **state?**,**name?**和 **purchase_count** 的表。以下示例創建 50 個 **tablets** ,每個 **US state** 。
注意
**單調增加 Values**
如果您在其值單調遞增的列上按范圍進行分區,則最后一個 **tablet?**的增長將遠大于其他平臺。此外,插入的所有數據將一次寫入單個 tablet?,限制了數據攝取的可擴展性。在這種情況下,請考慮通過 **HASH** 分配,而不是或除 **RANGE** 之外。
```
CREATE TABLE customers (
state STRING,
name STRING,
purchase_count int,
PRIMARY KEY (state, name)
)
PARTITION BY RANGE (state)
(
PARTITION VALUE = 'al',
PARTITION VALUE = 'ak',
PARTITION VALUE = 'ar',
-- ... etc ...
PARTITION VALUE = 'wv',
PARTITION VALUE = 'wy'
)
STORED AS KUDU;
```
PARTITION BY HASH ( 哈希分區 )
您可以通過散列分發到特定數量的 “**buckets**” ,而不是通過顯式范圍進行分發,或與范圍分布組合。您指定要分區的主鍵列,以及要使用的存儲桶數。通過散列指定的鍵列來分配行。假設散列的值本身不會表現出顯著的偏差,這將有助于將數據均勻地分布在數據桶之間。
您可以指定多個定義,您可以指定使用復合主鍵的定義。但是,在多個散列定義中不能提及一列。考慮兩列a和b:**√ * HASH(a),HASH(b)* ?√ HASH(a,b)* ?× HASH(a),HASH(a,b)**
注意
沒有指定列的 HASH 的 PARTITION BY HASH 是通過散列所有主鍵列來創建所需數量的桶的快捷方式。
如果主鍵值均勻分布在其域中,并且數據偏移不明顯,例如 **timestamps** ( 時間戳?)?或 **IDs** ( 序列號?),則哈希分區是合理的方法。
以下示例通過散列 **id** 和 **sku** 列創建 16 個 **tablets?**。這傳播了所有 16 個 **tablets?**的寫作。在這個例子中,對一系列 sku 值的查詢可能需要讀取所有 16 個 **tablets?**,因此這可能不是此表的最佳模式。有關擴展示例,請參閱 [高級分區](/pages/viewpage.action?pageId=10813620)。
```
CREATE TABLE cust_behavior (
id BIGINT,
sku STRING,
salary STRING,
edu_level INT,
usergender STRING,
`group` STRING,
city STRING,
postcode STRING,
last_purchase_price FLOAT,
last_purchase_date BIGINT,
category STRING,
rating INT,
fulfilled_date BIGINT,
PRIMARY KEY (id, sku)
)
PARTITION BY HASH PARTITIONS 16
STORED AS KUDU;
```
#### 高級分區
您可以組合 **HASH** 和 **RANGE** 分區來創建更復雜的分區模式。您可以指定零個或多個 **HASH** 定義,后跟零個或一個 **RANGE** 定義。每個定義可以包含一個或多個列。雖然枚舉每個可能的分發模式都超出了本文檔的范圍,但是幾個例子說明了一些可能性。
**PARTITION BY HASH and RANGE**
考慮上面的 [簡單哈希](/pages/viewpage.action?pageId=10813620) 示例,如果您經常查詢一系列 sku 值,可以通過將哈希分區與范圍分區相結合來優化示例。
以下示例仍然創建了16個 **tablets** ,首先將 **id** 列分為 **4** 個存儲區,然后根據 **sku** 字符串的值應用范圍劃分將每個存儲區分為四個數據塊。至少四片(最多可達**16**張)。當您查詢相鄰范圍的 **sku** 值時,您很有可能只需從四分之一的 **tablets** 中讀取即可完成查詢。
注意
默認情況下,使用 **PARTITION BY HASH** 時,整個主鍵是散列的。要只對主鍵進行散列,可以使用像 **PARTITION BY HASH(id, sku)** 這樣的語法來指定它。
```
CREATE TABLE cust_behavior (
id BIGINT,
sku STRING,
salary STRING,
edu_level INT,
usergender STRING,
`group` STRING,
city STRING,
postcode STRING,
last_purchase_price FLOAT,
last_purchase_date BIGINT,
category STRING,
rating INT,
fulfilled_date BIGINT,
PRIMARY KEY (id, sku)
)
PARTITION BY HASH (id) PARTITIONS 4,
RANGE (sku)
(
PARTITION VALUES < 'g',
PARTITION 'g' <= VALUES < 'o',
PARTITION 'o' <= VALUES < 'u',
PARTITION 'u' <= VALUES
)
STORED AS KUDU;
```
**Multiple?`PARTITION BY HASH`?Definitions ( 多重劃分由 HASH 定義 )**
再次擴展上述示例,假設查詢模式將是不可預測的,但您希望確保寫入分布在大量 **tablets** 上您可以通過在主鍵列上進行散列來實現整個主鍵的最大分配。
```
CREATE TABLE cust_behavior (
id BIGINT,
sku STRING,
salary STRING,
edu_level INT,
usergender STRING,
`group` STRING,
city STRING,
postcode STRING,
last_purchase_price FLOAT,
last_purchase_date BIGINT,
category STRING,
rating INT,
fulfilled_date BIGINT,
PRIMARY KEY (id, sku)
)
PARTITION BY HASH (id) PARTITIONS 4,
HASH (sku) PARTITIONS 4
STORED AS KUDU;
```
該示例創建**16**個分區。您也可以使用 **HASH(id,sku) PARTITIONS 16**.但是,對于 **sku** 值的掃描幾乎總是會影響所有**16**個分區,而不是可能限制為 **4** 。
**Non-Covering Range Partitions ( 不覆蓋分區 )**
**Kudu 1.0** 及更高版本支持使用非覆蓋范圍分區,其解決方案如下:
* 沒有未覆蓋的范圍分區,在需要考慮不斷增加的主鍵的時間序列數據或其他模式的情況下,服務于舊數據的 tablet 的大小相對固定,而接收新數據的 **tablets** 將不受限制地增長。
* 在您希望根據其類別(如銷售區域或產品類型)對數據進行分區的情況下,無需覆蓋范圍分區,則必須提前了解所有分區,或者如果需要添加或刪除分區,請手動重新創建表。 例如引入或消除產品類型。
非覆蓋范圍分區有一些注意事項。請務必閱讀鏈接:**/docs/schema_design.html [Schema Design guide]**。
此示例每年創建一個 **tablet** (共5個 **tablets** ),用于存儲日志數據。該表僅接受 **2012** 年至 **2016**年 的數據。這些范圍之外的鍵將被拒絕。
```
CREATE TABLE sales_by_year (
year INT, sale_id INT, amount INT,
PRIMARY KEY (sale_id, year)
)
PARTITION BY RANGE (year) (
PARTITION VALUE = 2012,
PARTITION VALUE = 2013,
PARTITION VALUE = 2014,
PARTITION VALUE = 2015,
PARTITION VALUE = 2016
)
STORED AS KUDU;
```
當記錄開始進入 **2017** 年時,他們將被拒絕。在這一點上, **2017** 年的范圍應該如下:
```
ALTER TABLE sales_by_year ADD RANGE PARTITION VALUE = 2017;
```
在需要數據保留的滾動窗口的情況下,范圍分區也可能會丟棄。例如,如果不再保留 **2012** 年的數據,則可能會批量刪除數據:
```
ALTER TABLE sales_by_year DROP RANGE PARTITION VALUE = 2012;
```
請注意,就像刪除表一樣,這不可逆轉地刪除存儲在丟棄的分區中的所有數據。
#### Partitioning Rules of Thumb ( 拇指分區規則?)
* 對于大型表格,如事實表,目標是在集群中擁有核心數量的 tablets 。
* 對于小型表格(如維度表),目標是足夠數量的 **tablets** ,每個 **tablets** 的大小至少為 **1 GB** 。
一般來說,請注意,在當前的實現中, **tablets** 的數量限制了讀取的并行性。增加 **tablets** 數量超過核心數量可能會有減少的回報。
### 將數據插入 Kudu 表
**Impala** 允許您使用標準 **SQL** 語句將數據插入 **Kudu** 。
#### 插入單個值
此示例插入單個行。
```
INSERT INTO my_first_table VALUES (99, "sarah");
```
此示例使用單個語句插入三行。
```
INSERT INTO my_first_table VALUES (1, "john"), (2, "jane"), (3, "jim");
```
#### 批量插入
批量插入時,至少有三種常用選擇。每個可能有優點和缺點,具體取決于您的數據和情況。
**Multiple single?`INSERT`?statements ( 多個單獨的 INSERT 語句 )**
這種方法具有易于理解和實現的優點。這種方法可能是低效的,因為 **Impala** 與 **Kudu** 的插入性能相比具有很高的查詢啟動成本。這將導致相對較高的延遲和較差的吞吐量。
**Single INSERT statement with multiple VALUES ( 具有多個 VALUES 的單個 INSERT 語句?)**
如果包含超過 1024 個 **VALUES** 語句,則在將請求發送到 **Kudu** 之前,**Impala** 將其分組為 1024 (或 **batch_size** 的值)。通過在 **Impala** 方面攤銷查詢啟動處罰,此方法可能會執行比多個順序 **INSERT** 語句略好。要設置當前 **Impala Shell** 會話的批量大小,請使用以下語法:**set batch_size = 10000;**
注意
增加 **Impala** 批量大小會導致 **Impala** 使用更多的內存。您應該驗證對群集的影響并進行相應調整。
**Batch Insert ( 批量插入 )**
從 **Impala** 和 **Kudu** 的角度來看,通常表現最好的方法通常是使用 **Impala** 中的 **SELECT FROM** 語句導入數據。
1. 如果您的數據尚未在 **Impala** 中,則一種策略是 [從文本文件](http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/impala_txtfile.html)(如 **TSV** 或 **CSV** 文件)導入。
2. [創建 **Kudu** 表](/pages/viewpage.action?pageId=10813620),注意指定為主鍵的列不能為空值。
3. 通過查詢包含原始數據的表將值插入到 **Kudu** 表中,如以下示例所示:
```
INSERT INTO my_kudu_table
SELECT * FROM legacy_data_import_table;
```
**Ingest using the C++ or Java API ( 采用C ++ 或 Java API?)**
?在許多情況下,適當的攝取路徑是使用 **C ++** 或 **Java API** 直接插入到 **Kudu** 表中。與其他 **Impala** 表不同,通過 **API** 插入到 **Kudu** 表中的數據可用于 **Impala** 中的查詢,而不需要任何 **INVALIDATE METADATA** 語句或其他 **Impala** 存儲類型所需的其他語句。
#### [`INSERT`?and Primary Key Uniqueness Violations](http://kudu.apache.org/docs/kudu_impala_integration.html#insert_ignore)?( 插入和主鍵唯一性違規 )
在大多數關系數據庫中,如果您嘗試插入已插入的行,則插入將失敗,因為主鍵將被重復。請參閱 [**INSERT**,**UPDATE** 和 **DELETE** 操作](/pages/viewpage.action?pageId=10813620)中的故障。然而,**Impala** 不會失敗查詢。相反,它會生成一個警告,但是繼續執行 **insert** 語句的其余部分。
如果插入的行意圖替換現有行,則可以使用 **UPSERT** 而不是 **INSERT** 。
```
INSERT INTO my_first_table VALUES (99, "sarah");
UPSERT INTO my_first_table VALUES (99, "zoe");
-- the current value of the row is 'zoe'
```
### 更新行
```
UPDATE my_first_table SET name="bob" where id = 3;
```
注意
當目標表在 **Kudu** 時,**UPDATE** 語句僅適用于 **Impala** 。
#### 批量更新
您可以使用批量插入中相同的方法 [批量更新](/pages/viewpage.action?pageId=10813620) 。
```
UPDATE my_first_table SET name="bob" where age > 10;
```
### 刪除行
```
DELETE FROM my_first_table WHERE id < 3;
```
您也可以使用更復雜的語法進行刪除。 **FROM** 子句中的逗號是 **Impala** 指定連接查詢的一種方法。有關 **Impala** 連接的更多信息,請參閱
```
DELETE c FROM my_second_table c, stock_symbols s WHERE c.name = s.symbol;
```
注意
當目標表在 **Kudu** 時,**DELETE** 語句僅適用于 **Impala** 。
#### 批量刪除
您可以使用 [“插入批量”](/pages/viewpage.action?pageId=10813620) 中概述的相同方法 批量刪除 。
```
DELETE FROM my_first_table WHERE id < 3;
```
### INSERT,UPDATE 和 DELETE 操作期間的故障
**INSERT** ,**UPDATE** 和 **DELETE** 語句不能被視為整體事務。如果這些操作中的一個無法部分通過,則可能已經創建了密鑰(在 **INSERT** 的情況下),或者記錄可能已被其他進程修改或刪除(在 **UPDATE** 或 **DELETE** 的情況下)。您應該設計您的應用程序。
### 更改表屬性
您可以通過更改表的屬性來更改 **Impala** 與給定 **Kudu** 表相關的元數據。這些屬性包括表名, **Kudu** 主地址列表,以及表是否由 **Impala** (內部)或外部管理。
**Rename an Impala Mapping Table ( 重命名 Impala 映射表?)**
```
ALTER TABLE my_table RENAME TO my_new_table;
```
注意
使用 **ALTER TABLE ... RENAME** 語句重命名表僅重命名 **Impala** 映射表,無論該表是內部還是外部表。這樣可以避免可能訪問基礎的 **Kudu** 表的其他應用程序的中斷。
**Rename the underlying Kudu table for an internal table ( 重新命名內部表的基礎 Kudu 表?)**
如果表是內部表,則可以通過更改 **kudu.table_name** 屬性重命名底層的 **Kudu** 表:
```
ALTER TABLE my_internal_table
SET TBLPROPERTIES('kudu.table_name' = 'new_name')
```
**Remapping an external table to a different Kudu table ( 將外部表重新映射到不同的 Kudu 表?)**
如果另一個應用程序在 **Impala** 下重命名了 **Kudu** 表,則可以重新映射外部表以指向不同的 **Kudu** 表名稱。
```
ALTER TABLE my_external_table_
SET TBLPROPERTIES('kudu.table_name' = 'some_other_kudu_table')
```
**Change the Kudu Master Address ( 更改 Kudu Master 地址?)**
```
ALTER TABLE my_table
SET TBLPROPERTIES('kudu.master_addresses' = 'kudu-new-master.example.com:7051');
```
**Change an Internally-Managed Table to External ( 將內部管理的表更改為外部?)**
```
ALTER TABLE my_table SET TBLPROPERTIES('EXTERNAL' = 'TRUE');
```
### 使用 Impala 刪除 Kudu 表
如果表是使用 **Impala** 中的內部表創建的,則使用 **CREATE TABLE** ,標準 **DROP TABLE** 語法會刪除底層的 **Kudu** 表及其所有數據。如果表被創建為一個外部表,使用 **CREATE EXTERNAL TABLE,Impala** 和 **Kudu** 之間的映射被刪除,但 **Kudu** 表保持原樣,并包含其所有數據。
```
DROP TABLE my_first_table;
```
## 下一步做什么?
上面的例子只是探索了 **Impala Shell** 所能做的一小部分。
* 了解 [**Impala** 項目](http://impala.io/)
* 閱讀 [**Impala** 文檔](http://www.cloudera.com/content/www/en-us/documentation/enterprise/latest/topics/impala.html)
* 查看 [**Impala SQL** 參考](http://www.cloudera.com/content/www/en-us/documentation/enterprise/latest/topics/impala_langref.html)
* 閱讀**?Impala** 內部部分或了解如何在** [Impala Wiki](https://github.com/cloudera/Impala/wiki)** 上為 **Impala** 做出貢獻。
* 閱讀原生的 [**Kudu API**](/pages/viewpage.action?pageId=10813613) 。
### 已知問題和限制
* 在使用 **Impala** 中的外部表格時,必須為具有大寫字母或非 **ASCII** 字符的名稱的 **Kudu** 表分配備用名稱。
* 具有包含大寫字母或非 **ASCII** 字符的列名稱的 **Kudu** 表可能不會用作 **Impala** 中的外部表。專欄可能在 **Kudu** 更名為解決這個問題。
* 創建 **Kudu** 表時,**CREATE TABLE** 語句必須在主鍵順序中包含其他列之間的主鍵列。
* 包含 **UNIXTIME_MICROS** 類型列的庫杜表可能不會用作 **Impala** 中的外部表。
* **Impala** 不能使用 **TIMESTAMP** , **DECIMAL** , **VARCHAR** 或嵌套類型的列創建 Kudu 表。
* **Impala** 無法更新主鍵列中的值。
* **NULL**,**NOT NULL**,**!=** 和 **LIKE** 謂詞不會被推送到 **Kudu** ,而是會被 **Impala** 掃描節點評估。這可能會降低相對于其他類型謂詞的性能。
* 通過 **Impala** 的更新,插入和刪除是非事務性的。如果查詢失敗的一部分途徑,其部分效果將不會回滾。
* 單個查詢的最大并行度僅限于表中的 **tablets** 數量。為了獲得良好的分析性能,針對每個主機10個或更多個 **tablets** 或使用大型表。