Apache Ignite etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Apache Ignite etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

1 Ekim 2021 Cuma

Apache Ignite IgniteCache Arayüzü - Data Grid API İçindir

Örnek
IgniteConfiguration şöyle olsun
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder;

public class IgniteConfigurationManager {

  public static IgniteConfiguration getConfiguration() {
    IgniteConfiguration igniteConfiguration = new IgniteConfiguration();
    igniteConfiguration.setIgniteInstanceName("ItemsGrid");
    igniteConfiguration.setPeerClassLoadingEnabled(true);
    igniteConfiguration.setLocalHost("127.0.0.1");
    TcpDiscoverySpi tcpDiscoverySpi = new TcpDiscoverySpi();
    TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
    ipFinder.setAddresses(Collections.singletonList("127.0.0.1:47500..47509"));
    tcpDiscoverySpi.setIpFinder(ipFinder);
    tcpDiscoverySpi.setLocalPortRange(9);
    igniteConfiguration.setDiscoverySpi(tcpDiscoverySpi);
    TcpCommunicationSpi communicationSpi = new TcpCommunicationSpi();
    communicationSpi.setLocalAddress("localhost");
    communicationSpi.setLocalPort(48100);
    communicationSpi.setSlowClientQueueLimit(1000);
    igniteConfiguration.setCommunicationSpi(communicationSpi);
    igniteConfiguration.setCacheConfiguration(cacheConfiguration());
    return igniteConfiguration;
  }

  private static CacheConfiguration[] cacheConfiguration() {
    List<CacheConfiguration> cacheConfigurations = new ArrayList<>();
    CacheConfiguration<Long, Item> cacheConfiguration = new CacheConfiguration();
    cacheConfiguration.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
    cacheConfiguration.setCacheMode(CacheMode.REPLICATED);
    cacheConfiguration.setName(Constants.ITEM_CACHE_NAME);
    cacheConfiguration.setWriteThrough(false);
    cacheConfiguration.setReadThrough(false);
    cacheConfiguration.setWriteBehindEnabled(false);
    cacheConfiguration.setBackups(1);
    cacheConfiguration.setStatisticsEnabled(true);
    cacheConfiguration.setIndexedTypes(Long.class, Item.class);
    cacheConfigurations.add(cacheConfiguration);
  
    return cacheConfigurations.toArray(new CacheConfiguration[cacheConfigurations.size()]);
  }
}
Item sınıfı şöyle olsun
import org.apache.ignite.cache.query.annotations.QuerySqlField;

@Entity
@Table(name = "items")
public class Item {
  @QuerySqlField(index = true)
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;
  
  @QuerySqlField(index = true)
  @Column(name = "name", nullable = false)
  private String name;
  
  @Column(name = "sku", nullable = false)
  private String sku;
  
  @QuerySqlField
  @JsonInclude()
  @Transient
  private int stockCount;
  
  @QuerySqlField
  @Column(name = "price", nullable = false)
  private double price;
}
Şöyle yaparız. Ignite Cache' transaction ile yazma yapılıyor
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.transactions.Transaction;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;


@Service
@Log4j
public class IgniteService {

  @Autowired
  private Ignite ignite;

  public void addOrUpdateItemCache(Item item) {
    try (Transaction tx = ignite.transactions() .txStart(TransactionConcurrency.OPTIMISTIC, TransactionIsolation.READ_COMMITTED)) {
      IgniteCache<Long, Item> cache = ignite.cache(Constants.ITEM_CACHE_NAME);
      cache.put(item.getId(), item);
      tx.commit();
      log.debug("Item Cache size after update:" + cache.size());
    }
  }

