Query your (big) data with the power of Python, Dask, and SQL
By: Nils Braun
Tags: Python, Machine Learning, Sql, Data Science, Dask

Query your (big) data with the power of Python, Dask, and SQL

How to get the best of all worlds

This post will describe what an SQL Query Engine is and how you can use dask-sql to analyze your (big) data quickly and easily and also call complex algorithms, such as machine learning, from SQL.

Photo by Moritz Kindler on Unsplash

SQL rules the world

If data is the new oil, SQL is its pipeline. SQL used to be “only” the language for accessing traditional relational OLTP databases. But today, it is much more: any BI-tool builds on SQL, for Data Analysts, Data Scientists, and Data Engineers SQL is a base skill, and even NoSQL databases often implement a language quite similar to SQL to make adoption for its users simpler.

In summary: whenever you are able to map your data pipeline and analysis on SQL, you open up your data for a large range of applications and users. The only question is: what to do if the data does not fit into the constraints of a traditional relational SQL database (e.g. too much data, too many different formats)?

SQL Query Engines

This is where SQL Query Engines come into play. Their job is, to make data from various data sources queryable with SQL — even though the data is not stored in a (traditional) database at all. Typical SQL Query Engines work as shown in this figure:

Schematic overview of SQL Query Engines with examples. Image by the author.

Let’s quickly walk through the components:

When you issue a SQL query to the query engine (e.g. via a JDBC/ODBC connection in your BI-tool), the query gets first parsed and analyzed by the tool. The SQL query engine compares and enriches the query with metadata it has about the actual raw data. As there is no relational SQL database it can issue the query against, the SQL query is converted into API calls of one of the distributed computing frameworks. Additional optimization steps can happen before and after this conversion. For example, Apache Hive submits MapReduce jobs whereas Apache Impala will (simplified) create on-the-fly-compiled C++ programs. The distributed computation framework is now responsible for performing the actual data analysis and distributing it over the cluster. These frameworks are the reason why SQL Query Engines work especially well with a lot of data: they can parallelize the work well and make use of the full power of your cluster. A typical well-known example of such a framework is Apache Spark. The distributed computation framework needs hardware to perform the calculation. Different frameworks can work with different cluster types and resource schedulers, e.g. YARN, kubernetes, Apache Mesos, … Finally, the data to query lives on an external storage device, e.g. S3 or hdfs. This is very different from a traditional relational database, which contains both the data and the functionality to query it.

For the user, it seems like querying a traditional relational SQL database — but the similarity is really only the SQL language.

Why so complicated?

This system of different components that need to play together nicely seems very complicated in comparison with a traditional relational database. However, there are some crucial benefits that explain why SQL Query Engines are developed and used by many small and large companies today.

Using a distributed computation framework is a must to query data in the quantities we need to deal with today. However, distributed computation is hard. SQL Query Engines give us an easy to understand interface and hide all the difficult particularities of the systems.

Separating data from computation allows having multiple (automated) ways to ingest and analyze the data simultaneously. It can also reduce costs as computation and storage can be scaled independently.

Reusing the same cluster for more complex, custom data pipelines and more simple SQL queries is again a way to reduce the overall costs.

As SQL is so widespread in use, SQL Query Engines democratize the access to the important data and algorithms and make them usable throughout the full company.

What is missing?

Especially the more modern representatives of SQL Query Engines like Apache Impala and presto are so widely in use for a good reason: when it comes to stability and overall performance it is very hard to beat them. However, there are some open issues that none of the presented solutions can easily handle so far:

If your data is in CSV or parquet, none of the tools has a problem. But what if you have your data in a strange proprietary format, for which you need a special library to read in the data?

Machine learning is already playing a large role in many companies and is also making its way from the Data Scientists to the Analyst. Currently, the support for ML prediction or training within the SQL queries is only basic (except for some cloud providers, where you can not influence the code), and interacting with the modern well-known libraries such as tensorflow, keras or scikit-learn is mostly impossible.

SQL Query Engines make it very simple and comfortable to query the data, but sometimes too simple. The world is messy, with inhomogeneous clusters, old historic batch systems, messy data, and complicated transformation steps. Including these things into the rigid concept of the SQL Query Engines can be tedious if not impossible.

Dask and dask-sql

So, how can we do better? With the power of Python and Dask!

Dask is a distributed computation framework written in Python and is comparable to Apache Spark (but is actually a lot more than that). dask-sql (disclosure: I am the author) adds an SQL query layer on top of Dask. It uses Apache Calcite for query parsing and optimization and translates the SQL into a Dask computational graph, which is then executed on the cluster. The SQL queries can either be issued from within your Python code and notebooks directly or via an SQL server speaking the presto on-wire protocol (which allows connecting any BI tool or external application).

How might Dask (and dask-sql) solve some shortcomings of the other SQL Query Engines?

Using python as the primary language opens up a wide variety of integrations and a vast ecosystem of tools and libraries. Every format and file you can read in with Python (which is basically everything) can also be used in Dask (and dask-sql), so you are not only limited to the typical big data formats such as parquet. (But of course, also those are supported).

Dask is able to connect to a large variety of cluster types and systems, including YARN, k9s, Apache Mesos, various batch systems, cloud providers, HPC systems, or manual deployments. You can even mix and match these, which makes it a lot more flexible than most of the other systems. Its large set of debugging and monitoring tools makes the process of finding performance bottlenecks easy.

Python is the language of Data Science — so porting and reusing algorithms, implemented transformation steps, and tools from your Data Science team is much easier. User-defined functions (UDFs) inside SQL queries come without any performance drawbacks in dask-sql and can range from simple numeric formulas to complex calls to machine learning libraries or other tools. They can be used when the SQL standard functions (a large fraction is already implemented in dask-sql, but not everything) are not enough anymore. As Dask DataFrames mimic the well-known pandas API, it is also very simple to define additional complicated distributed transformations and use them from within SQL.

Probably even more than any other framework (such as Apache Spark), the Dask ecosystem contains connectors, integration, and wrappers for so many things, ranging from machine learning to external system support and special use-cases (such as geospatial data). Just a small glimpse here.

Data on S3 queried distributed from a BI tool (Apache Hue in this case) via dask-sql in the background. Image by the author.

There must be a problem, or? Well, there is. Dask itself is a very mature project with many years of experience and a large community. dask-sql on the other hand is still a very young project and there are still a lot of possibilities to improve (in features, performance, and security). At least this is something, you can help with your feedback and contribution :-)

dask-sql is compatible with blazingSQL, a SQL Query Engine for computations on GPUs. Using GPUs adds a huge performance boost and allows you to perform SQL analysis on large amounts of data in no time. Adding custom functions is a bit more complicated, but the RAPIDS framework, which blazingSQL is using, adds many possibilities — also for machine learning or graph analytics.

Summary

SQL Query Engines are a crucial part of the data architecture: they open up the data and computation power not only to the few Data Engineers and distributed system experts but to a large group of users and applications. Dask and dask-sql also port these benefits into the python world and the combination of distributed processing, Python, and Dask give you even more benefits.

We have touched on a lot of different topics, and you might want to read more about details on the specific parts: