Статьи

Быстрый старт с помощью Data Grid в памяти, Apache Ignite

Сетка данных IMDG или In memory не является реляционной базой данных в памяти, базой данных NOSQL или реляционной базой данных. Это другой тип программного хранилища данных. Модель данных распределена по многим серверам в одном месте или в нескольких местах. Это распределение известно как фабрика данных. Эта распределенная модель известна как архитектура «с общим доступом». IMDG имеет следующие характеристики:

  1. Все серверы могут быть активны на каждом сайте.
  2. Все данные хранятся в оперативной памяти серверов.
  3. Серверы могут быть добавлены или удалены без перебоев, чтобы увеличить объем доступной оперативной памяти.
  4. Модель данных не является реляционной и основана на объектах.
  5. Распределенные приложения написаны на платформе независимого языка.
  6. Фабрика данных является эластичной, что позволяет осуществлять непрерывное автоматическое обнаружение и восстановление одного или нескольких серверов.

Больше всего времени мы используем IMDG для управления веб-сессиями сервера приложений и в качестве распределенного кэша или кэша L2. Добавление сообщества Hazelcast было нашими любимыми инструментами IMDG, но из последних нескольких реализаций сообщества Hazelcast его производительность нас совсем не радует. В качестве быстрой альтернативы HazelCast, мы решили попробовать
Апач загорелся . Этот пост посвящен apache ignite и будет использоваться для быстрого запуска. Для установки я буду использовать 2 виртуальные машины операционной системы Redhat со следующими конфигурациями:

  • Процессор: 2
  • RAM: 4
  • HDD: 25 ГБ
  • ОС: Редхат Сантьяго

Из множества возможностей Apache ignite6 мы рассмотрим только следующие функции:

  1. Подготовьте операционную систему
  2. Использование Spring для использования DataGrid
  3. Конфигурация MyBatis Cache
  4. Весеннее Кеширование

Установка apache ignite

Предварительно обязательные галстуки:

  1. Java 1.7 и выше
  2. открытые порты: 47500..47509, 8080 (для интерфейса покоя), 47400, 47100: 47101, 48100: 48101, 31100: 31101После установки JDK в операционной системе нам нужно открыть порты, упомянутые выше. Следуя командам, мы можем манипулировать iptables.
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    vi /etc/sysconfig/iptables
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 47500:47509 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 47400 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 47100 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 47101 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 48100 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 48101 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 31100 -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 31101 -j ACCEPT
     
    /etc/init.d/iptables restart

Установка Apache зажигать на нескольких машинах

  1. Загрузите финальную версию ignite 1.5.0 по следующим ссылкам .
  2. Разархивируйте архив в любом месте ОС, например / opt / apache-ignite
  3. Добавьте путь к среде IGNITE_HOME в домашнюю директорию apache ignite.
  4. скопируйте папку $ IGNITE_HOME / libs / option / ignite-rest-http в /home/user/apache-ignite-fabric-1.5.0/libs, это позволит включить зажигание apache через интерфейс rest.
  5. Запустите команду ignite.sh examples / config / example-cache.xml, чтобы запустить apache ignite.

    Если все идет хорошо, вы должны увидеть следующий журнал в вашей консоли:

    1
    2
    [12:32:01] Ignite node started OK (id=ceb614ca)
    [12:32:01] Topology snapshot [ver=4, servers=2, clients=0, CPUs=3, heap=2.0GB]

    и ignite также будет доступен через http по адресу http: // host: port / ignite? cmd = version

Использование Spring для использования DataGrid

