October 20th, Q&A session: Get you issues solved and questions answered!

GitHub logo
Edit

Ignite Cassandra Integration Configuration

Overview

To setup Cassandra as a persistent store, you need to set CacheStoreFactory for your Ignite caches to org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory.

This could be done using Spring context configuration like this:

<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
    <property name="cacheConfiguration">
        <list>
            ...
            <!-- Configuring persistence for "cache1" cache -->
            <bean class="org.apache.ignite.configuration.CacheConfiguration">
                <property name="name" value="cache1"/>
                <!-- Tune on Read-Through and Write-Through mode -->
                <property name="readThrough" value="true"/>
                <property name="writeThrough" value="true"/>
                <!-- Specifying CacheStoreFactory -->
                <property name="cacheStoreFactory">
                    <bean class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
                        <!-- Datasource configuration bean which is responsible for Cassandra connection details -->
                        <property name="dataSourceBean" value="cassandraDataSource"/>
                        <!-- Persistent settings bean which is responsible for the details of how objects will be persisted to Cassandra -->
                        <property name="persistenceSettingsBean" value="cache1_persistence_settings"/>
                    </bean>
                </property>
            </bean>
            ...
        </list>
        ...
    </property>
</bean>

There are two main properties which should be specified for CassandraCacheStoreFactory:

  • dataSourceBean - instance of the org.apache.ignite.cache.store.cassandra.datasource.DataSource class responsible for all the aspects of Cassandra database connection (credentials, contact points, read/write consistency level, load balancing policy and etc…​)

  • persistenceSettingsBean - instance of the org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings class responsible for all the aspects of how objects should be persisted into Cassandra (keyspace and its options, table and its options, partition and cluster key options, POJO object fields mapping, secondary indexes, serializer for BLOB objects and etc…​)

In the below section these two beans and their configuration settings will be described in details.

DataSourceBean

This bean stores all the details required for Cassandra database connection and CRUD operations. In the table below you can find all the bean properties:

Property Description Default

user

User name used to connect to Cassandra

password

User password used to connect to Cassandra

credentials

Credentials bean providing username and password

authProvider

Use the specified AuthProvider when connecting to Cassandra. Use this method when a custom authentication scheme is in place.

port

Port to use to connect to Cassandra (if it’s not provided in connection point specification)

contactPoints

Array of contact points (hostaname:[port]) to use for Cassandra connection

maxSchemaAgreementWaitSeconds

Maximum time to wait for schema agreement before returning from a DDL query

10 seconds

protocolVersion

Specifies what version of Cassandra driver protocol should be used (could be helpful for backward compatibility with old versions of Cassandra)

3

compression

Compression to use for the transport. Supported compressions: snappy, lz4

useSSL

Enables the use of SSL

false

sslOptions

Enables the use of SSL using the provided options

false

collectMetrix

Enables metrics collection

false

jmxReporting

Enables JMX reporting of the metrics

false

fetchSize

Specifies query fetch size. Fetch size controls how much resulting rows will be retrieved simultaneously.

readConsistency

Specifies consistency level for READ queries

writeConsistency

Specifies consistency level for WRITE/DELETE/UPDATE queries

loadBalancingPolicy

Specifies load balancing policy to use

TokenAwarePolicy

reconnectionPolicy

Specifies reconnection policy to use

ExponentialReconnectionPolicy

retryPolicy

Specifies retry policy to use

DefaultRetryPolicy

addressTranslater

Specifies address translater to use

IdentityTranslater

speculativeExecutionPolicy

Specifies speculative execution policy to use

NoSpeculativeExecutionPolicy

poolingOptions

Specifies connection pooling options

socketOptions

Specifies low-level socket options for the connections kept to the Cassandra hosts

nettyOptions

Hooks that allow clients to customize Cassandra driver’s underlying Netty layer

PersistenceSettingsBean

This bean stores all the details(keyspace, table, partition options, POJO fields mapping and etc…​) of how objects (keys and values) should be persisted into Cassandra database.

The constructor of org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings allows to create such a bean from a string which contains XML configuration document of specific structure (see below) or from the resource pointing to XML document.

Here is the generic example of an XML configuration document (persistence descriptor) which specifies how Ignite cache keys and values should be serialized/deserialized to/from Cassandra:

<!--
Root container for persistence settings configuration.

Note: required element

Attributes:
  1) keyspace [required] - specifies keyspace for Cassandra tables which should be used to store key/value pairs
  2) table    [required] - specifies Cassandra table which should be used to store key/value pairs
  3) ttl      [optional] - specifies expiration period for the table rows (in seconds)
