epdlxjmonad
Trino 476 (released in June 2025)
Spark 4.0.0 (released in May 2025)
Hive 4.0.0 on MR3 2.1 (released in July 2025)
At the end of the article, we discuss MPP vs MapReduce.
In this article, we report the results of evaluating the performance of the following systems using the 10TB TPC-DS Benchmark.
Trino 468 (released in December 2024)
Spark 4.0.0-RC2 (released in March 2025)
Hive 4.0.0 on Tez (built in February 2025)
Hive 4.0.0 on MR3 2.0 (released in April 2025)
Performance Evaluation of Trino 468, Spark 4.0.0-RC, and Hive 4.0.0
Trino 418 (released on May 17, 2023) Spark 3.4.0 (released on Apr 13, 2023) Hive 3.1.3 on MR3 1.7 (released on May 15, 2023)
I still play Diablo with 8 characters occasionally. I wish there was a game like this.
Spark on MR3 – A New Way to Run Apache Spark
Show HN: Fault Tolerance in Hive on MR3 on Kubernetes
Run Hive on Kubernetes, even in a Hadoop cluster
Show HN: Hive on MR3 on Amazon EKS with Autoscaling
Apart from adding new features (e.g., ACID support), a lot of effort is still put into optimizing queries and runtime. In essence, Hive is a tool specialized for SQL, so it tries to implement all the optimizations you can think of in the context of executing SQL queries. For example, Hive implements vectorized execution, whose counterpart in Spark was implemented only in a later version (with the introduction on Tungsten IIRC). Hive even supports query re-execution: if a query fails with a fatal error like OOM, Hive re-generates a new query after analyzing the runtime statistics collected by then. The second query usually runs much faster, and you can also update the column statistics in Metastore.
In contrast, Spark is a general-purpose execution engine where SparkSQL is just an application. I remember someone comparing Spark to Swiss army knife, which enables you to do a lot of things easily, but is no match against specialized tools developed for a particular task. My (opinionated) guess is that SparkSQL will be replaced by Hive and Presto, and Spark streaming will be replaced by Flink.
The reality is that nowadays both SparkSQL and Presto are way behind Hive, in terms of both speed and maturity. Hive made tremendous progress since 2015 (with the introduction of LLAP), while SparkSQL still has the issue of stability of fault tolerance and shuffling. (Presto does not support fault tolerance.) So, IMO, SparkSQL is nowhere near ready to replace Hive.
If you are curious about the performance of these systems, see [1] and [2] which compare Hive, SparkSQL, and Presto. Disclaimer: We are developing MR3 mentioned in the articles. However, we tried to make a fair comparison in the performance evalaution.
[1] https://mr3.postech.ac.kr/blog/2019/11/07/sparksql2.3.2-0.10... [2] https://mr3.postech.ac.kr/blog/2019/08/22/comparison-presto3...
We are currently trying to fix the first problem in a different context (not Spark), where worker containers store intermediate shuffle files in local disks mounted as hostPath volumes. The performance penalty is about 50% compared with running everything natively. Besides occasionally some containers almost get stuck for a long time. I believe that the Spark community will encounter the same problem in the future if they choose to use local disks for storing intermediate files.
Correctness of Hive on MR3, Presto, and Impala
In our case, we use a single process to run everything, in conjunction with strong invariants written into the code. When an invariant is violated, we analyze the log to figure out the sequence of events that triggers the violation. As the execution is multi-threaded, the analysis can take a while. If the execution was single-threaded, the analysis would be much easier. In practice, the analysis is usually quick because the log tells us what is going on in each thread.
So, I guess there is a trade-off between the overhead of building the test framework and the extra effort in log analysis.
We have gone through the pain of testing and debugging a distributed system that is under development for the past 5 years. We investigated several fancy ways of debugging distributed systems such as model checking and formal verification. In the end, we decided to use (and are more or less happy with) the traditional way. The decision was made mostly because 1) the implementation is too complex (a lot of Java and Scala code) to allow formal techniques; 2) the traditional way can still be very effective when combined with careful design and thorough testing.
Before building the distributed system, we worked on formal verification using program logic and were knowledgeable about a particular sub-field. From our experience, I guess it would require a PhD dissertation to successfully apply formal techniques to debugging our distributed system. The summary of our experience is at https://www.datamonad.com/post/2020-02-19-testing-mr3/.
We started a project 5 years ago, after a few months of failed attempts. From the very onset of the project, we tried to adhere to the key lessons of the book. Examples are: recognizing the importance of minimizing communication overhead (the most important assets are not people but time), following the surgical model (key decisions should be made by a single individual), practicing effect-free programming whenever possible, allocating enough time for testing, and so on. I would definitely attribute the success of our project to the teachings of the MMM.
Like many books on software engineering (and self-help books in general), just reading a book and learning its contents may not make any difference in practice. Only when you seriously make conscious efforts to practice its teachings do you realize what the book is really about. This is also the reason why many university courses on software engineering are boring.
Arguably, invariants are especially powerful in testing distributed systems:
1. The argument x must not be 0.
2. The variable x must smaller than the variable y.
3. The list foo must be non-empty.
4. The variable x should have value 'Success' if it had value 'Try' in the beginning of the function call.
These 'invariants', or assertions, can be extremely useful for testing the correctness of the code. Put simply, if an invariant is violated (during unit test, integration tests, or system tests), it indicates that either the design or the implementation is wrong. An article on testing methodology would be more appealing if it had some discussion on exploiting invariants/assertions.
Nevertheless using just a single thread to simulate everything seems like a great approach.