  public void addItemList(List<Item> items) {
    try (Transaction tx = ignite.transactions() .txStart(TransactionConcurrency.OPTIMISTIC, TransactionIsolation.READ_COMMITTED)) {
      IgniteCache<Long, Item> cache = ignite.cache(Constants.ITEM_CACHE_NAME);
      items.forEach((item) -> cache.put(item.getId(), item));
      tx.commit();
      log.info("[Item Cache size after update:" + cache.size());
    }
  }
}
Sorgulama için şöyle yaparız
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.query.QueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.transactions.Transaction;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@Log4j
public class IgniteCacheServiceImpl implements IgniteCacheService {

  @Autowired
  private Ignite ignite;

  @Override
  public Item getItemFromName(String itemName) throws ResourceNotFoundException {
    IgniteCache<Long, Item> cache = ignite.cache(Constants.ITEM_CACHE_NAME);
    log.debug("Cache size:" + cache.size());
    SqlFieldsQuery sql = new SqlFieldsQuery("SELECT id,price,stockCount FROM item WHERE name = ?").setArgs(itemName);
    try (QueryCursor<List<?>> cursor = cache.query(sql)) {
        for (List<?> row : cursor) {
            Object idObject = row.get(0);
            if (idObject instanceof Number) {
                Item item = new Item();
                item.setId(Long.valueOf(idObject.toString()));
                item.setPrice(Double.valueOf(row.get(1).toString()));
                item.setStockCount(Integer.valueOf(row.get(2).toString()));
                item.setName(itemName);
                log.debug("item found= " + item);
                return item;
            }
        }
    }
    throw new ResourceNotFoundException("Item with the name " + itemName + " not found");
  }