-->
<persistence keyspace="my_keyspace" table="my_table" ttl="86400">
    <!--
    Specifies Cassandra keyspace options which should be used to create provided keyspace if it doesn't exist.

    Note: optional element
    -->
    <keyspaceOptions>
        REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3}
        AND DURABLE_WRITES = true
    </keyspaceOptions>

    <!--
    Specifies Cassandra table options which should be used to create provided table if it doesn't exist.

    Note: optional element
    -->
    <tableOptions>
        comment = 'A most excellent and useful table'
        AND read_repair_chance = 0.2
    </tableOptions>

    <!--
    Specifies persistent settings for Ignite cache keys.

    Note: required element

    Attributes:
      1) class      [required] - java class name for Ignite cache key
      2) strategy   [required] - one of three possible persistent strategies:
            a) PRIMITIVE - stores key value as is, by mapping it to Cassandra table column with corresponding type.
                Should be used only for simple java types (int, long, String, double, Date) which could be mapped
                to corresponding Cassadra types.
            b) BLOB - stores key value as BLOB, by mapping it to Cassandra table column with blob type.
                Could be used for any java object. Conversion of java object to BLOB is handled by "serializer"
                which could be specified in serializer attribute (see below).
            c) POJO - stores each field of an object as a column having corresponding type in Cassandra table.
                Provides ability to utilize Cassandra secondary indexes for object fields.
      3) serializer [optional] - specifies serializer class for BLOB strategy. Shouldn't be used for PRIMITIVE and
        POJO strategies. Available implementations:
            a) org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer - uses standard Java
                serialization framework
            b) org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer - uses Kryo
                serialization framework
      4) column     [optional] - specifies column name for PRIMITIVE and BLOB strategies where to store key value.
        If not specified column having 'key' name will be used. Shouldn't be used for POJO strategy.
    -->
    <keyPersistence class="org.mycompany.MyKeyClass" strategy="..." serializer="..." column="...">
        <!--
        Specifies partition key fields if POJO strategy used.

        Note: optional element, only required for POJO strategy in case you want to manually specify
            POJO fields to Cassandra columns mapping, instead of relying on dynamic discovering of
            POJO fields and mapping them to the same columns of Cassandra table.
        -->
        <partitionKey>
            <!--
             Specifies mapping from POJO field to Cassandra table column.

             Note: required element

             Attributes:
               1) name   [required] - POJO field name
               2) column [optional] - Cassandra table column name. If not specified lowercase
                  POJO field name will be used.
            -->
            <field name="companyCode" column="company" />
            ...
            ...
        </partitionKey>

        <!--
        Specifies cluster key fields if POJO strategy used.

        Note: optional element, only required for POJO strategy in case you want to manually specify
            POJO fields to Cassandra columns mapping, instead of relying on dynamic discovering of
            POJO fields and mapping them to the same columns of Cassandra table.
        -->
        <clusterKey>
            <!--
             Specifies mapping from POJO field to Cassandra table column.

             Note: required element

             Attributes:
               1) name   [required] - POJO field name
               2) column [optional] - Cassandra table column name. If not specified lowercase
                  POJO field name will be used.
               3) sort   [optional] - specifies sort order (asc or desc)
            -->
            <field name="personNumber" column="number" sort="desc"/>
            ...
            ...
        </clusterKey>
    </keyPersistence>

    <!--
    Specifies persistent settings for Ignite cache values.

    Note: required element

    Attributes:
      1) class      [required] - java class name for Ignite cache value
      2) strategy   [required] - one of three possible persistent strategies:
            a) PRIMITIVE - stores key value as is, by mapping it to Cassandra table column with corresponding type.
                Should be used only for simple java types (int, long, String, double, Date) which could be mapped
                to corresponding Cassadra types.
            b) BLOB - stores key value as BLOB, by mapping it to Cassandra table column with blob type.
                Could be used for any java object. Conversion of java object to BLOB is handled by "serializer"
                which could be specified in serializer attribute (see below).
            c) POJO - stores each field of an object as a column having corresponding type in Cassandra table.
                Provides ability to utilize Cassandra secondary indexes for object fields.
      3) serializer [optional] - specifies serializer class for BLOB strategy. Shouldn't be used for PRIMITIVE and
        POJO strategies. Available implementations:
            a) org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer - uses standard Java
                serialization framework
            b) org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer - uses Kryo
                serialization framework
      4) column     [optional] - specifies column name for PRIMITIVE and BLOB strategies where to store value.
        If not specified column having 'value' name will be used. Shouldn't be used for POJO strategy.
    -->
    <valuePersistence class="org.mycompany.MyValueClass" strategy="..." serializer="..." column="">
        <!--
         Specifies mapping from POJO field to Cassandra table column.

         Note: required element

         Attributes:
           1) name         [required] - POJO field name
           2) column       [optional] - Cassandra table column name. If not specified lowercase
              POJO field name will be used.
           3) static       [optional] - boolean flag which specifies that column is static withing a given partition
           4) index        [optional] - boolean flag specifying that secondary index should be created for the field
           5) indexClass   [optional] - custom index java class name if you want to use custom index
           6) indexOptions [optional] - custom index options
        -->
        <field name="firstName" column="first_name" static="..." index="..." indexClass="..." indexOptions="..."/>
        ...
        ...
    </valuePersistence>
