0
votes

See much further down for my updated scenario...

I am experimenting with setting up Apache Ignite in our Docker-compose environment and have a few questions about Ignite and how to configure it.

  1. What is the purpose of downloading and running the Apache Ignite binaries if I have the Maven dependencies in the project? Do I need to run Ignite as well in each module or is just having the dependencies enough?

  2. Does each instance of an Ignite node need to have an associated configuration and how do those differ from each other?

  3. I have a Docker-Compose file with two services, one that pulls in the Ignite container and a Java shell that lets me run/test my module. In my shell, when I am running the compose services, it appears that my test discovers the ignite service. When I run my test out of IntelliJ it does not discover the other Ignite server.

My compose services:

  #Ignite
  ignite:
    image: apacheignite/ignite
    environment:
      - IGNITE_QUITE=false
    #volumes:
    #  - ./project/src/test/resources/ignite.xml:/opt/ignite/apache-ignite-fabric/config/default-config.xml
    ports:
      - 11211:11211
      - 47100:47100
      - 47500:47500
      - 49112:49112

  # Java Shell
  java:
    image: local/java
    build:
      context: .
    command: /bin/bash
    volumes:
      - .:/project
    depends_on:
      - ignite
    ports:
      - 8000:8000
      - 8080:8080
      - 1099:1099

My Ignite configuration I am using in the test:

 <bean id="ignite.cfg"
          class="org.apache.ignite.configuration.IgniteConfiguration">

        <property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                        <property name="addresses">
                            <list>
                                <!--
                                Explicitly specifying address of a local node to let it start and
                                operate normally even if there is no more nodes in the cluster.
                                You can also optionally specify an individual port or port range.
                                -->
                                <value>127.0.0.1</value>

                                <!--
                                IP Address and optional port range of a remote node.
                                You can also optionally specify an individual port.
                                -->
                                <value>127.0.0.1:47500..47509</value>
                            </list>
                        </property>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

My test:

@Test
    //@Ignore
    public void should_run_cluster()
    {
        try (Ignite ignite = Ignition.start("ignite2.xml"))
        {
            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) + ']');
            }
        }
    }

Depending on what I do, when running it out of IntelliJ, i seem to be able to talk to the Ignite node but it rejects the node joining the cluster.

I've tried exposing the ports (different port#'s, not exposed only internal, etc.) from the Java service but no luck.

If I try and attach my configuration to the Ignite service it completely does not work.

My end goal is to setup an environment using Docker-Compose that I can join locally for testing purposes but, eventually, move this to ECS/Fargate.

I am sure I am getting my configurations mixed up and any help would be appreciated...

----- UPDATE-----

So, i've been able to connect to Ignite from IntelliJ using localhost/127.0.0.1 and within the container network using the compose service name 'ignite.'

Is this the right way to do this? I cant see how I can use the same configuration, without using doing some token replacement (${port}), for each node because it seems I need to have a unique port value for the DiscoverySpi and the CommunicationSpi.

Also, when connecting from my client, in this case a JUnit, it takes forever to establish that initial connection.

So, my question now is if this is the right way to configure Ignite?

"Ignite" Service (in Compose):

  ignite:
    image: apacheignite/ignite
    environment:
      - IGNITE_QUIET=false
    volumes:
      - ./project/src/test/resources/ignite-main.xml:/opt/ignite/apache-ignite-fabric/config/default-config.xml
    ports:
      - 11211:11211
      - 47100:47100
      - 47500:47500
      - 49112:49112

"Ignite" Service Configuration (ignite-main.xml):

<property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="localPort" value="47500"/>
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                        <property name="addresses">
                            <list>
                                <value>localhost</value>
                                <value>localhost:47500</value>
                            </list>
                        </property>
                    </bean>
                </property>
            </bean>
        </property>
        <property name="communicationSpi">
            <bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
                <property name="localPort" value="47100"/>
            </bean>
        </property>

Client Ignite Configuration (ignite.xml):

<property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="localPort" value="47501"/>
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                        <property name="addresses">
                            <list>
                                <value>localhost</value>
                                <value>localhost:47500</value>
                            </list>
                        </property>
                    </bean>
                </property>
            </bean>
        </property>
        <property name="communicationSpi">
            <bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
                <property name="localPort" value="47101"/>
            </bean>
        </property>

Client Ignite Test Case:

private static Ignite ignite;

@BeforeClass
public static void beforeAll()
{
    ignite = Ignition.start("ignite.xml");
}

@AfterClass
public static void afterAll()
{
    ignite.close();
}

@Test
public void should_prep_cluster()
{
    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) + ']');
    }
}
2

2 Answers

2
votes

As a supplement to @alamar's answer:

Since Docker Compose services launch in separate containers, you can not use localhost or 127.0.0.1 to discover server node. You can link ignite service to be able to use DNS name ignite.

Compose services:

# Ignite
ignite:
  image: apacheignite/ignite
  environment:
    - IGNITE_QUIET=false
  # volumes:
  #   - ./project/src/test/resources/ignite.xml:/opt/ignite/apache-ignite-fabric/config/default-config.xml
  # It is not necessary to expose ports outside if they are only used inside docker-compose
  # ports:
  #   - 11211:11211
  #   - 47100:47100
  #   - 47500:47500
  #   - 49112:49112
# Java Shell
java:
  image: local/java
  build:
    context: .
  command: /bin/bash
  volumes:
    - .:/project
  links:
    - ignite
  ports:
    - 8000:8000
    - 8080:8080
    - 1099:1099

Client Ignite Configuration (ignite.xml):

<property name="discoverySpi">
    <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
        <property name="ipFinder">
            <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
                <property name="addresses">
                    <list>
                        <value>ignite:47500</value>
                    </list>
                </property>
            </bean>
        </property>
    </bean>
</property>
0
votes
  1. So that you can run stand-alone Ignite node with any set of modules, and e.g. run SQL against it with sqlline, or (while using peer class loading) do almost anything with connected Ignite clients to it. But then again, you can run Ignite nodes (client or server) directly from Maven projects, in this case you don't need binary distribution at all.

  2. Yes. Aside from node properties or consistentId which is not required, they may be identical.

  3. It's hard to say. Can you provide logs? I think that people who understand containers can check it without logs, but I can't.