  @Override
  public void updateStockCount(Map<Item, Integer> itemAndQuantityMap) throws OutOfStockException {
    try (Transaction tx = ignite.transactions().txStart(TransactionConcurrency.OPTIMISTIC, TransactionIsolation.READ_COMMITTED)) {
      IgniteCache<Long, Item> cache = ignite.cache(Constants.ITEM_CACHE_NAME);
      for (Map.Entry<Item, Integer> itemAndQuantity : itemAndQuantityMap.entrySet()) {
          Item cachedItem = cache.get(itemAndQuantity.getKey().getId());
          if (cachedItem != null) {
              if (cachedItem.getStockCount() < itemAndQuantity.getValue()) {
                  throw new OutOfStockException("Item out of stock: " + cachedItem.getName());
              }
              cachedItem.setStockCount(cachedItem.getStockCount() - itemAndQuantity.getValue());
              cache.put(itemAndQuantity.getKey().getId(), cachedItem);
          }
      }
      tx.commit();
      log.debug("Item Cache size after update:" + cache.size());
    
  }
}

10 Mart 2021 Çarşamba

Apache Ignite - Distributed SQL ve Cache

Giriş
Açıklaması şöyle. Apache Ignite Java ile geliştirilmiş
Apache® Ignite™ was originally contributed to the Apache Software Foundation by GridGain Systems. The project rapidly evolved into a top level Apache project with tens of thousands of downloads per month. The GridGain Professional Edition, Enterprise Edition, and Ultimate Edition are built on Apache Ignite.
GridGain vs Apache Ignite
Açıklaması şöyle
Indeed, Gridgain is wraper built on top of Ignite. Gridgain gives you additional features such as Security, Rolling production update etc that is required for enterprise level application.
GridGain şirketi "Data Center Replication" da sunuyor

Neleri Destekler
Apache Ignite bir sürü şeyi birden destekliyor.
SQL
Key/Value
Transactions
Compute
Services
Streaming
Machine Learning
 Açıklaması şöyle
Apache Ignite is a high-performance distributed database that stores data in memory (as well as persistent).
As with every NoSQL solution, it supports replication and sharding out-of-the-box but also provides ACID transactions, SQL support, and Compute Grid.
Distributed SQL
Şeklen şöyle

Persistence
Ignite native persistence
Third party persistence

Durable Memory
Şeklen şöyle. Bir anlamnda Linux'taki swap dosya sistemine benziyor.


Maven
Şu satırı dahil ederiz
<properties>
  <ignite.version>2.10.0</ignite.version>
  <ignite.spring.data.version>1.0.0</ignite.spring.data.version>
</properties>

<dependency>
  <groupId>org.apache.ignite</groupId>
  <artifactId>ignite-core</artifactId>
  <version>${ignite.version}</version>
</dependency>

<dependency>
  <groupId>org.apache.ignite</groupId>
  <artifactId>ignite-spring</artifactId>
  <version>${ignite.version}</version>
</dependency>

<dependency>
  <groupId>org.apache.ignite</groupId>
  <artifactId>ignite-spring-data-2.2-ext</artifactId>
  <version>${ignite.spring.data.version}</version>
</dependency>
Örnekler
Gridgain örnekler burada
Bazı diğer örnekler burada

Bağlantı
Bağlantı için 3 yöntem var
1. Thick Client : Cluster topolojisine dahil olur
2. Thin Client : Cluster topolojisine dahil olmaz
3. JDBC : Relational Database olarak kullanmak istersek

Java
Şöyle yaparız. Herhangi bir düğüme bağlanmak yeterli
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
Connection con = DriverManager.getConnection("jdbc:ignite:thin://192.168.0.50");
In-memory data grid
Apache Ignite in-memory data grid özelliğine sahip olduğu için Hazelcast gibi Distributed Cache olarak kullanılabilir.

Embedded node
Apache Ignite embedded olarak yani aynı JVM içinde kullanılabiliyor. Eğer Spring ile birlikte kullanmak istersek açıklaması şöyle
The embedded node can be started by SpringCacheManager itself. In this case, we will need to provide a path to either the Ignite configuration XML file or IgniteConfiguration bean via configurationPath or configuration properties respectively.
Ignite Rest API
Açıklaması şöyle
Ignite provides an out-of-the-box HTTP REST client that gives us the ability to communicate with the grid over HTTP and HTTPS protocols using the REST approach. REST APIs can be used to perform different operations like reading/writing from/to cache, execute tasks, get various metrics and more.

To enable HTTP connectivity, we have addedignite-rest-http as a Maven dependency in our application. Explicit configuration is not required; the connector starts up automatically and listens on port 8080. We can also change the port by specifying -DIGNITE_JETTY_PORT=8081 as VM arguments.

We can check whether the rest API is working by using the below curl command.
curl 'http://localhost:8081/ignite?cmd=version'

Following is a sample GET REST API which we can be used to procure the data from the Cache using the CacheName and key.
http://localhost:8081/ignite?cmd=get&cacheName=student&key=1
Anotasyonlar
@QuerySqlField
 Alanın Ignıte tarafından görülebilmesini sağlar

@AffinityKeyMapped
Foreign key olarak bağlı iki tablonun collocated olmasını sağlar. Satır sayısı az olduğu için Collocated yapılamayan tablolar, replicate edilmeli

SQL Dili
ANSI 99 uyumlu
INSERT 
UPDATE
DELETE
CREATE TABLE
DROP TABLE
CREATE INDEX
DROP INDEX
ALTER TABLE
SELECT : JOIN ve SUBQUERY 

yapılabilir

ALTER TABLE
Şöyle yaparız
ALTER TABLE city ADD COLUMN IF NOT EXISTS population int;
ALTER TABLE person DROP COLUMN (code,gdp);
CREATE INDEX
B+ Tree Index kullanır. Inline veri büyülüğü belirtilebilir.

CREATE TABLE
CREATE TABLE yazısına taşıdım

SELECT
Örnek
Şöyle yaparız. country ve city diye iki tablo var. Burada "Collocated Join"  önemli. Collocated yan yana demek. Non-collocated join'ler ciddi performans kaybına sebep olabilir.
SELECT country.name, city.name MAX(city,population) as max_pop
FROm country JOIN city on city.countrycode = country.code WHERE country.code IN ('USA','RUS','CHN') GROUP BY country.name, city.name ORDER BY max_op DESC LIMIT 3;