</persistence>

Below are provided all the details about persistence descriptor configuration and its elements:

persistence

Caution

! Required Element

Root container for persistence settings configuration.

Attribute Required Description

keyspace

yes

Keyspace for Cassandra tables which should be used to store key/value pairs. If keyspace doesn’t exist it will be created (if specified Cassandra account has appropriate permissions).

table

no

Cassandra table which should be used to store key/value pairs. If table doesn’t exist it will be created (if specified Cassandra account has appropriate permissions). If table name doesn’t specified Ignite cache name will be used as a table name.

ttl

no

Expiration period for the table rows (in seconds).

In the next chapters you’ll find what child elements could be placed inside persistence settings container.

keyspaceOptions

Note

Optional Element

Options to create Cassandra keyspace specified in the keyspace attribute of persistence settings container.

Keyspace will be created only if it doesn’t exist and if an account used to connect to Cassandra has appropriate permissions.

The text specified in this XML element is just a chunk of CREATE KEYSPACE Cassandra DDL statement which goes after WITH keyword.

tableOptions

Note

Optional Element

Options to create Cassandra table specified in the table attribute of persistence settings container.

A table will be created only if it doesn’t exist and if an account used to connect to Cassandra has appropriate permissions.

The text specified in this XML element is just a chunk of CREATE TABLE Cassandra DDL statement which goes after WITH keyword.

keyPersistence

Caution

! Required Element

Persistent settings for Ignite cache keys.

These settings specify how key objects from Ignite cache should be stored/loaded to/from Cassandra table:

Attribute Required Description

class

yes

Java class name for Ignite cache keys.

strategy

yes

Specifies one of three possible persistent strategies (see below) which controls how object should be persisted/loaded to/from Cassandra table.

serializer

no

Serializer class for BLOB strategy (see below for available implementations). Shouldn’t be used for PRIMITIVE and POJO strategies.

column

no

Column name for PRIMITIVE and BLOB strategies where to store key. If not specified, column having 'key' name will be used. Attribute shouldn’t be specified for POJO strategy.

Persistence strategies:

Name Description

PRIMITIVE

Stores object as is, by mapping it to Cassandra table column with corresponding type. Should be used only for simple java types (int, long, String, double, Date) which could be directly mapped to corresponding Cassadra types. Use this link to figure out Java to Cassandra types mapping.

BLOB

Stores object as BLOB, by mapping it to Cassandra table column with blob type. Could be used for any java object. Conversion of java object to BLOB is handled by "serializer" which could be specified in serializer attribute of keyPersistence container.

POJO

Stores each field of an object as a column having corresponding type in Cassandra table. Provides ability to utilize Cassandra secondary indexes for object fields. Could be used only for POJO objects following Java Beans convention and having their fields of simple java type which could be directly mapped to corresponding Cassandra types.

Available serializer implementations:

Class Description

org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer

Uses standard Java serialization framework

org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer

Uses Kryo serialization framework

If you are using PRIMITIVE or BLOB persistence strategy you don’t need to specify internal elements of keyPersistence tag, cause the idea of these two strategies is that the whole object should be persisted into one column of Cassandra table (which could be specified by column attribute).

If you are using the POJO persistence strategy you have two option:

  • Leave keyPersistence tag empty - in a such case, all the fields of POJO object class will be detected automatically using such rules:

    • Only fields having simple java types which could be directly mapped to appropriate Cassandra types will be detected.

    • Fields discovery mechanism takes into account @QuerySqlField annotation:

      • If name attribute is specified it will be used as a column name for Cassandra table. Otherwise field name in a lowercase will be used as a column name.

      • If descending attribute is specified for a field mapped to cluster key column, it will be used to set sort order for the column.

    • Fields discovery mechanism takes into account @AffinityKeyMapped annotation. All the fields marked by this annotation will be treated as partition key fields (in an order as they are declared in a class). All other fields will be treated as cluster key fields.

    • If there are no fields annotated with @AffinityKeyMapped all the discovered fields will be treated as partition key fields.

  • Specify persistence details inside keyPersistence tag - in such case, you have to specify partition key fields mapping to Cassandra table columns inside partitionKey tag. This tag is used just as a container for mapping settings and doesn’t have any attributes. Optionally (if you are going to use cluster key) you can also specify cluster key fields mapping to appropriate Cassandra table columns inside clusterKey tag. This tag is used just as a container for mapping settings and doesn’t have any attributes.

