Search code examples
mysqlignite

Ignite not connecting to MySQL properly


I am trying to setup Ignite as a cache with MySQL as the external storage. I am deploying this as a Deployment(stateless) in my kubernetes cluster.

Following is my xml config:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="         http://www.springframework.org/schema/beans              http://www.springframework.org/schema/beans/spring-beans.xsd              http://www.springframework.org/schema/util              http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- Data source bean -->
    <bean class="com.mysql.cj.jdbc.MysqlDataSource" id="mysqlDataSource">
        <property name="URL" value="jdbc:mysql://mysql.default.svc.cluster.local:3306/my_database"/>
        <property name="user" value="root"/>
        <property name="password" value="xxxxxx"/>
    </bean>

    <!-- Ignite Configuration -->
    <bean class="org.apache.ignite.configuration.IgniteConfiguration">
        <!-- Enable peer class loading. -->
        <property name="peerClassLoadingEnabled" value="true"/>

        <property name="cacheConfiguration">
            <list>
                <!-- Configuration for KVCache -->
                <bean class="org.apache.ignite.configuration.CacheConfiguration">
                    <property name="name" value="KVCache"/>
                    <property name="cacheMode" value="REPLICATED"/>
                    <property name="atomicityMode" value="TRANSACTIONAL"/>
                    <property name="writeSynchronizationMode" value="FULL_SYNC"/>
                    <property name="backups" value="1"/>
                    <property name="writeBehindEnabled" value="true"/>
                    <property name="writeBehindBatchSize" value="1"/>
                    <property name="cacheStoreFactory">
                        <bean class="org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory">
                            <property name="dataSourceBean" value="mysqlDataSource"/>
                            <property name="dialect">
                                <bean class="org.apache.ignite.cache.store.jdbc.dialect.MySQLDialect"/>
                            </property>
                            <property name="types">
                                <list>
                                    <bean class="org.apache.ignite.cache.store.jdbc.JdbcType">
                                        <property name="cacheName" value="KVCache"/>
                                        <property name="keyType" value="java.lang.Integer"/>
                                        <property name="valueType" value="java.lang.Object"/>
                                        <!--Specify the schema if applicable -->
                                        <!--property name="databaseSchema" value="MY_DB_SCHEMA"/-->
                                        <property name="databaseSchema" value="my_database"/>
                                        <property name="databaseTable" value="kv"/>
                                        <property name="keyFields">
                                            <list>
                                                <bean class="org.apache.ignite.cache.store.jdbc.JdbcTypeField">
                                                    <constructor-arg>
                                                        <util:constant static-field="java.sql.Types.INTEGER"/>
                                                    </constructor-arg>
                                                    <constructor-arg value="id"/>
                                                    <constructor-arg value="int"/>
                                                    <constructor-arg value="id"/>
                                                </bean>
                                            </list>
                                        </property>
                                        <property name="valueFields">
                                            <list>
                                                <bean class="org.apache.ignite.cache.store.jdbc.JdbcTypeField">
                                                    <constructor-arg>
                                                        <util:constant static-field="java.sql.Types.VARCHAR"/>
                                                    </constructor-arg>
                                                    <constructor-arg value="id"/>
                                                    <constructor-arg value="java.lang.String"/>
                                                    <constructor-arg value="id"/>
                                                </bean>
                                                <bean class="org.apache.ignite.cache.store.jdbc.JdbcTypeField">
                                                    <constructor-arg>
                                                        <util:constant static-field="java.sql.Types.VARCHAR"/>
                                                    </constructor-arg>
                                                    <constructor-arg value="name"/>
                                                    <constructor-arg value="java.lang.String"/>
                                                    <constructor-arg value="name"/>
                                                </bean>
                                            </list>
                                        </property>
                                    </bean>
                                </list>
                            </property>
                        </bean>
                    </property>
                    <!-- Configure query entities if you want to use SQL queries -->
                    <property name="queryEntities">
                        <list>
                            <bean class="org.apache.ignite.cache.QueryEntity">
                                <property name="keyType" value="java.lang.Integer"/>
                                <property name="valueType" value="java.lang.Object"/>
                                <property name="keyFieldName" value="id"/>
                                <property name="keyFields">
                                    <list>
                                        <value>id</value>
                                    </list>
                                </property>
                                <property name="fields">
                                    <map>
                                        <entry key="name" value="java.lang.String"/>
                                        <entry key="id" value="java.lang.String"/>
                                    </map>
                                </property>
                            </bean>
                        </list>
                    </property>
                </bean>
                <!-- Provide similar configurations for other caches/tables -->
            </list>
        </property>
    </bean>
</beans>

Following is my deployment.yaml for the kubernetes deployment:

# An example of a Kubernetes configuration for pod deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
  # Cluster name.
  name: ignite-cluster
  namespace: default
spec:
  # The initial number of Ignite pods.
  replicas: 2
  # serviceName: ignite-service
  selector:
    matchLabels:
      app: ignite
  template:
    metadata:
      labels:
        app: ignite
    spec:
      serviceAccountName: ignite
      # terminationGracePeriodSeconds: 60000 (use in production for graceful restarts and shutdowns)
      containers:
        # Custom pod name.
        - name: ignite-node
          image: apacheignite/ignite:2.12.0
          env:
            - name: OPTION_LIBS
              value: ignite-kubernetes,ignite-rest-http,control-center-agent
            - name: CONFIG_URI
              value: file:///ignite/config/persist.xml
            - name: USER_LIBS
              value: "/ignite/mysql-connector-java-8.0.28.jar"
              # consider this property for production -DIGNITE_WAIT_FOR_BACKUPS_ON_SHUTDOWN=true
          ports:
            # Ports you might need to open.
            - containerPort: 47100 # communication SPI port
            - containerPort: 47500 # discovery SPI port
            - containerPort: 49112 # JMX port
            - containerPort: 10800 # thin clients/JDBC driver port
            - containerPort: 8080 # REST API
          volumeMounts:
            - mountPath: /ignite/config
              name: config-vol
            - mountPath: /ignite/mysql-connector-java-8.0.28.jar
              name: mysql
            - mountPath: /ignite/bin
              name: bin
            - mountPath: /ignite/libs
              name: libs
      volumes:
        - name: config-vol
          configMap:
            name: ignite-cfg-persistent
        - name: mysql
          hostPath:
            path: /Users/username/Downloads/control-center-agent-2.12.0.0/libs/mysql-connector-java-8.0.28.jar
            type: File
        - name: libs
          hostPath:
            path: /Users/username/Downloads/control-center-agent-2.12.0.0/libs/control-center-agent
        - name: bin
          hostPath:
            path: /Users/username/Downloads/control-center-agent-2.12.0.0/bin

The cluster comes up normally with ACTIVE state. But the cache doesn't have existing values from the table itself.


Solution

  • As described in docs, in order to load data from external storage to apache ignite you should call cache.loadCache(null);

    // Load data from kv table into KVCache.
    IgniteCache<Integer, Object> kvCache = ignite.cache("KVCache");
    
    kvCache.loadCache(null);