{"id":11130,"date":"2018-05-16T09:37:23","date_gmt":"2018-05-16T09:37:23","guid":{"rendered":"http:\/\/stblog.lunaeme.com\/?p=11130"},"modified":"2023-09-20T12:56:22","modified_gmt":"2023-09-20T12:56:22","slug":"apache-ignite-cache","status":"publish","type":"post","link":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/","title":{"rendered":"Apache Ignite: More than a simple cache"},"content":{"rendered":"<p>Let us suppose that we start to develop a webserver for our IOT App with a few endpoints, like POST for receive events, GET devicesBySensorType, GET all, and PUT for update device metadata, etc.<\/p>\n<p><!--more--><\/p>\n<p>At first, a cache for common data could seem like a secondary issue, but if we start to think long term and if we want to improve performance and\/or to decrease response time (e.g when a service retrieve data from a database), we realize that a cache is a mandatory requirement.<\/p>\n<p>An initial solution could be to use the always reliable HashMap class (or ConcurrentHashMap after the first ConcurrentModificationException): this is a first attempt that, by caching objects in different maps in memory, may give us quick benefits. But it is not enough.<\/p>\n<h2>Hello Data Grid<\/h2>\n<p>With <strong>Ignite<\/strong>, this is simple, only add the dependency on your scala\/java project:<\/p>\n<pre class=\"lang:default decode:true\">&gt; sbt\n\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"org.apache.ignite\" % \"ignite-core\" % \"2.4.0\"\n\n&gt; maven\n\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;dependency&gt;\n&nbsp;&nbsp;&nbsp;       &lt;groupId&gt;org.apache.ignite&lt;\/groupId&gt;\n          &lt;artifactId&gt;ignite-core&lt;\/artifactId&gt;\n          &lt;version&gt;2.4.0&lt;\/version&gt;\n   &lt;\/dependency&gt;<\/pre>\n<p><span style=\"font-weight: 400;\">Scala code for the example:<\/span><\/p>\n<pre class=\"lang:default decode:true\">object IgniteSimpleDataGrid extends App {\n\n     val igniteConfig = new IgniteConfiguration()\n     val cacheConfig = new CacheConfiguration(\"ignite\")\n     igniteConfig.setCacheConfiguration(cacheConfig)\n     val ignite = Ignition.start(igniteConfig)\n     val cache: IgniteCache[Int, String] = ignite.getOrCreateCache[Int, String](\"ignite\")\n     for (i &lt;- 1 to 10) {\n       cache.put(i, s\"value-$i\")\n     }\n     println(s\"From cache 7 -&gt; ${cache.get(7)}\")\n     println(s\"Not exists 20 -&gt; ${cache.get(20)}\")\n}<\/pre>\n<p>Run the class and see the output<br \/>\n<strong>(Note: ONLY one running Ignite instance per JVM)<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11260 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-2018-03-18-at-23.37.59.png\" alt=\"Screen Shot \" width=\"1308\" height=\"592\"><\/p>\n<p>Perfect, we have our first single version of Ignite Data Grid, but what if we need HA and to deploy another instance of the app? Or it may sound familiar a common situation where that metadata endpoint is related to another service and uses the same information so are in need of sharing data between the apps and, sadly, the maps cache schema solution does not work anymore.<\/p>\n<p>What if I tell you that with <strong>in-memory data grid<\/strong> data could be distributed and every node in the cluster (forming a ring topology) can access and maintain the shared information, besides computing remote functions or custom predicates? Would you believe that this is possible? The answer is <strong>absolutely yes<\/strong> and here is where Ignite stands out among other solutions.<\/p>\n<p>Let\u2019s test <em>IgniteSimpleDataGrid&nbsp;<\/em>class with two instances(nodes) : node1 is already running so before we can start the app again (node2), we need to comment the for cycle (block in the code snippet), because node1 has already populated the cache with values and this means that node2 will only be reading from cache.<\/p>\n<pre class=\"lang:default decode:true\">\/* for (i &lt;- 1 to 10) {\n&nbsp;&nbsp;&nbsp;&nbsp;cache.put(i, s\"value-$i\")\n&nbsp;&nbsp;&nbsp;&nbsp;} *\/\n&nbsp;&nbsp;&nbsp;println(s\"From cache 7 -&gt; ${cache.get(7)}\")\n&nbsp;&nbsp;&nbsp;println(s\"Not exists 20 -&gt; ${cache.get(20)}\")<\/pre>\n<p>Pay attention to the output in node2: the console prints almost the same data as node1 in the first example (look at the id, it is different).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11261 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-2018-03-18-at-23.39.54.png\" alt=\"Screen Shot 2\" width=\"685\" height=\"104\"><\/p>\n<p>And now, look at the output in node1:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11262 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-3.png\" alt=\"Screen Shot 3\" width=\"691\" height=\"108\"><\/p>\n<p>Both nodes print this line:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11263 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-4.png\" alt=\"Screen Shot 4\" width=\"587\" height=\"17\"><\/p>\n<p>Great!! That means that we have our Ignite in-memory distributed key-value store cluster up and running!! (more than a simple cache, and we see why).<br \/>\nNodes have been self-discovered and all of them see the same data. If we start more nodes, the topology will keep on growing up, each node will be assigned with a unique id and the server number will increase ( e.g. servers =3, servers=4 , etc..)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11265 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-5.png\" alt=\"Screen Shot 5\" width=\"430\" height=\"50\"><\/p>\n<p>If we stop node1, topology decreases and the rest of the running nodes print this change, because they are listening to topology change events.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11266 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-6.png\" alt=\"Screen Shot 6\" width=\"631\" height=\"56\"><\/p>\n<p>Ignite implements high availability, if a node goes down, the data is then re-balanced around the cluster without any user operation involved.<\/p>\n<p>Let us clarify this point.<\/p>\n<blockquote><p><strong>My definition of Ignite is that it&#8217;s a distributed in-memory cache, query and processing platform for working with large-scale data sets in real-time (leaving aside, streaming processing, Spark integration, Machine learning grid, Ignite FileSystem, persistence, transactions&#8230;)<\/strong><\/p><\/blockquote>\n<p>How can Ignite<strong> automagically<\/strong> create a cluster? Well, it provides TcpDiscoverySpi as a default implementation of DiscoverySpi that uses TCP\/IP for node discovery. Discovery SPI can be configured for Multicast- and Static IP-based node discovery. (Spi = especially Ip Finder)<\/p>\n<p>It means that nodes use multicast to find each other:<\/p>\n<pre class=\"lang:default decode:true\">val igniteConfig = new IgniteConfiguration()\nval spi = new TcpDiscoverySpi()\nval ipFinder = new TcpDiscoveryMulticastIpFinder()\nipFinder.setMulticastGroup(\"228.10.10.157\") \/\/ Default value = DFLT_MCAST_GROUP = \"228.1.2.4\";\nspi.setIpFinder(ipFinder)\ncfg.setDiscoverySpi(spi)\nval ignite = Ignition.start(igniteConfig)\nval cache: IgniteCache[Int, String] = ignite.getOrCreateCache[Int, String](\"ignite\")<\/pre>\n<h2><span style=\"font-weight: 400;\">Ignite Ring Topology<\/span><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11272 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-7-1.png\" alt=\"Screen Shot 7\" width=\"523\" height=\"335\"><\/p>\n<p>In the image the nodes form a ring of <strong>server<\/strong>&nbsp;nodes but, inside an Ignite cluster, nodes can either have roles and belong to a cluster group or they could be <strong>client<\/strong>&nbsp;nodes (this means &#8220;outside&#8221; of the ring and without the possibility of maintaining cached data. This may prove useful for external applications.<\/p>\n<p>Nodes can broadcast messages to other nodes in a particular group:<\/p>\n<pre class=\"lang:default decode:true\">val igniteCluster = ignite.cluster()\n\/\/Send to cluster remotes nodes (ignoring this) this Code\nignite.compute(igniteCluster.forRemotes()).broadcast(\n      new IgniteRunnable {\n          override def run(): Unit = println(s\"Hello node ${igniteCluster.localNode()},this message had been send by igniteCompute broadcast\")\n       }\n)<\/pre>\n<p>As this example shows, when a node starts, it sends a message to the cluster group <strong>forRemotes<\/strong> and to all other nodes (except from itself) that have been configured in <strong>mode=server<\/strong>. You might see an exception on the first node at the beginning when the cluster has just been created but don&#8217;t worry because it is normal.<\/p>\n<p>Furthermore it is possible to define nodes with your custom attributes:<\/p>\n<pre class=\"lang:default decode:true\">igniteConfig.setUserAttributes(Map[String,Any](\"ROLE\" -&gt; \"MASTER\").asJava)\nignite.compute(igniteCluster.forAttribute(\"ROLE\",\"WORKER\")).broadcast(new IgniteRunnable {\n        override def run(): Unit = println(s\"Hello worker node ${igniteCluster.localNode()},\" +s\"this message had been send by ignite master node\")\n})<\/pre>\n<p><span style=\"font-weight: 400;\">Here the node has attribute <strong>ROLE = MASTER<\/strong>, and broadcast only to nodes with <strong>ROLE = WORKER<\/strong><\/span><\/p>\n<p><span style=\"font-weight: 400;\">Nodes with:<\/span><\/p>\n<pre class=\"lang:default decode:true\">igniteConfig.setUserAttributes(Map[String,Any](\"ROLE\" -&gt; \"WORKER\").asJava)<\/pre>\n<p><span style=\"font-weight: 400;\">will receive the message:<\/span><\/p>\n<blockquote><p><strong>As long as your cluster is alive, Ignite will guarantee that the data between different cluster nodes will always remain consistent regardless of crashes or topology changes.<\/strong><\/p><\/blockquote>\n<p>So far so good: we have seen nodes, topology, cluster groups, broadcast and now let us look forward to one of the best feature of Ignite (PS: durable memory, persistence, spark RDD, streaming, transactions will be tackled in the next posts XD):&nbsp;<strong>SQL Queries<\/strong>!!<br \/>\nDoes it sounds crazy? Yes, SQLQueries! Over your data!<br \/>\nIgnite is fully ANSI-99 compliant and it supports Text queries and Predicate-based Scan Queries.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11273 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-8-1.png\" alt=\"Screen Shot 8\" width=\"371\" height=\"260\"><\/p>\n<h2><span style=\"font-weight: 400;\">Cache Queries<\/span><\/h2>\n<p>Before starting to play with code, a few considerations:<\/p>\n<ul>\n<li><span style=\"font-weight: 400;\">Add dependency<\/span><\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">sbt = \"org.apache.ignite\" % \"ignite-indexing\" % \"2.4.0\"\n\n&nbsp;maven = &lt;dependency&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;     &nbsp;&lt;groupId&gt;org.apache.ignite&lt;\/groupId&gt;\n            &lt;artifactId&gt;ignite-indexing&lt;\/artifactId&gt;\n            &lt;version&gt;2.4.0&lt;\/version&gt;\n       &nbsp; &lt;\/dependency&gt;<\/pre>\n<ul>\n<li>Tell Ignite, which entities are allowed to be used on queries, it is easy, only adding annotations to classes:<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true \">case class IotDevice(\n@(QuerySqlField@field)(index = true) name: String,\n@(QuerySqlField@field)(index = true) gpio: String,\n@(QueryTextField@field) sensorType: String,\n@(QueryTextField@field) model: String)<\/pre>\n<p>Here we said, that all fields are available for use in queries, and add indexes over name and gpio attributes (like in any sql database)<\/p>\n<ul>\n<li>After indexed and queryable fields are defined, they have to be registered in the SQL engine along with the object types they belong to.<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">val igniteConfig = new IgniteConfiguration()\nval cacheConfig = new CacheConfiguration(\"ignite\")\ncacheConfig.setIndexedTypes(Seq(classOf[String], classOf[IotDevice]): _*)\nigniteConfig.setCacheConfiguration(cacheConfig)\nval ignite = Ignition.start(igniteConfig)\nval cacheIot: IgniteCache[String, IotDevice] = ignite.getOrCreateCache[Int, String](\"ignite\")<\/pre>\n<p>Following the idea of IoT WebServer, for example we develop the web server and put data to the cacheIot defined above.<\/p>\n<pre class=\"lang:default decode:true\">val temp1 = IotDevice(name = \"temp1\", gpio = \u201c123ASD\", sensorType = \"temperature\", model = \"test\")\ncacheIot.put(temp1.gpio,temp1)\nval temp2 = IotDevice(name = \"temp2\", gpio = \u201c456ASD\", sensorType = \"temperature\", model = \"test\")\ncacheIot.put(temp2.gpio,temp2)<\/pre>\n<p>Now user call method: <strong>GET\/devicesBySensorType?sensor=temperature<\/strong><\/p>\n<p>In our IotDevice case class <strong>sensorType<\/strong>&nbsp;is valid for queries thus, we can execute this query in three ways in Ignite:<\/p>\n<p>Simple sql :<\/p>\n<pre class=\"lang:default decode:true\">val sqlText = s\"sensorType = 'temperature'\"\nval sql = new SqlQuery[String, IotDevice](classOf[IotDevice], sqlText)\nval temperatureQueryResult = cacheIot.query(sql).getAll.asScala.map(_.getValue)\nprintln(s\"SqlQuery = $temperatureQueryResult\")<\/pre>\n<p><span style=\"font-weight: 400;\">ScanQuery:<\/span><\/p>\n<pre class=\"lang:default decode:true\">val cursor = cacheIot.query(new ScanQuery(new IgniteBiPredicate[String, IotDevice] {\n        override def apply(key: String, entryValue: IotDevice) : Boolean = entryValue.sensorType == \"temperature\"\n}))\nval temperatureScanResult = cursor.getAll.asScala\nprintln(s\"ScanQuery = $temperatureScanResult\")<\/pre>\n<p><span style=\"font-weight: 400;\">Text-based queries based on Lucene indexing, here find all IotDevices where sensorType == &#8220;temperature&#8221; (the annotation on model attribute<strong> QueryTextField<\/strong> allow this query, if you want, Ignite supports more than one QueryTextField)<\/span><\/p>\n<pre class=\"lang:default decode:true\">val textQuery = new TextQuery[IotDevice, String](classOf[IotDevice], \"temperature\")\nval temperatureTextResult = cacheIot.query(textQuery).getAll.asScala\nprintln(s\"TextQuery = $temperatureTextResult\") \/\/all devices with sensorType = temperature<\/pre>\n<p><span style=\"font-weight: 400;\">The result of queries:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11274 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-9-1.png\" alt=\"\" width=\"1279\" height=\"75\"><\/p>\n<p>Here is the full code for the example:<\/p>\n<pre class=\"lang:default decode:true \">import org.apache.ignite.cache.query.annotations.{QuerySqlField, QueryTextField}\nimport org.apache.ignite.cache.query.{ScanQuery, SqlQuery, TextQuery}\nimport org.apache.ignite.configuration.{CacheConfiguration, IgniteConfiguration}\nimport org.apache.ignite.lang.IgniteBiPredicate\nimport org.apache.ignite.{IgniteCache, Ignition}\nimport scala.annotation.meta.field\nimport scala.collection.JavaConverters._\n\nobject IgniteSql extends App {\n\n     val igniteConfig = new IgniteConfiguration()\n     val cacheConfig = new CacheConfiguration(\"ignite\")\n     cacheConfig.setIndexedTypes(Seq(classOf[String], classOf\\[IotDevice]): _*)\n     igniteConfig.setCacheConfiguration(cacheConfig)\n\n     val ignite = Ignition.start(igniteConfig)\n     val cacheIot: IgniteCache[String, IotDevice] = ignite.getOrCreateCache[String, IotDevice](\"ignite\")\n\n     val temp1 = IotDevice(name = \"temp1\", gpio = \"123ASD\", sensorType = \"temperature\", model = \"testTemp\")\n     cacheIot.put(temp1.gpio, temp1)\n     val temp2 = IotDevice(name = \"temp2\", gpio = \"456ASD\", sensorType = \"temperature\", model = \"testTemp\")\n     cacheIot.put(temp2.gpio, temp2)\n\n     val sqlText = s\"sensorType = 'temperature'\"\n     val sql = new SqlQuery[String, IotDevice](classOf[IotDevice], sqlText)\n     val temperatureQueryResult = cacheIot.query(sql).getAll.asScala.map(_.getValue)\n     println(s\"SqlQuery = $temperatureQueryResult\")\n\n     val cursor = cacheIot.query(new ScanQuery(new IgniteBiPredicate[String, IotDevice] {\n          override def apply(key: String, entryValue: IotDevice): Boolean = entryValue.sensorType == \"temperature\"}))\n\n     val temperatureScanResult = cursor.getAll.asScala\n     println(s\"ScanQuery = $temperatureScanResult\")\n\n     val textQuery = new TextQuery[IotDevice, String](classOf[IotDevice], \"temperature\")\n     val temperatureTextResult = cacheIot.query(textQuery).getAll.asScala\n     println(s\"TextQuery = $temperatureTextResult\") \/\/all devices with sensorType = temperature\n\n}\n\ncase class IotDevice(@(QuerySqlField@field)(index = true) name: String,\n@(QuerySqlField@field)(index = true) gpio: String,\n@(QueryTextField@field) sensorType: String,\n@(QueryTextField@field) model: String)<\/pre>\n<h2><span style=\"font-weight: 400;\">&nbsp;Partition and Replication<\/span><\/h2>\n<p>Besides having our cluster and executing queries, we might ask ourselves: where currently is our data? Ignite provides three different modes of cache operation: PARTITIONED, REPLICATED, and LOCAL:<\/p>\n<ul>\n<li><strong>Partitioned<\/strong>: this mode is the most scalable among the distributed cache modes. In this mode the overall data set is divided equally into partitions and all partitions are split equally between participating nodes. This is ideal when working with large data sets and updates are frequent. In this mode you can also optionally configure any number of backup nodes for cached data.<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true \">cacheCfg.setCacheMode(CacheMode.PARTITIONED)\ncacheCfg.setBackups(1);<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11277 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-10.png\" alt=\"Screen Shot 10\" width=\"484\" height=\"416\"><\/p>\n<ul>\n<li><strong>Replicated<\/strong>: this mode is expensive because all the data is replicated to every node in the cluster and every data updates must be propagated to all other nodes that can have an impact on performance and scalability. This mode is ideal when we are working with small datasets and updates are not frequent.<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true \">cacheCfg.setCacheMode(CacheMode.REPLICATED)<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11278 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-11.png\" alt=\"\" width=\"481\" height=\"377\"><\/p>\n<ul>\n<li><span style=\"font-weight: 400;\"><strong>Local<\/strong>: this mode is the most light-weight mode of cache operation, as no data is distributed to other cache nodes.<\/span><\/li>\n<\/ul>\n<h2><span style=\"font-weight: 400;\">In-Memory features<\/span><\/h2>\n<p>Since Ignite architecture is *memory friendly*, RAM is always treated as the first memory tier, where all the processing happens. Some benefits of this:<\/p>\n<p>&#8211; <strong>Off-heap Based<\/strong>: Data and indexes are stored outside Java heap, therefore only your app code may trigger Garbage collection actions.<br \/>\n&#8211; <strong>Predictable memory usage<\/strong>: It is possible to set up memory utilization.<br \/>\n&#8211; <strong>Automatic memory defragmentation<\/strong>: Apache Ignite uses the memory as efficiently as possible and executes defragmentation routines in the background thus avoiding fragmentation.<br \/>\n&#8211; <strong>Improved performance and memory utilization<\/strong>: All the data and indexes are stored in paged format with similar representation in memory and on disk, which removes any need for serializing or deserializing of data.<\/p>\n<h2><span style=\"font-weight: 400;\">Conclusion<\/span><\/h2>\n<p>Could Ignite help your distributed architectures? Would it be costly to integrate Ignite in your apps that are already in production?<\/p>\n<p>There is a lot more to cover and discuss&#8230;and a lot of code to try out! We only scratched the surface of this great tool.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-11279 aligncenter\" src=\"http:\/\/blog.stratio.com\/wp-content\/uploads\/2018\/05\/Screen-Shot-12.png\" alt=\"\" width=\"576\" height=\"357\"><\/p>\n<p>For more information, documentation, and screencasts, visit:<\/p>\n<ul>\n<li><a href=\"https:\/\/ignite.apache.org\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">Ignite Apache<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/apache\/ignite\" target=\"_blank\" rel=\"noopener noreferrer\">Github Apache Ignite<\/a><\/li>\n<li><a href=\"https:\/\/twitter.com\/ApacheIgnite\" target=\"_blank\" rel=\"noopener noreferrer\">@ApacheIgnite<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/gastonlucero\/ignitestratio\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/gastonlucero\/ignitestratio<\/a><\/li>\n<li><a href=\"https:\/\/apacheignite.readme.io\/docs\/cluster-config#multicast-based-discovery\" target=\"_blank\" rel=\"noopener noreferrer\">Multicast in Ignite<\/a><\/li>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/IP_multicast\" target=\"_blank\" rel=\"noopener noreferrer\">Wikipedia &nbsp;&#8211; IP_Multicast<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Apache Ignite is a distributed in-memory cache, query and processing platform for working with large-scale data sets in real-time (leaving aside, streaming processing, Spark integration, Machine learning grid, Ignite FileSystem, persistence, transactions\u2026)<\/p>\n","protected":false},"author":2,"featured_media":13552,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[686],"tags":[],"ppma_author":[794],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v22.9 (Yoast SEO v22.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Apache Ignite, more than a simple cache - Blog<\/title>\n<meta name=\"description\" content=\"Apache Ignite is a distributed in-memory cache, query and processing platform for working with large-scale data sets in real-time (leaving aside, streaming processing, Spark integration, Machine learning grid, Ignite FileSystem, persistence, transactions\u2026)\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Apache Ignite: More than a simple cache\" \/>\n<meta property=\"og:description\" content=\"Apache Ignite is a distributed in-memory cache, query and processing platform for working with large-scale data sets in real-time (leaving aside, streaming processing, Spark integration, Machine learning grid, Ignite FileSystem, persistence, transactions\u2026)\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/\" \/>\n<meta property=\"og:site_name\" content=\"Stratio\" \/>\n<meta property=\"article:published_time\" content=\"2018-05-16T09:37:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-20T12:56:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1300\" \/>\n\t<meta property=\"og:image:height\" content=\"820\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@stratiobd\" \/>\n<meta name=\"twitter:site\" content=\"@stratiobd\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/af4f5fbbeb95bd7d55f79d9a677e615d\"},\"headline\":\"Apache Ignite: More than a simple cache\",\"datePublished\":\"2018-05-16T09:37:23+00:00\",\"dateModified\":\"2023-09-20T12:56:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/\"},\"wordCount\":1394,\"commentCount\":7,\"publisher\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg\",\"articleSection\":[\"Product\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/\",\"url\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/\",\"name\":\"Apache Ignite, more than a simple cache - Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg\",\"datePublished\":\"2018-05-16T09:37:23+00:00\",\"dateModified\":\"2023-09-20T12:56:22+00:00\",\"description\":\"Apache Ignite is a distributed in-memory cache, query and processing platform for working with large-scale data sets in real-time (leaving aside, streaming processing, Spark integration, Machine learning grid, Ignite FileSystem, persistence, transactions\u2026)\",\"breadcrumb\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#primaryimage\",\"url\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg\",\"contentUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg\",\"width\":1300,\"height\":820},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.stratio.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Apache Ignite: More than a simple cache\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#website\",\"url\":\"https:\/\/www.stratio.com\/blog\/\",\"name\":\"Stratio Blog\",\"description\":\"Corporate blog\",\"publisher\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.stratio.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\",\"name\":\"Stratio\",\"url\":\"https:\/\/www.stratio.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png\",\"contentUrl\":\"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png\",\"width\":260,\"height\":55,\"caption\":\"Stratio\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/stratiobd\",\"https:\/\/es.linkedin.com\/company\/stratiobd\",\"https:\/\/www.youtube.com\/c\/StratioBD\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/af4f5fbbeb95bd7d55f79d9a677e615d\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/image\/589aaf4b404b1fe099b09564062c4563\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g\",\"caption\":\"admin\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Apache Ignite, more than a simple cache - Blog","description":"Apache Ignite is a distributed in-memory cache, query and processing platform for working with large-scale data sets in real-time (leaving aside, streaming processing, Spark integration, Machine learning grid, Ignite FileSystem, persistence, transactions\u2026)","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/","og_locale":"en_US","og_type":"article","og_title":"Apache Ignite: More than a simple cache","og_description":"Apache Ignite is a distributed in-memory cache, query and processing platform for working with large-scale data sets in real-time (leaving aside, streaming processing, Spark integration, Machine learning grid, Ignite FileSystem, persistence, transactions\u2026)","og_url":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/","og_site_name":"Stratio","article_published_time":"2018-05-16T09:37:23+00:00","article_modified_time":"2023-09-20T12:56:22+00:00","og_image":[{"width":1300,"height":820,"url":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_creator":"@stratiobd","twitter_site":"@stratiobd","twitter_misc":{"Written by":"admin","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#article","isPartOf":{"@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/"},"author":{"name":"admin","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/af4f5fbbeb95bd7d55f79d9a677e615d"},"headline":"Apache Ignite: More than a simple cache","datePublished":"2018-05-16T09:37:23+00:00","dateModified":"2023-09-20T12:56:22+00:00","mainEntityOfPage":{"@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/"},"wordCount":1394,"commentCount":7,"publisher":{"@id":"https:\/\/www.stratio.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#primaryimage"},"thumbnailUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg","articleSection":["Product"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/","url":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/","name":"Apache Ignite, more than a simple cache - Blog","isPartOf":{"@id":"https:\/\/www.stratio.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#primaryimage"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#primaryimage"},"thumbnailUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg","datePublished":"2018-05-16T09:37:23+00:00","dateModified":"2023-09-20T12:56:22+00:00","description":"Apache Ignite is a distributed in-memory cache, query and processing platform for working with large-scale data sets in real-time (leaving aside, streaming processing, Spark integration, Machine learning grid, Ignite FileSystem, persistence, transactions\u2026)","breadcrumb":{"@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#primaryimage","url":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg","contentUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2018\/07\/Apache-Ignite_More-than-a-simple-cache.jpg","width":1300,"height":820},{"@type":"BreadcrumbList","@id":"https:\/\/www.stratio.com\/blog\/apache-ignite-cache\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.stratio.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Apache Ignite: More than a simple cache"}]},{"@type":"WebSite","@id":"https:\/\/www.stratio.com\/blog\/#website","url":"https:\/\/www.stratio.com\/blog\/","name":"Stratio Blog","description":"Corporate blog","publisher":{"@id":"https:\/\/www.stratio.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.stratio.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.stratio.com\/blog\/#organization","name":"Stratio","url":"https:\/\/www.stratio.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png","contentUrl":"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png","width":260,"height":55,"caption":"Stratio"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/stratiobd","https:\/\/es.linkedin.com\/company\/stratiobd","https:\/\/www.youtube.com\/c\/StratioBD"]},{"@type":"Person","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/af4f5fbbeb95bd7d55f79d9a677e615d","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/image\/589aaf4b404b1fe099b09564062c4563","url":"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g","caption":"admin"}}]}},"authors":[{"term_id":794,"user_id":2,"is_guest":0,"slug":"admin","display_name":"admin","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/11130"}],"collection":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/comments?post=11130"}],"version-history":[{"count":18,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/11130\/revisions"}],"predecessor-version":[{"id":13561,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/11130\/revisions\/13561"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/media\/13552"}],"wp:attachment":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/media?parent=11130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/categories?post=11130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/tags?post=11130"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=11130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}