Next two sections are providing a detailed specification for partition and cluster key fields mappings (which makes sense if you choose the second option from the list above).

partitionKey

Note

Optional Element

Container for field elements specifying Cassandra partition key.

Defines the Ignite cache KEY object fields (inside it), which should be used as a partition key fields in Cassandra table and specifies fields mappings to table columns.

Mappings are specified by using <field> tag having such attributes:

Attribute Required Description

name

yes

POJO object field name.

column

no

Cassandra table column name. If not specified lowercase POJO field name will be used.

clusterKey

Note

Optional Element

Container for field elements specifying Cassandra cluster key.

Defines the Ignite cache KEY object fields (inside it), which should be used as a cluster key fields in Cassandra table and specifies fields mappings to table columns.

Mapping are specified by using <field> tag having such attributes:

Attribute Required Description

name

yes

POJO object field name.

column

no

Cassandra table column name. If not specified lowercase POJO field name will be used.

sort

no

Specifies sort order for the field (asc or desc).

valuePersistence

Caution

! Required Element

Persistent settings for Ignite cache values.

These settings specify how value objects from Ignite cache should be stored/loaded to/from Cassandra table. The settings attributes look very similar to corresponding settings for Ignite cache keys:

Attribute Required Description

class

yes

Java class name for Ignite cache values.

strategy

yes

Specifies one of three possible persistent strategies (see below) which controls how object should be persisted/loaded to/from Cassandra table.

serializer

no

Serializer class for BLOB strategy (see below for available implementations). Shouldn’t be used for PRIMITIVE and POJO strategies.

column

no

Column name for PRIMITIVE and BLOB strategies where to store value. If not specified, column having value name will be used. Attribute shouldn’t be specified for POJO strategy.

Persistence strategies (same as for key persistence settings):

Name Description

PRIMITIVE

Stores object as is, by mapping it to Cassandra table column with corresponding type. Should be used only for simple java types (int, long, String, double, Date) which could be directly mapped to corresponding Cassadra types. Use this link to figure out Java to Cassandra types mapping.

BLOB

Stores object as BLOB, by mapping it to Cassandra table column with blob type. Could be used for any java object. Conversion of java object to BLOB is handled by "serializer" which could be specified in serializer attribute of keyPersistence container.

POJO

Stores each field of an object as a column having a corresponding type in Cassandra table. Provides ability to utilize Cassandra secondary indexes for object fields. Could be used only for POJO objects following Java Beans convention and having their fields of simple java type which could be directly mapped to corresponding Cassandra types.

Available serializer implementations (same as for key persistence settings):

Class Description

org.apache.ignite.cache.store.cassandra.serializer.JavaSerializer

Uses standard Java serialization framework.

org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer

Uses Kryo serialization framework.

If you are using PRIMITIVE or BLOB persistence strategy you don’t need to specify internal elements of valuePersistence tag, cause the idea of these two strategies is that the whole object should be persisted into one column of Cassandra table (which could be specified by column attribute).

If you are using POJO persistence strategy you have two option (similar to the same options for keys):

  • Leave valuePersistence tag empty - in such a case, all the fields of POJO object class will be detected automatically using such rules:

    • Only fields having simple java types which could be directly mapped to appropriate Cassandra types will be detected.

    • Fields discovery mechanism takes into account @QuerySqlField annotation:

      • If name attribute is specified it will be used as a column name for Cassandra table. Otherwise, field name in a lower case will be used as a column name.

      • If index attribute is specified, secondary index will be created for a corresponding column in Cassandra table (if such table doesn’t exist).

  • Specify persistence details inside valuePersistence tag - in such a case, you have to specify your POJO fields mapping to Cassandra table columns inside valuePersistence tag.

If you selected the second option from the list above, you have to use <field> tag to specify POJO fields to Cassandra table columns mapping. The tag has following attributes:

Attribute Required Description

name

yes

POJO object field name.

column

no

Cassandra table column name. If not specified lowercase POJO field name will be used.

static

no

Boolean flag which specifies that column is static withing a given partition.

index

no

Boolean flag specifying that secondary index should be created for the field.

indexClass

no

Custom index java class name, in case you want to use custom index.

indexOptions

no

Custom index options.