Ignite集成Spark之IgniteDataFrames 頂 原 薦

本系列共兩篇文章,主要探討如何將Ignite和Spark進行集成。

下面簡要地回顧一下在第一篇文章中所談到的內容。

Ignite是一個分佈式的內存數據庫、緩存和處理平臺,爲事務型、分析型和流式負載而設計,在保證擴展性的前提下提供了內存級的性能。

Spark是一個流式數據和計算引擎,通常從HDFS或者其他存儲中獲取數據,一直以來,他都傾向於OLAP型業務,並且聚焦於MapReduce類型負載。

因此,這兩種技術是可以互補的。

將Ignite與Spark整合

整合這兩種技術會爲Spark用戶帶來若干明顯的好處:

  • 通過避免大量的數據移動,獲得真正可擴展的內存級性能;
  • 提高RDD、DataFrame和SQL的性能;
  • 在Spark作業之間更方便地共享狀態和數據。

下圖中顯示瞭如何整合這兩種技術,並且標註了顯著的優勢:

第一篇文章中,主要聚焦於IgniteRDD,而本文會聚焦於IgniteDataFrames。

IgniteDataframes

Spark的DataFrame API爲描述數據引入了模式的概念,Spark通過表格的形式進行模式的管理和數據的組織。

DataFrame是一個組織爲命名列形式的分佈式數據集,從概念上講,DataFrame等同於關係數據庫中的表,並允許Spark使用Catalyst查詢優化器來生成高效的查詢執行計劃。而RDD只是跨集羣節點分區化的元素集合。

Ignite擴展了DataFrames,簡化了開發,改進了將Ignite作爲Spark的內存存儲時的數據訪問時間,好處包括:

  • 通過Ignite讀寫DataFrames時,可以在Spark作業之間共享數據和狀態;
  • 通過優化Spark的查詢執行計劃加快SparkSQL查詢,這些主要是通過IgniteSQL引擎的高級索引以及避免了Ignite和Spark之間的網絡數據移動實現的。

IgniteDataframes示例

下面通過一些代碼以及搭建幾個小程序的方式,瞭解Ignite DataFrames如何使用,如果想實際運行這些代碼,可以從GitHub上下載。

一共會寫兩個Java的小應用,然後在IDE中運行,還會在這些Java應用中執行一些SQL。

一個Java應用會從JSON文件中讀取一些數據,然後創建一個存儲於Ignite的DataFrame,這個JSON文件Ignite的發行版中已經提供,另一個Java應用會從Ignite的DataFrame中讀取數據然後使用SQL進行查詢。

下面是寫應用的代碼:

public class DFWriter {

    private static final String CONFIG = "config/example-ignite.xml";

    public static void main(String args[]) {
        Ignite ignite = Ignition.start(CONFIG);

        SparkSession spark = SparkSession
                .builder()
                .appName("DFWriter")
                .master("local")
                .config("spark.executor.instances", "2")
                .getOrCreate();

        Logger.getRootLogger().setLevel(Level.OFF);
        Logger.getLogger("org.apache.ignite").setLevel(Level.OFF);

        Dataset<Row> peopleDF = spark.read().json(
                resolveIgnitePath("resources/people.json").getAbsolutePath());

        System.out.println("JSON file contents:");

        peopleDF.show();

        System.out.println("Writing DataFrame to Ignite.");

        peopleDF.write()
                .format(IgniteDataFrameSettings.FORMAT_IGNITE())
                .option(IgniteDataFrameSettings.OPTION_CONFIG_FILE(), CONFIG)
                .option(IgniteDataFrameSettings.OPTION_TABLE(), "people")
                .option(IgniteDataFrameSettings.OPTION_CREATE_TABLE_PRIMARY_KEY_FIELDS(), "id")
                .option(IgniteDataFrameSettings.OPTION_CREATE_TABLE_PARAMETERS(), "template=replicated")
                .save();

        System.out.println("Done!");

        Ignition.stop(false);
    }
}

DFWriter中,首先創建了SparkSession,它包含了應用名,之後會使用spark.read().json()讀取JSON文件並且輸出文件內容,下一步是將數據寫入Ignite存儲。下面是DFReader的代碼:

public class DFReader {

    private static final String CONFIG = "config/example-ignite.xml";

    public static void main(String args[]) {
        Ignite ignite = Ignition.start(CONFIG);

        SparkSession spark = SparkSession
                .builder()
                .appName("DFReader")
                .master("local")
                .config("spark.executor.instances", "2")
                .getOrCreate();

        Logger.getRootLogger().setLevel(Level.OFF);
        Logger.getLogger("org.apache.ignite").setLevel(Level.OFF);

        System.out.println("Reading data from Ignite table.");

        Dataset<Row> peopleDF = spark.read()
                .format(IgniteDataFrameSettings.FORMAT_IGNITE())
                .option(IgniteDataFrameSettings.OPTION_CONFIG_FILE(), CONFIG)
                .option(IgniteDataFrameSettings.OPTION_TABLE(), "people")
                .load();

        peopleDF.createOrReplaceTempView("people");

        Dataset<Row> sqlDF = spark.sql("SELECT * FROM people WHERE id > 0 AND id < 6");
        sqlDF.show();

        System.out.println("Done!");

        Ignition.stop(false);
    }
}

DFReader中,初始化和配置與DFWriter相同,這個應用會執行一些過濾,需求是查找所有的id > 0 以及 < 6的人,然後輸出結果。

在IDE中,通過下面的代碼可以啓動一個Ignite節點:

public class ExampleNodeStartup {
    public static void main(String[] args) throws IgniteException {
        Ignition.start("config/example-ignite.xml");
    }
}

到此,就可以對代碼進行測試了。

運行應用

首先在IDE中啓動一個Ignite節點,然後運行DFWriter應用,輸出如下:

JSON file contents:
+-------------------+---+------------------+
|         department| id|              name|
+-------------------+---+------------------+
|Executive Committee|  1|       Ivan Ivanov|
|Executive Committee|  2|       Petr Petrov|
|         Production|  3|          John Doe|
|         Production|  4|         Ann Smith|
|         Accounting|  5|    Sergey Smirnov|
|         Accounting|  6|Alexandra Sergeeva|
|                 IT|  7|         Adam West|
|        Head Office|  8|    Beverley Chase|
|        Head Office|  9|      Igor Rozhkov|
|                 IT| 10|Anastasia Borisova|
+-------------------+---+------------------+

Writing DataFrame to Ignite.
Done!

如果將上面的結果與JSON文件的內容進行對比,會顯示兩者是一致的,這也是期望的結果。

下一步會運行DFReader,輸出如下:

Reading data from Ignite table.
+-------------------+--------------+---+
|         DEPARTMENT|          NAME| ID|
+-------------------+--------------+---+
|Executive Committee|   Ivan Ivanov|  1|
|Executive Committee|   Petr Petrov|  2|
|         Production|      John Doe|  3|
|         Production|     Ann Smith|  4|
|         Accounting|Sergey Smirnov|  5|
+-------------------+--------------+---+

Done!

這也是期望的輸出。

總結

通過本文,會發現使用Ignite DataFrames是如何簡單,這樣就可以通過Ignite DataFrame進行數據的讀寫了。

未來,這些代碼示例也會作爲Ignite發行版的一部分進行發佈。

關於Ignite和Spark的集成,內容就是這些了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章