If you have worked with Apache Ignite, you have probably noticed that there are quite a few different client connectors that you can use. Client node, thick client, thin client, JDBC driver, ODBC driver, REST API, … All this might get a little confusing.
“Which type of client do I need to use in MY application?” — you would likely ask yourself.
So let me break this down. Below are all the client connectors available for Apache Ignite out of the box, as well as some best practices around when you should (or should not) use them.
Thick Client (a.k.a. Client Node)
Thick client is basically a regular Ignite node, which runs in client mode.
The difference between client nodes and server nodes is logical rather than physical. Clients do not participate in caching, compute, service deployment and other similar activities, but under the hood, they work in (almost) exact same way as servers. Mainly, this means that a client node utilizes the same discovery and communication mechanisms, which brings both advantages and disadvantages.
- A thick client is a part of topology, so it’s aware of partitioning configuration as well as data collocation techniques you applied to your caches. Whenever a thick client sends a request to read or update a cache entry, it goes directly to the node where this entry is stored — this is very efficient from scalability and performance standpoint.
- Thick clients provide a full set of APIs available in Apache Ignite. There are certain features (e.g., near caches or continuous queries) that are available ONLY in thick clients.
As always, high efficiency and rich functionality come with a price.
- First, a thick client is pretty heavy (hence the name) — in some cases it might consume quite a bit of CPU and RAM. For example, if you execute a SQL query, the client is actually used as a reducer that accumulates sub results from different nodes and makes the final calculations. Again — this is good for performance, but this also requires more CPU/RAM power. If your application is running on a device with limited resources, you would most likely want to use other options.
- Second, it is required that every thick client has full connectivity with every single server node. Moreover, since a thick client is just a regular node, it is possible that a server node will initiate a TCP connection with a client node. If there is a firewall, NAT or a load balancer between the cluster and the application, it will be really hard or even impossible to use thick clients. Basically, this means that thick clients are better used in the same physical environment in which server nodes run.
- Finally, keep in mind that think clients are available only for JVM languages, .NET languages, and C++. For other platforms, you will have to use other options.
Thin clients are actually much closer to what we usually think about when talking about clients. A thin client is very lightweight, initiates a single TCP socket connection with one of the nodes in the cluster, and communicates via a simple binary protocol. It also follows a very straightforward request-response pattern.
- Thin clients consume minimum resources and are very undemanding from the network communication standpoint. This makes them ideal for remote applications, running outside of the cluster’s data center behind NAT or a firewall. They also work perfectly fine on devices with limited resources. IoT is a good example of a use case for thin clients.
- The binary protocol used by thin clients is language and platform agnostic, which means that you can run a thin client virtually anywhere. Currently, Ignite provides implementations written in Java, .NET, C++, Python, NodeJS and PHP, which already exceeds what we have for thick clients. And it’s fairly easy to add new languages to this list.
- A thin client is not collocation-aware. It’s typically connected to only one node in the cluster, which is used as a gateway — all requests from the client go through this server node. This creates an obvious bottleneck. Some implementations support load balancing between two or more nodes, but even in this case scalability is more limited than with thick clients.
- Thin clients provide limited API. Currently, you can only create/destroy caches, execute key-value operations and SQL queries. Compute Grid and Service Grid APIs are likely to be added in the future (contributions are welcome!). However, advanced features that require push notifications from servers to clients (near caches, continuous queries) or sophisticated threading models (data streaming) will most likely never be implemented for thin clients.
JDBC and ODBC Drivers
JDBC and ODBC are standard SQL APIs for JVM and C++ compatible languages respectively. Ignite provides implementations for these APIs out of the box:
Architecturally, they work exactly like thin clients — connecting to one of the nodes and using that node as a gateway. Because of that, SQL drivers share advantages and disadvantages with thin clients. There are a couple more key differences I would like to mention though.
- JDBC and ODBC are industry standards, which means that the provided drivers enable easier integration with existing SQL-oriented tools. As an example, you can use them to transparently connect BI tools like Tableau or Pentaho to Apache Ignite.
- The limitation here is obvious — you get only SQL API from this type of client connector. In my experience, the vast majority of use cases require more features if you want to get the most from Apache Ignite in terms of scalability and performance. Unless you don’t have a choice other than to use standard JDBC/ODBC, I would absolutely recommend looking at other options.
Apache Ignite also comes with the REST API, which allows performing basic operations like reading or updating cache entries, executing SQL queries, looking at some of the metrics, etc.
In its current implementation, this API is not really suitable for any performance-sensitive purposes, so I usually avoid using it in production for applications of any type.
However, the REST API might sometimes be useful during development or testing — to quickly check a particular entry value or a SQL query result, for example.
Choosing The Right Option
Okay, there are several options for client connectors, and each of them has its own pros and cons. So, which one should you go with for a particular application? Here is a simple algorithm that will help you to make the choice.
- If the application is deployed in the same environment where server nodes run, and as long as there is full network connectivity between the application and every server node (i.e. no firewall or NAT), use the thick client. Generally speaking, thick clients should be your first choice as they are the most efficient and provide the most functionality.
- If the application is remote and/or runs on a device with limited resources, use the thin client. This is your second choice.
- Finally, if the application must use standard JDBC or ODBC API (e.g. it’s a BI tool like Tableau), use the corresponding SQL driver.
That’s it! Not that confusing anymore, right? 🙂 I definitely hope so. But if anything is still unclear, please feel free to comment below.