This is an automated email from the ASF dual-hosted git repository.
dpavlov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-training.git
The following commit(s) were added to refs/heads/master by this push:
new d5f19a2 TRAINING-18: Apache Ignite: JDK requirements, put & get
operations (#33)
d5f19a2 is described below
commit d5f19a215fbbcdd6318be0ac1467775e9c31aeb4
Author: Dmitriy Pavlov <[email protected]>
AuthorDate: Wed Oct 30 20:53:44 2019 +0300
TRAINING-18: Apache Ignite: JDK requirements, put & get operations (#33)
---
content/Ignite/pom.xml | 14 ++
content/Ignite/src/main/asciidoc/index.adoc | 219 ++++++++++++++++++++-
.../{StartClientNode.java => PutGetExample.java} | 24 ++-
.../Ignite/src/main/java/example/SqlExample.java | 121 ++++++++++++
.../src/main/java/example/StartClientNode.java | 5 +-
.../resources/images/replicated_vs_partitioned.png | Bin 0 -> 26704 bytes
6 files changed, 373 insertions(+), 10 deletions(-)
diff --git a/content/Ignite/pom.xml b/content/Ignite/pom.xml
index d4276c8..da4a6b7 100644
--- a/content/Ignite/pom.xml
+++ b/content/Ignite/pom.xml
@@ -222,6 +222,15 @@
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.14.v20181114</version>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
</plugins>
</build>
@@ -231,5 +240,10 @@
<artifactId>ignite-core</artifactId>
<version>2.7.5</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-indexing</artifactId>
+ <version>2.7.5</version>
+ </dependency>
</dependencies>
</project>
diff --git a/content/Ignite/src/main/asciidoc/index.adoc
b/content/Ignite/src/main/asciidoc/index.adoc
index 730170c..acc13ec 100644
--- a/content/Ignite/src/main/asciidoc/index.adoc
+++ b/content/Ignite/src/main/asciidoc/index.adoc
@@ -19,9 +19,10 @@
:revealjs_progress: true
:revealjs_slidenumber: true
:sourcedir: ../java
+:imagesdir: ../resources/images
== What is Apache Ignite?
-Ignite™ is a memory-centric distributed database, caching, and processing
platform.
+Apache Ignite™ is a memory-centric distributed database, caching, and
processing platform.
2 major use-cases
@@ -33,7 +34,7 @@ IMDG = Stores data (data grid) + Processes data (compute grid)
- Stores entries in-memory
- Data is distributed among nodes
-- Needs external store
+- May need external data source (DB, REST, other)
- Collocated Processing = code goes to data
== In-Memory Database
@@ -81,6 +82,31 @@ Maven
</dependency>
----
+== Download full dirstibution
+Go to Ignite Project site
+https://ignite.apache.org/[https://ignite.apache.org/] -> Downloads -> Binaries
+
+Download latest binary release from the table
https://ignite.apache.org/download.cgi#binaries[here]
+
+Unzip to any folder.
+
+\bin\ignite.sh / ignite.bat will start server node
+
+== Java Requirements
+JDK 8 and later
+
+Start script will auto-detect version of Java
+
+https://apacheignite.readme.io/docs/getting-started#section-running-ignite-with-java-9-10-11[Running
using Java 9+]
+from IDE requires additional parameters
+
+[.small]`--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED
+--add-exports=java.base/sun.nio.ch=ALL-UNNAMED
+--add-exports=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED
+--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED
+--add-exports=java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED
+--illegal-access=permit`
+
== Starting a server node
By default, Ignite starts server node
[source,java]
@@ -99,3 +125,192 @@ Both server and client nodes will log
`Topology snapshot [ver=2, locNode=b5fc314f, servers=1, clients=1,
state=ACTIVE, CPUs=12, offheap=3.2GB, heap=7.1GB]`
This means nodes detected each other
+
+== Save data into Grid
+Ignite supports JCache JSR 107 API,
+`IgniteCache<K,V> extends javax.cache.Cache<K,V>`
+
+[source,java]
+----
+include::{sourcedir}/example/PutGetExample.java[tags=contains,indent=0]
+----
+
+== Dynamic Cache
+----
+ignite.getOrCreateCache(CacheConfiguration cfg)
+----
+
+Creates an instance of the cache on the fly
+
+----
+ignite.createCache(CacheConfiguration cfg)
+----
+
+Creates cache instance
+
+Ignite will create and deploy the cache across all server cluster members
+
+Cache will be deployed to any new joined node
+
+Limitation - not possible to create new cache in transaction
+
+== Static cache
+Accessed using method
+----
+ignite.cache(String name)
+----
+Will return existing cache or null
+
+- No cache creation under running transaction
+
+- User has to provide configuration before node startup
+
+== Application and cache
+Applications are usually made up of multiple caches
+
+- one for each data type to be stored
+
+-- This is a best practice
+
+-- If you have two classes, Card and Client, you should have two caches
+
+== Replicated and partitioned
+
+image::replicated_vs_partitioned.png[]
+
+Replicated - Cache A
+Partitioned - Cache B & C
+Replicated, use case:
+rare write, often - read, e.g. dictionary
+
+== Partitioned Caches
+Most common usage of cache
+
+.Defaults
+
+. 1024 partitions
+. No redundancy
+. In-memory - volatile
+
+WARNING: Configure backups for fault tolerance
+
+For most cases: 1 backup is enough
+
+== Cache Atomicity Mode
+ATOMIC
+
+- distributed transactions not supported; distributed locking not supported
+- higher performance and throughput ratios
+
+TRANSACTIONAL
+
+- ACID Compliant
+- Transaction over several caches requires all caches to be transactional
+
+TRANSACTIONAL_SNAPSHOT
+
+- ACID for SQL Queries
+
+== Non SQL query Scan query
+Provides iteration over cache data
+
+May have additional filter
+
+Filter is sent to server
+
+Iterator over cache uses scan query
+
+== Scan query example
+[source,java]
+----
+include::{sourcedir}/example/SqlExample.java[tags=scan,indent=0]
+----
+
+== SQL support
+Provides full ANSI SQL-99 support including
+
+- aggregations
+- distributed joins
+
+Drivers
+
+- JDBC
+- ODBC
+
+DML: SELECT, UPDATE, INSERT, and DELETE queries
+& subset of DDL
+
+== SQL in Apache Ignite
+H2 In memory SQL database part of Ignite process
+
+- parse/execute query
+- not storage
+
+Additional module 'ignite-indexing' is required in the classpath of all Ignite
nodes.
+
+== Adding indexing module
+Gradle
+[source,groovy]
+----
+compile group: 'org.apache.ignite', name: 'ignite-indexing', version: '2.7.5'
+----
+
+Maven
+[source,xml]
+----
+<dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-indexing</artifactId>
+ <version>2.7.5</version>
+</dependency>
+----
+
+== Declare cache visible as table
+[source,java]
+----
+include::{sourcedir}/example/SqlExample.java[tags=entity,indent=0]
+----
+Otherwise:
+----
+IgniteSQLException: Failed to find SQL table for type: Client
+----
+
+== Declare visible entity fields
+[source,java]
+----
+include::{sourcedir}/example/SqlExample.java[tags=field,indent=0]
+----
+
+email is declared to be visible by SQL engine
+
+phoneNumber is declared as visible and index build is required
+
+== SqlQuery
+Result is a number of Java objects (entries)
+
+Only filter condition is specified by user
+
+"Select * from Customer" is always added automatically
+
+Table name based on entry class name
+
+== SqlQuery Example
+[source,java]
+----
+include::{sourcedir}/example/SqlExample.java[tags=query,indent=0]
+----
+
+== SqlFieldsQuery
+"Projection" of entry
+
+Result is List<?> - fields
+
+Subset/specific fields
+
+Full SQL statement is required
+
+== SqlFieldsQuery Example
+[source,java]
+----
+include::{sourcedir}/example/SqlExample.java[tags=fields,indent=0]
+----
diff --git a/content/Ignite/src/main/java/example/StartClientNode.java
b/content/Ignite/src/main/java/example/PutGetExample.java
similarity index 63%
copy from content/Ignite/src/main/java/example/StartClientNode.java
copy to content/Ignite/src/main/java/example/PutGetExample.java
index 5975d41..39d7822 100644
--- a/content/Ignite/src/main/java/example/StartClientNode.java
+++ b/content/Ignite/src/main/java/example/PutGetExample.java
@@ -19,19 +19,29 @@
package example;
import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.IgniteConfiguration;
-import java.io.IOException;
-
-public class StartClientNode {
- public static void main(String[] args) throws IOException {
- // tag::contains[]
+/**
+ * Put and get example. Requires server node to be up and running.
+ */
+public class PutGetExample {
+ public static void main(String[] args) {
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setClientMode(true);
+
try (Ignite ignite = Ignition.start(cfg)) {
+ // tag::contains[]
+ IgniteCache<Integer, String> cache =
ignite.getOrCreateCache("myCacheName");
+
+ // Store keys in cache (values will end up on different cache
nodes).
+ for (int i = 0; i < 10; i++)
+ cache.put(i, Integer.toString(i));
+ for (int i = 0; i < 10; i++)
+ System.out.println("Got [key=" + i + ", val=" + cache.get(i) +
']');
+ // end::contains[]
}
- // end::contains[]
}
-}
\ No newline at end of file
+}
diff --git a/content/Ignite/src/main/java/example/SqlExample.java
b/content/Ignite/src/main/java/example/SqlExample.java
new file mode 100644
index 0000000..5e4b412
--- /dev/null
+++ b/content/Ignite/src/main/java/example/SqlExample.java
@@ -0,0 +1,121 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+package example;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringJoiner;
+import javax.cache.Cache;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.ScanQuery;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.lang.IgniteBiPredicate;
+
+public class SqlExample {
+
+ public static class Customer {
+ private long id = -1;
+
+ @QuerySqlField
+ private String name;
+
+ // tag::field[]
+ @QuerySqlField
+ private String email;
+
+ @QuerySqlField(index = true)
+ private String phoneNumber;
+ // end::field[]
+
+ public Customer(int id, String name, String email, String phoneNumber)
{
+ this.id = id;
+ this.name = name;
+ this.email = email;
+ this.phoneNumber = phoneNumber;
+ }
+
+ @Override public String toString() {
+ return new StringJoiner(", ", Customer.class.getSimpleName() +
"[", "]")
+ .add("id=" + id)
+ .add("name='" + name + "'")
+ .add("email='" + email + "'")
+ .add("phoneNumber='" + phoneNumber + "'")
+ .toString();
+ }
+ }
+
+ public static void main(String[] args) {
+ IgniteConfiguration cfg = new IgniteConfiguration();
+ try (Ignite ignite = Ignition.start(cfg)) {
+
+ // tag::entity[]
+ CacheConfiguration<Long, Customer> ccfg = new
CacheConfiguration<>("customer");
+ ccfg.setQueryEntities(Collections.singletonList(new
QueryEntity(Long.class, Customer.class)));
+ // end::entity[]
+ IgniteCache<Long, Customer> cache = ignite.getOrCreateCache(ccfg);
+ Customer client = new Customer(777200, "Jennifer Stain",
"[email protected]", "+1-541-754-3010");
+ System.out.println("Saving client " + client);
+ cache.put(client.id, client);
+
+ // tag::scan[]
+ IgniteBiPredicate<Long, Customer> filter
+ = (Long k, Customer v) -> v.email != null &&
v.email.contains("@test.com");
+
+ try (QueryCursor<Cache.Entry<Long, Customer>> cursor
+ = cache.query(new ScanQuery<Long,
Customer>().setFilter(filter))) {
+ for (Cache.Entry<Long, Customer> entry : cursor.getAll())
+ System.out.println(entry.getValue().name + " " +
entry.getValue().phoneNumber);
+ }
+ // end::scan[]
+
+ // tag::query[]
+ String phoneNum = "+1-541-754-3010";
+ try (QueryCursor<Cache.Entry<Long, Customer>> qry
+ = cache.query(new SqlQuery<Long,
Customer>(Customer.class, "where phoneNumber = ?")
+ .setArgs(phoneNum))) {
+
+ for (Cache.Entry<Long, Customer> entry : qry) {
+ Customer val = entry.getValue();
+ System.out.println("Customer found " + val);
+ }
+ }
+ // end::query[]
+
+ // tag::fields[]
+ SqlFieldsQuery qry = new SqlFieldsQuery("select concat(name, ' <',
email, '>') from Customer");
+
+ // Execute query to get collection of rows. In this particular
+ // case each row will have one element with full name formatted in
Git-style
+ Collection<List<?>> res = cache.query(qry).getAll();
+
+ // Print names.
+ System.out.println("Names of all customers:" + res);
+ // end::fields[]
+ }
+ }
+}
diff --git a/content/Ignite/src/main/java/example/StartClientNode.java
b/content/Ignite/src/main/java/example/StartClientNode.java
index 5975d41..97e2e95 100644
--- a/content/Ignite/src/main/java/example/StartClientNode.java
+++ b/content/Ignite/src/main/java/example/StartClientNode.java
@@ -24,8 +24,11 @@ import org.apache.ignite.configuration.IgniteConfiguration;
import java.io.IOException;
+/**
+ * (Think) client exmaple. Requires server node to be up and running.
+ */
public class StartClientNode {
- public static void main(String[] args) throws IOException {
+ public static void main(String[] args) {
// tag::contains[]
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setClientMode(true);
diff --git
a/content/Ignite/src/main/resources/images/replicated_vs_partitioned.png
b/content/Ignite/src/main/resources/images/replicated_vs_partitioned.png
new file mode 100644
index 0000000..a35c8ca
Binary files /dev/null and
b/content/Ignite/src/main/resources/images/replicated_vs_partitioned.png differ