{"id":623,"date":"2020-03-25T10:00:21","date_gmt":"2020-03-25T17:00:21","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=623"},"modified":"2020-03-31T09:03:25","modified_gmt":"2020-03-31T16:03:25","slug":"java-sdk-v4-async-vs-sync","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/java-sdk-v4-async-vs-sync\/","title":{"rendered":"Azure Cosmos DB Java SDK v4 &#8211; Exploring the new Async API"},"content":{"rendered":"<p><span style=\"font-size: 12pt;\">In this second of our series for the <a href=\"http:\/\/www.azurecosmosdb.com\">Azure Cosmos DB<\/a> Java SDK v4 for Core (SQL) API, I\u2019m going to explore our new Async API.<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">To get you caught up though go check out the first post in this series <a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/java-sdk-v4-1\/\">Azure Cosmos DB Java SDK v4 &#8211; New Java SDK Quickstart Guide and Sample Code!<\/a><\/span><\/p>\n<p><span style=\"font-size: 12pt;\">Current users of our Java SDK v2 are familiar with our Sync API and may have tried our Java SDK v3 with mixed results. We are really excited about our new Java SDK v4 because the performance is much better than our v3 SDK but also because the Java SDK v4 implements both an Async API and Sync API.<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">If you are a Sync API user you may be wondering why would I want to use the Async API. The answer is that asynchronous calls will allow you to better saturate your available throughput. This is important because you always want to squeeze every ounce of performance for the provisioned throughput you are paying for.<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">Another thing to understand about our new Async API is that it is built upon a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reactive_programming\">Reactive programming<\/a> model. Reactive programming is a declarative programming data flow paradigm in which program operation and control flow are described as a stream of data items passing through a pipeline of operations in which each operation affects the data which flows downstream. In practical terms, your code will describe a directed graph of operations which represents the logic of the program. Here\u2019s a simple declarative data flow in pseudo-code:<\/span><\/p>\n<p style=\"text-align: center;\"><span style=\"font-family: 'courier new', courier, monospace; font-size: 10pt;\">asynchronous data source =&gt; operation1 =&gt; operation2 =&gt; operation3 =&gt; print<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">With the Async API, Java SDK 4.0 requires that you use\u00a0<a href=\"https:\/\/projectreactor.io\/\">Reactor<\/a>\u00a0framework to describe the logic of your application. In the rest of this post. I\u2019ll demonstrate some common Cosmos DB tasks with Async API and Reactor. Then I\u2019ll show the same tasks with Sync API for comparison. When you&#8217;re done, take a look at our new <a href=\"https:\/\/github.com\/Azure-Samples\/azure-cosmos-java-sql-api-samples\/blob\/master\/reactor-pattern-guide.md\">Reactor Pattern Guide<\/a> to help you get started with Reactive Programming!<\/span><\/p>\n<p><strong>Note: <\/strong>Real Azure Cosmos DB performance test results are shown below. Reproducing them will incur <a href=\"https:\/\/azure.microsoft.com\/en-us\/pricing\/details\/cosmos-db\/\">container throughput and storage costs<\/a>.<\/p>\n<h2><span style=\"font-size: 14pt;\"><strong>Async API<\/strong><\/span><\/h2>\n<p>The Async API sends requests to Azure Cosmos DB using <a href=\"https:\/\/github.com\/reactor\/reactor-netty\">Reactor Netty<\/a> with asynchronous I\/O at the OS level \u2013 therefore your application won\u2019t block waiting for the response to each request. Instead your application will push out as many requests per second as your system hardware and your\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/estimate-ru-with-capacity-planner\">provisioned throughput<\/a>\u00a0allow. Meanwhile responses from the server will be handled as they arrive. This raises the upper bound on request throughput substantially.<\/p>\n<p><span style=\"font-size: 12pt;\">This code is from the <a href=\"https:\/\/github.com\/Azure-Samples\/azure-cosmos-java-sql-api-samples\/tree\/master\/src\/main\/java\/com\/azure\/cosmos\/examples\/requestthroughput\/async\">Async Request Throughput sample<\/a>. Here is an example of creating a new database- and container-if not-exists and then inserting new items using the Async API. Clients, databases, and containers have special async types in Java SDK v4 (like <span style=\"font-family: courier new,courier,monospace; font-size: 10pt;\">CosmosAsyncClient<\/span> below.) Notice the time between request and response is used to run background tasks.<\/span><\/p>\n<p><script src=\"https:\/\/gist.github.com\/anfeldma-ms\/824f6f83d1b6298ad87de17160b6dd34.js\"><\/script><\/p>\n<p>I configured an Azure VM to issue Async API requests to Azure Cosmos DB. As you can see below, the VM drove more than 64000 RU\/s of async request throughput into a geographically co-located container using a single execution thread:<\/p>\n<p><img decoding=\"async\" class=\" wp-image-727 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/04\/async_screenshot-1.png\" alt=\"Image async screenshot\" width=\"383\" height=\"627\" \/><\/p>\n<p>In all the tests I ran for this blog post, I changed container provisioned throughput from\u00a0400 RU\/s to 100000 RU\/s to fully demonstrate attainable throughput.<\/p>\n<p>Now let&#8217;s see how Sync API compares.<\/p>\n<p><span style=\"font-size: 14pt;\"><strong>Sync API<\/strong><\/span><\/p>\n<p>If you found the Reactor patterns hard to follow, a benefit of Sync API is that code can be simpler and easier to follow.<\/p>\n<p><span style=\"font-size: 12pt;\">One thing you may find surprising is that the Sync API is actually built on top of the Async API. Put simply: it makes an Async API call and then blocks on it. For example a Sync API call to <span style=\"font-family: courier new,courier,monospace; font-size: 10pt;\">CosmosContainer.createItem()<\/span> basically calls <span style=\"font-family: courier new,courier,monospace; font-size: 10pt;\">CosmosAsyncContainer.block()<\/span>.<\/span> <span style=\"font-family: courier new,courier,monospace; font-size: 10pt;\">.block()<\/span> hangs until the Async API gets a response. Notice this means we cannot use the time between request and response for other tasks.<\/p>\n<p><span style=\"font-size: 12pt;\">Here is a snippet from the <a href=\"https:\/\/github.com\/Azure-Samples\/azure-cosmos-java-sql-api-samples\/tree\/master\/src\/main\/java\/com\/azure\/cosmos\/examples\/requestthroughput\/sync\">Sync Request Throughput sample<\/a>. This code below does the same thing as the snippet above, but using only sync calls. In the line that starts with <span style=\"font-family: courier new,courier,monospace; font-size: 10pt;\">client = <\/span>, <span style=\"font-family: courier new,courier,monospace; font-size: 10pt;\">.buildClient()<\/span> chooses the Sync API for your application.\u00a0<\/span><\/p>\n<p><script src=\"https:\/\/gist.github.com\/anfeldma-ms\/c69d53eeb0e4f6258837290b6be7d247.js\"><\/script><\/p>\n<p>I updated my Azure VM to send requests using Sync API, and for comparison it drove ~1000 RU\/s of sync request throughput into Azure Cosmos DB &#8211; much less than the &gt;64000 RU\/s attainable with Async API:<\/p>\n<p><img decoding=\"async\" class=\"wp-image-728 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/04\/sync_screenshot.png\" alt=\"Image sync screenshot\" width=\"380\" height=\"593\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/04\/sync_screenshot.png 325w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/04\/sync_screenshot-192x300.png 192w\" sizes=\"(max-width: 380px) 100vw, 380px\" \/><\/p>\n<p>And this is still with 100000 RU\/s provisioned throughput. This happens because Sync API waits the full response time between requests. As long as Async API calls are non-blocking, Async throughput is the same regardless of response time and will be higher than Sync API.<\/p>\n<p><span style=\"font-size: 12pt;\"><strong>Conclusion<\/strong><\/span><\/p>\n<p><span style=\"font-size: 12pt;\">So that\u2019s it! We think our new Async API is pretty great. But if you\u2019re not there yet and want or need to keep using the Sync API well we got you covered there too. If you\u2019re ready to take that next step or just want to explore, we\u2019ve got lots of resources to help you get started. Go check out our new <a href=\"https:\/\/github.com\/Azure-Samples\/azure-cosmos-java-sql-api-samples\/blob\/master\/reactor-pattern-guide.md\">Reactor Pattern Guide<\/a> and our <a href=\"https:\/\/github.com\/Azure-Samples\/azure-cosmos-java-sql-api-samples\">Java SDK v4 samples<\/a> as well as our updated <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/cosmos-db\/performance-tips-async-java\">performance tips for Async Java<\/a>.<\/span><\/p>\n<p><span style=\"font-size: 12pt;\">Enjoy and keep an eye out for our next post, Azure Cosmos DB Java SDK v4, Post #3: How to make a Java SDK v4 app with Change Feed!!<\/span><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this second of our series for the Azure Cosmos DB Java SDK v4 for Core (SQL) API, I\u2019m going to explore our new Async API. To get you caught up though go check out the first post in this series Azure Cosmos DB Java SDK v4 &#8211; New Java SDK Quickstart Guide and Sample [&hellip;]<\/p>\n","protected":false},"author":20288,"featured_media":61,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[14,643,19],"tags":[],"class_list":["post-623","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-core-sql-api","category-java-sdk","category-tips-and-tricks"],"acf":[],"blog_post_summary":"<p>In this second of our series for the Azure Cosmos DB Java SDK v4 for Core (SQL) API, I\u2019m going to explore our new Async API. To get you caught up though go check out the first post in this series Azure Cosmos DB Java SDK v4 &#8211; New Java SDK Quickstart Guide and Sample [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/623","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/20288"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=623"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/623\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/61"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=623"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}