From 64bf1396ed32155322e0831e0b2184c88213649a Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Fri, 1 Mar 2024 15:25:47 -0500 Subject: [PATCH] Swap ascii art for actual image --- _posts/2024-02-27-comet-donation.md | 54 +++++++------------- img/datafusion-comet/comet-architecture.png | Bin 0 -> 30027 bytes 2 files changed, 18 insertions(+), 36 deletions(-) create mode 100644 img/datafusion-comet/comet-architecture.png diff --git a/_posts/2024-02-27-comet-donation.md b/_posts/2024-02-27-comet-donation.md index 91647c57c00f..d21c8ad49095 100644 --- a/_posts/2024-02-27-comet-donation.md +++ b/_posts/2024-02-27-comet-donation.md @@ -33,43 +33,25 @@ accelerate Spark workloads. It is designed as a drop-in replacement for Spark's JVM based SQL execution engine and offers significant performance improvements for some workloads as shown below. -```text - ┌─────────────────────────────────────────────────────────────────┐ - │ │ - │ ┌──────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ - │ │ SQL │ │ Cluster │ │ DAG/Task │ ... │ Executor │ │ - │ │ Planner │ │ Manager │ │ Scheduler │ │ │ │ - │ └──────────┘ └────────────┘ └────────────┘ └────────────┘ │ - │ │ │ - └─────────────────────────────────────────────────────────────────┘ - Spark (JVM Based) │ - ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ - - │ - ▼ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -Comet Execution ┃ ┃ -Engine ┃ ┌─────────────────────────┐ ┃ -(Native Code) ┃ │ Apache Arrow DataFusion │ ┃ - ┃ └─────────────────────────┘ ┃ - ┃ ┃ - ┃ ┌─────────────────────────┐ ┃ - ┃ │ Spark Compatible │ ┃ - ┃ │ Expressions/Operators │ ┃ - ┃ └─────────────────────────┘ ┃ - ┃ ┃ - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ -``` - -**Figure 1**: With Comet, users interact with the same Spark ecosystem, tools -and APIs such as Spark SQL. Queries still run through Spark's mature and feature -rich query optimizer and planner. However, the execution is delegated to Comet, -which is significantly faster and more resource efficient than the JVM based -implementation. +
+ Fig 1: Adaptive Arrow schema architecture overview. +
+ Figure 1: With Comet, users interact with the same Spark ecosystem, tools + and APIs such as Spark SQL. Queries still run through Spark's query optimizer and planner. + However, the execution is delegated to Comet, + which is significantly faster and more resource efficient than a JVM based + implementation. +
+
+ -[Rust]: https://www.rust-lang.org/ -# Background +[Rust]: https://www.rust-lang.org/ Comet is one of a growing class of projects that aim to accelerate Spark using native columnar engines such as the proprietary [Databricks Photon Engine] and @@ -103,4 +85,4 @@ Before then, here are some ways to get involved: [mailing list discussion]: https://lists.apache.org/thread/0q1rb11jtpopc7vt1ffdzro0omblsh0s [roadmap]: https://github.com/apache/arrow-datafusion-comet/issues/19 - + diff --git a/img/datafusion-comet/comet-architecture.png b/img/datafusion-comet/comet-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..e7c9075736144e955a9441ca9342069919b9bf5a GIT binary patch literal 30027 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