# 使用 Kudu 開發應用程序
原文鏈接 : [http://kudu.apache.org/docs/developing.html](http://kudu.apache.org/docs/developing.html)
譯文鏈接 : [http://cwiki.apachecn.org/pages/viewpage.action?pageId=10813629](http://cwiki.apachecn.org/pages/viewpage.action?pageId=10813629)
貢獻者 : [小瑤](/display/~chenyao) [ApacheCN](/display/~apachecn) [Apache中文網](/display/~apachechina)
## 使用 Kudu 開發應用程序
**Kudu?**提供 **C ++**,**Java** 和 **Python** 客戶端 **API** 以及參考示例來說明它們的用途。
注意
不支持使用服務器端或專用接口,不屬于公共 **API** 的接口沒有穩定性保證。
## 查看 API 文檔
### C++ API 文檔
?您可以在線查看 **C ++** 客戶端 **API** 文檔。或者,在從源代碼構建 **Kudu** 后,您還可以另外構建 **doxygen** 目標(例如,如果使用 **make** ,則運行 **make doxygen** ),并通過在您最喜歡的 **Web** 中打開 **docs/doxygen/client_api/html/index.html** 文件來使用本地生成的 **API** 文檔瀏覽器。
重要
為了構建 **doxygen** 目標,有必要在您的構建機器上安裝帶有 **Dot( graphviz )**支持的 **doxygen** 。如果您從源代碼構建 **Kudu** 后安裝了 **doxygen** ,則需要再次運行 **cmake** 以獲取 **doxygen** 位置并生成適當的目標。
### Java API 文檔
?您可以在線查看[ **Java API** 文檔](http://kudu.apache.org/apidocs/index.html) 。或者,在構建 [**Java** 客戶端](/pages/viewpage.action?pageId=10813629)之后,**Java API** 文檔可以在 **java/kudu-client/target/apidocs/index.html** 中找到。
## 工作實例
[**kudu** 示例](https://github.com/cloudera/kudu-examples) **Github** 倉庫中提供了幾個示例應用程序。每個示例包括一個自述文件,顯示如何編譯和運行它。這些例子說明了 **Kudu** **API** 的正確使用,以及如何設置虛擬機來運行 **Kudu** 。以下列表包括今天可用的一些示例。檢查存儲庫本身,以防此列表過期。
**java/java-example**
連接到 **Kudu** 實例的簡單 **Java** 應用程序創建一個表,向其中寫入數據,然后丟棄該表。
**java/collectl**
偵聽 **TCP** 套接字的小型 **Java** 應用程序,用于與 **Collectl** 有線協議相對應的時間序列數據。常用的 **collectl** 工具可用于將示例數據發送到服務器。
**java/insert-loadgen**
生成隨機插入負載的 **Java** 應用程序。
**python/dstat-kudu**
一個示例程序,顯示如何使用 **Kudu Python API** 將數據加載到由外部程序生成的新的/現有的 **Kudu** 表中, **dstat** 在這種情況下。
**python/graphite-kudu**
使用 **graphite-web**?( 石墨網?) 與 **Kudu** 作為后端的實驗插件。
**demo-vm-setup**
腳本下載并運行帶有 **Kudu** 的 **VirtualBox** 虛擬機已安裝。有關詳細信息,請參閱 [快速入門](/pages/viewpage.action?pageId=10813610) 。
這些例子應該是您自己的 **Kudu** 應用程序和集成的有用起點。
### Maven Artifacts ( Maven 工件 )
以下 **Maven <dependency>** 元素對于 **Apache Kudu** 公開版本(從**1.0.0** 開始)是有效的:
```
<dependency>
<groupId>org.apache.kudu</groupId>
<artifactId>kudu-client</artifactId>
<version>1.1.0</version>
</dependency>
```
**Java** 客戶端和各種 **Java** 集成(例如 **Spark** , **Flume** )的便利二進制文件現在也可以通過[ **ASF Maven** 存儲庫](http://repository.apache.org/) 和[ **Maven Central** 存儲庫](https://mvnrepository.com/artifact/org.apache.kudu)獲得。
## Impala命令使用 Kudu 的例子
請參閱 [使用 **Impala** 與 **Kudu**](/pages/viewpage.action?pageId=10813620) 進行有關使用 **Kudu** 安裝和使用 **Impala** 的指導,其中包括幾個 **impala-shell** 示例。
## Kudu 與 Spark 集成
**Kudu** 從 **1.0.0** 版開始,通過 **Data Source API** 與 **Spark** 集成。使用 **--packages** 選項包括 **kudu-spark** 依賴關系:
如果使用 **Spark** 與 **Scala 2.10** ,請使用 **kudu-spark_2.10** 插件:
```
spark-shell --packages org.apache.kudu:kudu-spark_2.10:1.1.0
```
如果在 **Scala 2.11** 中使用 **Spark 2** ,請使用 **kudu-spark2_2.11** 插件:
```
spark-shell --packages org.apache.kudu:kudu-spark2_2.11:1.1.0
```
然后導入 **kudu-spark** 并創建一個數據框:
```
import org.apache.kudu.spark.kudu._
import org.apache.kudu.client._
import collection.JavaConverters._
// Read a table from Kudu
val df = sqlContext.read.options(Map("kudu.master" -> "kudu.master:7051","kudu.table" -> "kudu_table")).kudu
// Query using the Spark API...
df.select("id").filter("id" >= 5).show()
// ...or register a temporary table and use SQL
df.registerTempTable("kudu_table")
val filteredDF = sqlContext.sql("select id from kudu_table where id >= 5").show()
// Use KuduContext to create, delete, or write to Kudu tables
val kuduContext = new KuduContext("kudu.master:7051", sqlContext.sparkContext)
// Create a new Kudu table from a dataframe schema
// NB: No rows from the dataframe are inserted into the table
kuduContext.createTable(
"test_table", df.schema, Seq("key"),
new CreateTableOptions()
.setNumReplicas(1)
.addHashPartitions(List("key").asJava, 3))
// Insert data
kuduContext.insertRows(df, "test_table")
// Delete data
kuduContext.deleteRows(filteredDF, "test_table")
// Upsert data
kuduContext.upsertRows(df, "test_table")
// Update data
val alteredDF = df.select("id", $"count" + 1)
kuduContext.updateRows(filteredRows, "test_table"
// Data can also be inserted into the Kudu table using the data source, though the methods on KuduContext are preferred
// NB: The default is to upsert rows; to perform standard inserts instead, set operation = insert in the options map
// NB: Only mode Append is supported
df.write.options(Map("kudu.master"-> "kudu.master:7051", "kudu.table"-> "test_table")).mode("append").kudu
// Check for the existence of a Kudu table
kuduContext.tableExists("another_table")
// Delete a Kudu table
kuduContext.deleteTable("unwanted_table")
<> and OR predicates are not pushed to Kudu, and instead will be evaluated by the Spark task. Only LIKE predicates with a suffix wildcard are pushed to Kudu, meaning that LIKE "FOO%" is pushed down but LIKE "FOO%BAR" isn’t.
```
### Spark 集成已知問題和限制
* 注冊為臨時表時,必須為具有大寫字母或非 **ASCII** 字符的名稱的 **Kudu** 表分配備用名稱。
* 具有包含大寫字母或非 **ASCII** 字符的列名稱的 **Kudu** 表可能不與 **SparkSQL** 一起使用。 **Columns?**可能在 **Kudu** 更名為解決這個問題。
* **<>** 和 **OR** 謂詞不被推送到 **Kudu** ,而是將在?**Spark**?的evaluate過程中執行, 只有具有后綴通配符的 **LIKE** 謂詞才被推送到 **Kudu**?執行,這意味著 **LIKE“FOO%”**語句被下推到**Kudu**,而?**“FOO%BAR”**?這樣的語句不會。
* **Kudu** 不支持 **Spark SQL** 支持的所有類型,例如 **Date** , **Decimal** 和復雜類型。
* **Kudu** 表只能在 **SparkSQL** 中注冊為臨時表。 可能不會使用 **HiveContext** 查詢 **Kudu** 表。
## Kudu Python 客戶端
**Kudu Python** 客戶端為 **C ++** 客戶端 API 提供了一個 **Python** 友好的界面。 下面的示例演示了如何使用部分 **Python** 客戶端。
```
import kudu
from kudu.client import Partitioning
from datetime import datetime
# Connect to Kudu master server
client = kudu.connect(host='kudu.master', port=7051)
# Define a schema for a new table
builder = kudu.schema_builder()
builder.add_column('key').type(kudu.int64).nullable(False).primary_key()
builder.add_column('ts_val', type_=kudu.unixtime_micros, nullable=False, compression='lz4')
schema = builder.build()
# Define partitioning schema
partitioning = Partitioning().add_hash_partitions(column_names=['key'], num_buckets=3)
# Create new table
client.create_table('python-example', schema, partitioning)
# Open a table
table = client.table('python-example')
# Create a new session so that we can apply write operations
session = client.new_session()
# Insert a row
op = table.new_insert({'key': 1, 'ts_val': datetime.utcnow()})
session.apply(op)
# Upsert a row
op = table.new_upsert({'key': 2, 'ts_val': "2016-01-01T00:00:00.000000"})
session.apply(op)
# Updating a row
op = table.new_update({'key': 1, 'ts_val': ("2017-01-01", "%Y-%m-%d")})
session.apply(op)
# Delete a row
op = table.new_delete({'key': 2})
session.apply(op)
# Flush write operations, if failures occur, capture print them.
try:
session.flush()
except kudu.KuduBadStatus as e:
print(session.get_pending_errors())
# Create a scanner and add a predicate
scanner = table.scanner()
scanner.add_predicate(table['ts_val'] == datetime(2017, 1, 1))
# Open Scanner and read all tuples
# Note: This doesn't scale for large scans
result = scanner.open().read_all_tuples()
```
## 與 MapReduce , YARN 和其他框架集成
**Kudu** 旨在與 **Hadoop** 生態系統中的 **MapReduce** , **YARN** , **Spark** 和其他框架集成。 請參閱 **[RowCounter.java](https://github.com/apache/kudu/blob/master/java/kudu-client-tools/src/main/java/org/apache/kudu/mapreduce/tools/RowCounter.java)** 和** [ImportCsv.java](https://github.com/apache/kudu/blob/master/java/kudu-client-tools/src/main/java/org/apache/kudu/mapreduce/tools/ImportCsv.java)** ,了解可以對自己的集成進行建模的示例。 請繼續關注未來使用 **YARN** 和 **Spark** 的更多示例。