Прежде всего, нам нужно создать проект maven, чтобы записать кучу кода для проверки возможностей Apache Ignite.

    • Добавьте следующие зависимости в pom.xml
      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      <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-indexing</artifactId>
                  <version>${ignite.version}</version>
              </dependency>
              <!-- myBatis -->
              <dependency>
                  <groupId>org.mybatis.caches</groupId>
                  <artifactId>mybatis-ignite</artifactId>
                  <version>1.0.0-beta1</version>
              </dependency>
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis-spring</artifactId>
                  <version>1.2.4</version>
              </dependency>
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.3.1</version>
              </dependency>
              <!-- Oracle 12-->
              <dependency>
                  <groupId>com.oracle</groupId>
                  <artifactId>ojdbc6</artifactId>
                  <version>11.2.0.3</version>
              </dependency>

      Обратите внимание, что jar-клиент Oracle JDBC должен находиться в локальных репозиториях maven. В моем случае я использую клиент Oracle 11.2.02.

    • Добавьте файл spring-context.xml в каталог ресурсов со следующими контекстами:
      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="
          <!-- Enable annotation-driven caching. -->
          <cache:annotation-driven/>
       
          <context:property-placeholder location="classpath:jdbc.properties"/>
          <!-- beans -->
       
          <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
              <property name="gridName" value="TestGrid"/>
              <!-- Enable client mode. -->
              <property name="clientMode" value="true"/>
       
              <property name="cacheConfiguration">
                  <list>
                      <!-- Partitioned cache example configuration (Atomic mode). -->
                      <bean class="org.apache.ignite.configuration.CacheConfiguration">
                          <!--<property name="atomicityMode" value="ATOMIC"/>-->
                          <!-- Set cache mode. -->
                          <property name="cacheMode" value="PARTITIONED"/>
                          <property name="backups" value="1"/>
                          <property name="statisticsEnabled" value="true" />
                      </bean>
                  </list>
              </property>
              <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
              <property name="discoverySpi">
                  <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                      <property name="ipFinder">
                          <!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
                          <!--<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">-->
                          <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                              <property name="addresses">
                                  <list>
                                      <!-- In distributed environment, replace with actual host IP address. -->
                                      <value>Add your node ip address</value>
                                      <value>add your node ip address</value>
                                  </list>
                              </property>
                          </bean>
                      </property>
                  </bean>
              </property>
          </bean>
          <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource" />
              <property name="mapperLocations" value="classpath*:com/blu/ignite/dao/*Mapper.xml"/>
          </bean>
          <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
              <property name="URL" value="${jdbc.url}" />
              <property name="user" value="${jdbc.username}"/>
              <property name="password" value="${jdbc.password}"/>
              <property name="connectionCachingEnabled" value="true"/>
          </bean>
      </beans>

      Давайте рассмотрим несколько свойств конфигурации:

      • property name = ”clientMode” value = ”true” — это свойство заставит текущее приложение работать в качестве клиента.
      • свойство name = ”cacheMode” value = ”PARTITIONED” — режим кэширования будет разбит на части, режим кэширования также может быть реплицирован.
      • свойство name = ”backups” value = ”1 ″ — всегда будет один избыточный элемент кэша в другом узле.
      • свойство name = ”statisticsEnabled” value = ”true” — это свойство активирует статистику кеша.
    • Теперь давайте напишем немного:
      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      public class SpringIgniteRun {
          public static void main(String[] args) throws Exception{
              System.out.println("Run Spring example!!");
              ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-core.xml");
       
              IgniteConfiguration igniteConfiguration = (IgniteConfiguration) ctx.getBean("ignite.cfg");
              Ignite ignite = Ignition.start(igniteConfiguration);
              // get or create cache
              IgniteCache cache = ignite.getOrCreateCache("myCacheName");
              for(int i = 1; i < 1000; i++){
                  cache.put(i, Integer.toString(i));
              }
              for(int i =1; i<1000;i++){
                  System.out.println("Cache get:"+ cache.get(i));
              }
              Thread.sleep(20000); // sleep for 20 seconds
              // statistics
              System.out.println("Cache Hits:"+ cache.metrics(ignite.cluster()).getCacheHits());
              ignite.close();
          }
      }

      Приведенный выше код самоочевиден, мы просто создаем кэш с именем «myCacheName» и добавляем 1000-строковое значение Integer. После вставки значения в кеш мы также читаем элементы из кеша и проверяем статистику. через ignitevisorcmd вы также можете отслеживать сетку данных, затем вы можете найти снимок экрана со статистикой сетки

      Снимок экрана 2016-02-18 в 16.24.20

    Конфигурация MyBatis Cache

    Теперь давайте добавим кэш MyBatis ORM l2 и рассмотрим, как он работает.

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <bean id="servicesBean" class="com.blu.ignite.WebServices">
            <property name="dao" ref="userServicesBean"/>
        </bean>
        <bean id="userServicesBean" class="com.blu.ignite.dao.UserServices">
            <property name="userMapper" ref="userMapper"/>
        </bean>
     
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="mapperLocations" value="classpath*:com/blu/ignite/dao/*Mapper.xml"/>
        </bean>
        <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
            <property name="URL" value="${jdbc.url}" />
            <property name="user" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
            <property name="connectionCachingEnabled" value="true"/>
        </bean>
     
     
        <bean id="userMapper" autowire="byName" class="org.mybatis.spring.mapper.MapperFactoryBean">
            <property name="mapperInterface" value="com.blu.ignite.mapper.UserMapper" />
            <property name="sqlSessionFactory" ref="sqlSessionFactory" />
        </bean>
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.blu.ignite.mapper" />
        </bean>

    Мы добавляем SQLsessionFactory, MyBatis Mapper и Service Bean. Теперь давайте добавим * .Mapper.xml

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?xml version="1.0" encoding="UTF-8" ?>
     
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     
    <mapper namespace="com.blu.ignite.mapper.UserMapper">
     
        <cache type="org.mybatis.caches.ignite.IgniteCacheAdapter" />
     
        <select id="getUser" parameterType="String" resultType="com.blu.ignite.dto.User" useCache="true">
          SELECT * FROM users WHERE id = #{id}
        </select>
     
        <select id="getUniqueJob" parameterType="String" resultType="String" useCache="false">
            select unique job from emp order by job desc
        </select>
     
    </mapper>

    Полные сценарии sql (DDL / DML) таблиц emp и dept находятся в каталоге com / blu / ignite / scripts. Я создал простой веб-сервис для получения пользователей и уникальных заданий для сотрудников. Вот код для веб-службы следующим образом:

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @WebService(name = "BusinessRulesServices",
            serviceName="BusinessRulesServices",
            targetNamespace = "http://com.blu.rules/services")
    public class WebServices {
        private UserServices userServices;
     
        @WebMethod(operationName = "getUserName")
        public String getUserName(String userId){
            User user = userServices.getUser(userId);
            return user.getuName();
        }
        @WebMethod(operationName = "getUniqueJobs")
        public List getUniqueJobs(){
            return userServices.getUniqueJobs();
        }
        @WebMethod(exclude = true)
        public void setDao(UserServices userServices){
            this.userServices = userServices;
        }
     
    }

    Вызов веб-метода getUserName будет запрашивать базу данных и кэшировать результат запроса в кеше воспламенения.

    Весеннее Кеширование

    С помощью пружинного кэширования вы можете добиться кэширования возвращаемого значения любого метода бобов. Apache ignite создаст кеш по имени кеша, который вы предоставите аннотацией @Cacheable («returnHello»). Например, если у меня есть такой метод, как показано ниже:

    1
    2
    3
    4
    5
    6
    @Cacheable("returnHello")
        public String sayhello(String str){
            System.out.println("Client says:"+ str);
     
            return "hello"+str;
        }

    В первый раз, когда метод будет вызван, реплицированный кэш с именем аргумента будет создан в ignite, в следующий раз каждый вызов вышеуказанного метода будет возвращать значение из кэша.

    Снимок экрана 2016-02-18 в 18.48.17

    • Пока этого достаточно. Вскоре я вернусь с некоторыми новыми функциями apache ignite. Полный исходный код проекта будет найден в github .
    Ссылка: Быстрый старт с помощью Data Grid In memory, Apache Ignite от нашего партнера по JCG Шамима Буйяна в блоге My workspace .