You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dm...@apache.org on 2020/09/30 23:44:20 UTC

[ignite] branch IGNITE-7595 updated: Ported the Cassandra integration's documentation from readme.io to the new docs engine

This is an automated email from the ASF dual-hosted git repository.

dmagda pushed a commit to branch IGNITE-7595
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/IGNITE-7595 by this push:
     new 0cb8389  Ported the Cassandra integration's documentation from readme.io to the new docs engine
     new fdef11c  Merge remote-tracking branch 'origin/IGNITE-7595' into IGNITE-7595
0cb8389 is described below

commit 0cb83898200e81c05fd6e90fb2b82473df3aba61
Author: Denis Magda <dm...@gridgain.com>
AuthorDate: Wed Sep 30 16:39:41 2020 -0700

    Ported the Cassandra integration's documentation from readme.io to the new docs engine
---
 docs/_data/toc.yaml                                |  10 +
 .../cassandra/configuration.adoc                   | 574 +++++++++++++++++
 .../cassandra/ddl-generator.adoc                   |  85 +++
 .../cassandra/overview.adoc                        |  40 ++
 .../cassandra/usage-examples.adoc                  | 677 +++++++++++++++++++++
 docs/_docs/persistence/external-storage.adoc       |  10 +-
 6 files changed, 1391 insertions(+), 5 deletions(-)

diff --git a/docs/_data/toc.yaml b/docs/_data/toc.yaml
index c68e4e8..6bd41f0 100644
--- a/docs/_data/toc.yaml
+++ b/docs/_data/toc.yaml
@@ -421,6 +421,16 @@
           url: extensions-and-integrations/streaming/zeromq-streamer
         - title: Twitter Streamer
           url: extensions-and-integrations/streaming/twitter-streamer
+    - title: Cassandra Integration
+      items:
+        - title: Overview
+          url: extensions-and-integrations/cassandra/overview
+        - title: Configuration
+          url: extensions-and-integrations/cassandra/configuration
+        - title: Usage Examples
+          url: extensions-and-integrations/cassandra/usage-examples
+        - title: DDL Generator
+          url: extensions-and-integrations/cassandra/ddl-generator
 - title: C# and .NET Specific
   items:
     - title: Configuration Options
diff --git a/docs/_docs/extensions-and-integrations/cassandra/configuration.adoc b/docs/_docs/extensions-and-integrations/cassandra/configuration.adoc
new file mode 100644
index 0000000..d35d32d
--- /dev/null
+++ b/docs/_docs/extensions-and-integrations/cassandra/configuration.adoc
@@ -0,0 +1,574 @@
+= 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:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<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:
+
+[cols="20%,70%,10%",opts="header"]
+|===
+| 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:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<!--
+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]
+====
+[discrete]
+=== ! Required Element
+Root container for persistence settings configuration.
+====
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| 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]
+====
+[discrete]
+=== 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
+http://docs.datastax.com/en/cql/3.0/cql/cql_reference/create_keyspace_r.html[CREATE KEYSPACE, window=_blank] Cassandra DDL statement which goes after *WITH* keyword.
+
+=== tableOptions
+
+[NOTE]
+====
+[discrete]
+=== 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
+http://docs.datastax.com/en/cql/3.0/cql/cql_reference/create_table_r.html[CREATE TABLE, window=_blank] Cassandra DDL statement which goes after *WITH* keyword.
+
+=== keyPersistence
+
+[CAUTION]
+====
+[discrete]
+=== ! 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:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| 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:
+
+[cols="1,3",opts="header"]
+|===
+| 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
+https://docs.datastax.com/en/developer/java-driver/4.4/manual/core/#cql-to-java-type-mapping[link, window=_blank] 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 https://docs.datastax.com/en/developer/java-driver/4.4/manual/core/#cql-to-java-type-mapping[simple java type which could be directly mapped to corresponding Cassandra types, window=_blank].
+|===
+
+Available serializer implementations:
+
+[cols="1,3",opts="header"]
+|===
+| 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
+http://docs.datastax.com/en/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[appropriate Cassandra types, window=_blank]
+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 http://docs.datastax.com/en/cql/3.0/cql/ddl/ddl_compound_keys_c.html[partition key, window=_blank]
+fields (in an order as they are declared in a class). All other fields will be treated as
+http://docs.datastax.com/en/cql/3.0/cql/ddl/ddl_compound_keys_c.html[cluster key] fields.
+ ** If there are no fields annotated with `@AffinityKeyMapped` all the discovered fields will be treated as
+http://docs.datastax.com/en/cql/3.0/cql/ddl/ddl_compound_keys_c.html[partition key, window=_blank] 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]
+====
+[discrete]
+=== 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:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| 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]
+====
+[discrete]
+=== 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:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| 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]
+====
+[discrete]
+=== ! 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:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| 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):
+
+[cols="1,3",opts="header"]
+|===
+| 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
+http://docs.datastax.com/en/developer/java-driver/2.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[link, window=_blank] 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 http://docs.datastax.com/en/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[simple java type which could be directly mapped to corresponding Cassandra types, window=_blank].
+|===
+
+Available serializer implementations (same as for key persistence settings):
+
+[cols="1,3",opts="header"]
+|===
+| 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
+http://docs.datastax.com/en/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[appropriate Cassandra types, window=_blank] 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:
+
+[cols="20%,20%,60%",opts="header"]
+|===
+| 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.
+|===
diff --git a/docs/_docs/extensions-and-integrations/cassandra/ddl-generator.adoc b/docs/_docs/extensions-and-integrations/cassandra/ddl-generator.adoc
new file mode 100644
index 0000000..4935648
--- /dev/null
+++ b/docs/_docs/extensions-and-integrations/cassandra/ddl-generator.adoc
@@ -0,0 +1,85 @@
+= DDL Generator
+
+== Overview
+
+One of the benefits of the Ignite Cassandra integration is that you don't need to care about Cassandra DDL syntax for
+table creation and Java to Cassandra type mapping details.
+
+You just need to create an XML configuration which specifies how Ignite cache keys and values should be serialized/deserialized to/from Cassandra.
+Based on this settings all the absent Cassandra keyspaces and tables will be created automatically. The only requirement for all this "magic" to work:
+
+[CAUTION]
+====
+[discrete]
+===
+In connection settings for Cassandra, you should specify user having enough permissions to create keyspaces/tables
+====
+
+However, for some of the deployments it's not possible because of a very strict security policy. Thus the only solution in
+a such situation is to provide DDL scripts for DevOps team to create all the necessary Cassandra keyspaces/tables in advance.
+
+That's the exact use-case for DDL generator utility that generates DDLs from
+link:extensions-and-integrations/cassandra/configuration#persistencesettingsbean[PersistenceSettingsBean settings].
+
+Below is a sample syntax for the Cassandra DDL generation:
+
+[tabs]
+--
+tab:Shell[]
+[source, shell]
+----
+java org.apache.ignite.cache.store.cassandra.utils.DDLGenerator /opt/dev/ignite/persistence-settings-1.xml /opt/dev/ignite/persistence-settings-2.xml
+----
+--
+
+The generated DDL can look as follows:
+
+[tabs]
+--
+tab:Generated Cassandra DDL[]
+[source, sql]
+----
+-------------------------------------------------------------
+DDL for keyspace/table from file: /opt/dev/ignite/persistence-settings-1.xml
+-------------------------------------------------------------
+
+create keyspace if not exists test1
+with replication = {'class' : 'SimpleStrategy', 'replication_factor' : 3} and durable_writes = true;
+
+create table if not exists test1.primitive_test1
+(
+ key int,
+ value int,
+ primary key ((key))
+);
+
+-------------------------------------------------------------
+DDL for keyspace/table from file: /opt/dev/ignite/persistence-settings-2.xml
+-------------------------------------------------------------
+
+create keyspace if not exists test1
+with REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3} AND DURABLE_WRITES = true;
+
+create table if not exists test1.pojo_test3
+(
+ company text,
+ department text,
+ number int,
+ first_name text,
+ last_name text,
+ age int,
+ married boolean,
+ height bigint,
+ weight float,
+ birth_date timestamp,
+ phones blob,
+ primary key ((company, department), number)
+)
+with comment = 'A most excellent and useful table' AND read_repair_chance = 0.2 and clustering order by (number desc);
+----
+--
+
+Just don't forget to set the `CLASSPATH` environment variable correctly:
+
+. Include the jar file for Ignite Cassandra module (`ignite-cassandra-<version-number>.jar`) in your `CLASSPATH`.
+. If you are using `POJO` persistence strategy for some of your custom java classes you need to include jars with these classes in your CLASSPATH as well.
diff --git a/docs/_docs/extensions-and-integrations/cassandra/overview.adoc b/docs/_docs/extensions-and-integrations/cassandra/overview.adoc
new file mode 100644
index 0000000..cbe3935
--- /dev/null
+++ b/docs/_docs/extensions-and-integrations/cassandra/overview.adoc
@@ -0,0 +1,40 @@
+= Apache Cassandra Acceleration With Apache Ignite
+
+== Overview
+
+The Ignite Cassandra integration implements the link:persistence/external-storage#overview[CacheStore] interface allowing
+to deploy Ignite as a high-performance caching layer on top of Cassandra.
+
+Some observations in regards to the integration:
+
+. The integration uses Cassandra http://www.datastax.com/dev/blog/java-driver-async-queries[asynchronous queries, window=_blank]
+for `CacheStore` batch operations such as such as `loadAll()`, `writeAll()` and `deleteAll()` to provide extremely high performance.
+. The integration automatically creates all necessary tables (and keyspaces) in Cassandra if they are absent. Also, it
+automatically detects all the necessary fields for Ignite key-value tuples that will be stored as POJOs, and creates an
+appropriate table structure. Thus you don't need to care about the Cassandra DDL syntax for table creation and Java to
+Cassandra type mapping details.
+. You can optionally specify the settings (replication factor, replication strategy, bloom filter and etc.) for Cassandra
+tables and keyspaces which should be created.
+. Combines functionality of BLOB and POJO storage, allowing to specify how you prefer to store (as a BLOB or as a POJO)
+key-value tuples from your Ignite cache.
+. Supports standard https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html[Java, window=_blank] and
+https://github.com/EsotericSoftware/kryo[Kryo, window=_blank] serialization for key-values which should be stored as BLOBs in Cassandra
+. Supports Cassandra http://docs.datastax.com/en/cql/3.0/cql/cql_reference/create_index_r.html[secondary indexes, window=_blank] (including custom indexes)
+through persistence configuration settings for particular Ignite cache or such settings could be detected automatically
+if you configured link:SQL/indexes#configuring-indexes-using-annotations[SQL Indexes by Annotations] by using `@QuerySqlField(index = true)` annotation
+. Supports sort order for Cassandra cluster key fields through persistence configuration settings or such settings could be
+detected automatically if you are using `@QuerySqlField(descending = true)` annotation.
+. Supports link:data-modeling/affinity-collocation[affinity co-location] for the POJO key classes having one of their fields
+annotated by `@AffinityKeyMapped`. In such a way, key-values tuples which were stored on one node in an Ignite cache will
+be also stored (co-located) on one node in Cassandra.
+
+[CAUTION]
+====
+[discrete]
+=== Ignite SQL Queries and Cassandra
+Note that in order to execute SQL queries you need to have all the data loaded from Cassandra into an Ignite cluster.
+The Ignite SQL engine doesn't assumes that all the records are available in memory and won't try to query Cassandra.
+
+An alternative would be to use Ignite Native Persistence - a distributed, ACID, and SQL-compliant disk store that allows
+performing SQL queries on the data stored in-memory as well as on disk.
+====
diff --git a/docs/_docs/extensions-and-integrations/cassandra/usage-examples.adoc b/docs/_docs/extensions-and-integrations/cassandra/usage-examples.adoc
new file mode 100644
index 0000000..894228b
--- /dev/null
+++ b/docs/_docs/extensions-and-integrations/cassandra/usage-examples.adoc
@@ -0,0 +1,677 @@
+= Ignite Cassandra Integration Usage Examples
+
+== Overview
+
+As described in link:extensions-and-integrations/cassandra/configuration[configuration section], to configure Cassandra
+as a cache store you need to set `CacheStoreFactory` for your Ignite caches to `org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory`.
+
+Below is an example of a typical configuration for Ignite cache to use Cassandra as a cache store. We will go step-by-step
+through all the configuration items, further down. The example is taken from the unit tests resource file
+`store/src/test/resources/org/apache/ignite/tests/persistence/blob/ignite-config.xml` of the Cassandra module source code.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       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">
+
+    <!-- Cassandra connection settings -->
+    <import resource="classpath:org/apache/ignite/tests/cassandra/connection-settings.xml" />
+
+    <!-- Persistence settings for 'cache1' -->
+    <bean id="cache1_persistence_settings" class="org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings">
+        <constructor-arg type="org.springframework.core.io.Resource" value="classpath:org/apache/ignite/tests/persistence/blob/persistence-settings-1.xml" />
+    </bean>
+
+    <!-- Persistence settings for 'cache2' -->
+    <bean id="cache2_persistence_settings" class="org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings">
+        <constructor-arg type="org.springframework.core.io.Resource" value="classpath:org/apache/ignite/tests/persistence/blob/persistence-settings-3.xml" />
+    </bean>
+
+    <!-- Ignite configuration -->
+    <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"/>
+                    <property name="readThrough" value="true"/>
+                    <property name="writeThrough" value="true"/>
+                    <property name="cacheStoreFactory">
+                        <bean class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+                            <property name="dataSourceBean" value="cassandraAdminDataSource"/>
+                            <property name="persistenceSettingsBean" value="cache1_persistence_settings"/>
+                        </bean>
+                    </property>
+                </bean>
+
+                <!-- Configuring persistence for "cache2" cache -->
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="cache2"/>
+                    <property name="readThrough" value="true"/>
+                    <property name="writeThrough" value="true"/>
+                    <property name="cacheStoreFactory">
+                        <bean class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+                            <property name="dataSourceBean" value="cassandraAdminDataSource"/>
+                            <property name="persistenceSettingsBean" value="cache2_persistence_settings"/>
+                        </bean>
+                    </property>
+                </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">
+                    <!--
+                        Ignite provides several options for automatic discovery that can be used
+                        instead os static IP based discovery. For information on all options refer
+                        to our documentation: http://apacheignite.readme.io/docs/cluster-config
+                    -->
+                    <!-- 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>127.0.0.1:47500..47509</value>
+                            </list>
+                        </property>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+    </bean>
+</beans>
+----
+--
+
+In the specified example we have two Ignite caches configured: `cache1` and `cache2`. So lets look at the configuration details.
+
+Lets start from the cache configuration details. They are pretty similar for both caches (`cache1` and `cache2`) and looks like that:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<bean class="org.apache.ignite.configuration.CacheConfiguration">
+    <property name="name" value="cache1"/>
+    <property name="readThrough" value="true"/>
+    <property name="writeThrough" value="true"/>
+    <property name="cacheStoreFactory">
+        <bean class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+            <property name="dataSourceBean" value="cassandraAdminDataSource"/>
+            <property name="persistenceSettingsBean" value="cache1_persistence_settings"/>
+        </bean>
+    </property>
+</bean>
+----
+--
+
+First of all we can see that `read-through` and `write-through` options are enabled:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<property name="readThrough" value="true"/>
+<property name="writeThrough" value="true"/>
+----
+--
+
+which is required for Ignite cache, if you plan to use a persistent store for cache entries which expired.
+
+You can optionally specify the `write-behind` setting if you prefer persistent store to be updated asynchronously:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<property name="readThrough" value="true"/>
+<property name="writeThrough" value="true"/>
+----
+--
+
+The next important thing is `CacheStoreFactory` configuration:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<property name="cacheStoreFactory">
+    <bean class="org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory">
+        <property name="dataSourceBean" value="cassandraAdminDataSource"/>
+        <property name="persistenceSettingsBean" value="cache1_persistence_settings"/>
+    </bean>
+</property>
+----
+--
+
+You should use `org.apache.ignite.cache.store.cassandra.CassandraCacheStoreFactory` as a `CacheStoreFactory` for your
+Ignite caches to utilize Cassandra as a persistent store. For `CassandraCacheStoreFactory` you should specify two required properties:
+
+* `dataSourceBean` - name of the Spring bean, which specifies all the details about Cassandra database connection.
+
+* `persistenceSettingsBean` - name of the Spring bean, which specifies all the details about how objects should be persisted into Cassandra database.
+
+In the specified example `cassandraAdminDataSource` is a data source bean, which is imported into Ignite cache config file using this directive:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<import resource="classpath:org/apache/ignite/tests/cassandra/connection-settings.xml" />
+----
+--
+
+and `cache1_persistence_settings` is a persistence settings bean, which is defined in Ignite cache config file using such directive:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<bean id="cache1_persistence_settings" class="org.apache.ignite.cache.store.cassandra.utils.persistence.KeyValuePersistenceSettings">
+    <constructor-arg type="org.springframework.core.io.Resource" value="classpath:org/apache/ignite/tests/persistence/blob/persistence-settings-1.xml" />
+</bean>
+----
+--
+
+Now lets look at the specification of `cassandraAdminDataSource` from `store/src/test/resources/org/apache/ignite/tests/cassandra/connection-settings.xml`
+test resource.
+
+Specifically,`CassandraAdminCredentials` and `CassandraRegularCredentials` are classes which extend
+`org.apache.ignite.cache.store.cassandra.datasource.Credentials`. You are welcome to implement these classes and reference them afterwards.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       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">
+
+    <bean id="cassandraAdminCredentials" class="org.my.project.CassandraAdminCredentials"/>
+    <bean id="cassandraRegularCredentials" class="org.my.project.CassandraRegularCredentials"/>
+
+    <bean id="loadBalancingPolicy" class="com.datastax.driver.core.policies.TokenAwarePolicy">
+        <constructor-arg type="com.datastax.driver.core.policies.LoadBalancingPolicy">
+            <bean class="com.datastax.driver.core.policies.RoundRobinPolicy"/>
+        </constructor-arg>
+    </bean>
+
+    <bean id="contactPoints" class="org.apache.ignite.tests.utils.CassandraHelper" factory-method="getContactPointsArray"/>
+
+    <bean id="cassandraAdminDataSource" class="org.apache.ignite.cache.store.cassandra.datasource.DataSource">
+        <property name="credentials" ref="cassandraAdminCredentials"/>
+        <property name="contactPoints" ref="contactPoints"/>
+        <property name="readConsistency" value="ONE"/>
+        <property name="writeConsistency" value="ONE"/>
+        <property name="loadBalancingPolicy" ref="loadBalancingPolicy"/>
+    </bean>
+
+    <bean id="cassandraRegularDataSource" class="org.apache.ignite.cache.store.cassandra.datasource.DataSource">
+        <property name="credentials" ref="cassandraRegularCredentials"/>
+        <property name="contactPoints" ref="contactPoints"/>
+        <property name="readConsistency" value="ONE"/>
+        <property name="writeConsistency" value="ONE"/>
+        <property name="loadBalancingPolicy" ref="loadBalancingPolicy"/>
+    </bean>
+</beans>
+----
+--
+
+For more details about Cassandra data source connection configuration visit the link:extensions-and-integrations/cassandra/configuration[integration configuration page].
+
+Finally, the last piece which wasn't still described is persistence settings configuration. Lets look at the
+`cache1_persistence_settings` from the `org/apache/ignite/tests/persistence/blob/persistence-settings-1.xml` test resource.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="blob_test1">
+    <keyPersistence class="java.lang.Integer" strategy="PRIMITIVE" />
+    <valuePersistence strategy="BLOB"/>
+</persistence>
+----
+--
+
+In the configuration above, we can see that Cassandra `test1.blob_test1` table will be used to store key/value objects for
+**cache1** cache. Key objects of the cache will be stored as **integer** in `key` column. Value objects of the cache will be
+stored as **blob** in `value` column. For more information about persistence settings configuration visit the
+link:extensions-and-integrations/cassandra/configuration[integration configuration page].
+
+Next sections will provide examples of persistence settings configuration for different kind of persistence strategies
+(see more details about persistence strategies on the link:extensions-and-integrations/cassandra/configuration[integration configuration page].
+
+== Example 1
+
+Persistence setting for Ignite cache with keys of `Integer` type to be persisted as `int` in Cassandra and values of
+`String` type to be persisted as `text` in Cassandra.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table">
+    <keyPersistence class="java.lang.Integer" strategy="PRIMITIVE" column="my_key"/>
+    <valuePersistence class="java.lang.String" strategy="PRIMITIVE" />
+</persistence>
+----
+--
+
+Keys will be stored in `my_key` column. Values will be stored in `value` column (which is used by default if `column` attribute wasn't specified).
+
+== Example 2
+
+Persistence setting for Ignite cache with keys of `Integer` type to be persisted as `int` in Cassandra and values of `any`
+type (you don't need to specify the type for **BLOB** persistence strategy) to be persisted as `blob` in Cassandra.
+The only solution for this situation is to store value as a `BLOB` in Cassandra table.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table">
+    <keyPersistence class="java.lang.Integer" strategy="PRIMITIVE" />
+    <valuePersistence strategy="BLOB"/>
+</persistence>
+----
+--
+
+Keys will be stored in `key` column (which is used by default if `column` attribute wasn't specified). Values will be stored in `value` column.
+
+== Example 3
+
+Persistence setting for Ignite cache with keys of `Integer` type and values of **any** type, both to be persisted as `BLOB` in Cassandra.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table">
+    <!-- By default Java standard serialization is going to be used -->
+    <keyPersistence class="java.lang.Integer"
+                    strategy="BLOB"/>
+
+    <!-- Kryo serialization specified to be used -->
+    <valuePersistence class="org.apache.ignite.tests.pojos.Person"
+                      strategy="BLOB"
+                      serializer="org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer"/>
+</persistence>
+----
+--
+
+Keys will be stored in `key` column having `blob` type and using
+https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html[Java standard serialization, window=_blank]. Values will be stored in
+`value` column having `blob` type and using https://github.com/EsotericSoftware/kryo[Kryo serialization, window=_blank].
+
+== Example 4
+
+Persistence setting for Ignite cache with keys of `Integer` type to be persisted as `int` in Cassandra and values of custom
+POJO `org.apache.ignite.tests.pojos.Person` type to be dynamically analyzed and persisted into a set of table columns,
+so that each POJO field will be mapped to appropriate table column. For more details about dynamic POJO fields discovery
+refer to link:extensions-and-integrations/cassandra/configuration#persistencesettingsbean[PersistenceSettingsBean] documentation section.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table">
+    <keyPersistence class="java.lang.Integer" strategy="PRIMITIVE"/>
+    <valuePersistence class="org.apache.ignite.tests.pojos.Person" strategy="POJO"/>
+</persistence>
+----
+--
+
+Keys will be stored in `key` column having `int` type. 
+
+Now lets imagine that the `org.apache.ignite.tests.pojos.Person` class has such an implementation:
+
+[tabs]
+--
+tab:Java[]
+[source, java]
+----
+public class Person {
+    private String firstName;
+    private String lastName;
+    private int age;
+    private boolean married;
+    private long height;
+    private float weight;
+    private Date birthDate;
+    private List<String> phones;
+
+    public void setFirstName(String name) {
+        firstName = name;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setLastName(String name) {
+        lastName = name;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setMarried(boolean married) {
+        this.married = married;
+    }
+
+    public boolean getMarried() {
+        return married;
+    }
+
+    public void setHeight(long height) {
+        this.height = height;
+    }
+
+    public long getHeight() {
+        return height;
+    }
+
+    public void setWeight(float weight) {
+        this.weight = weight;
+    }
+
+    public float getWeight() {
+        return weight;
+    }
+
+    public void setBirthDate(Date date) {
+        birthDate = date;
+    }
+
+    public Date getBirthDate() {
+        return birthDate;
+    }
+
+    public void setPhones(List<String> phones) {
+        this.phones = phones;
+    }
+
+    public List<String> getPhones() {
+        return phones;
+    }
+}
+----
+--
+
+In this case Ignite cache values of the `org.apache.ignite.tests.pojos.Person` type will be persisted into a set of
+Cassandra table columns using such dynamically configured mapping rule:
+
+[opts="header"]
+|===
+| POJO field    | Table column     | Column type
+| firstName     | firstname        | text
+| lastName      | lastname         | text
+| age           | age              | int
+| married       | married          | boolean
+| height        | height           | bigint
+| weight        | weight           | float
+| birthDate     | birthdate        | timestamp
+|===
+
+As you can see from the table above, `phones` field will not be persisted into table. That's because it's not of simple
+java type which could be directly mapped to http://docs.datastax.com/en/developer/java-driver/1.0/java-driver/reference/javaClass2Cql3Datatypes_r.html[appropriate, window=_blank] Cassandra type.
+Such kind of fields could be persisted into Cassandra only if you manually specify all mapping details for the object type
+and if field type itself is implementing `java.io.Serializable` interface. In a such case field will be persisted into a
+separate table column as `blob`. See more details in the next example.
+
+== Example 5
+
+Persistence setting for Ignite cache with keys of custom POJO `org.apache.ignite.tests.pojos.PersonId` and values of
+custom POJO `org.apache.ignite.tests.pojos.Person` types, both to be persisted into a set of table columns based on
+manually specified mapping rules.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table" ttl="86400">
+    <!-- Cassandra keyspace options which should be used to create provided keyspace if it doesn't exist -->
+    <keyspaceOptions>
+        REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3}
+        AND DURABLE_WRITES = true
+    </keyspaceOptions>
+
+    <!-- Cassandra table options which should be used to create provided table if it doesn't exist -->
+    <tableOptions>
+        comment = 'A most excellent and useful table'
+        AND read_repair_chance = 0.2
+    </tableOptions>
+
+    <!-- Persistent settings for Ignite cache keys -->
+    <keyPersistence class="org.apache.ignite.tests.pojos.PersonId" strategy="POJO">
+        <!-- Partition key fields if POJO strategy used -->
+        <partitionKey>
+            <!-- Mapping from POJO field to Cassandra table column -->
+            <field name="companyCode" column="company" />
+            <field name="departmentCode" column="department" />
+        </partitionKey>
+
+        <!-- Cluster key fields if POJO strategy used -->
+        <clusterKey>
+            <!-- Mapping from POJO field to Cassandra table column -->
+            <field name="personNumber" column="number" sort="desc"/>
+        </clusterKey>
+    </keyPersistence>
+
+    <!-- Persistent settings for Ignite cache values -->
+    <valuePersistence class="org.apache.ignite.tests.pojos.Person"
+                      strategy="POJO"
+                      serializer="org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer">
+        <!-- Mapping from POJO field to Cassandra table column -->
+        <field name="firstName" column="first_name" />
+        <field name="lastName" column="last_name" />
+        <field name="age" />
+        <field name="married" index="true"/>
+        <field name="height" />
+        <field name="weight" />
+        <field name="birthDate" column="birth_date" />
+        <field name="phones" />
+    </valuePersistence>
+</persistence>
+----
+--
+
+These persistence settings looks rather complicated. Lets go step by step and analyse them.
+
+Lets first look at the root tag:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<persistence keyspace="test1" table="my_table" ttl="86400">
+----
+--
+
+It specifies that Ignite cache keys and values should be stored in `test1.my_table` table and that data in each row
+http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_expire_c.html[expires, window=_blank] after `86400` sec which is `24` hours.
+
+Then we can see the advanced settings for Cassandra keyspace. The setting will be used to create keyspace if it's not exist.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<keyspaceOptions>
+    REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 3}
+    AND DURABLE_WRITES = true
+</keyspaceOptions>
+----
+--
+
+Then by analogy to keyspace setting we can see table advanced setting, which will be used only for table creation.
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<tableOptions>
+    comment = 'A most excellent and useful table'
+    AND read_repair_chance = 0.2
+</tableOptions>
+----
+--
+
+Next section specifies how Ignite cache keys should be persisted:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<keyPersistence class="org.apache.ignite.tests.pojos.PersonId" strategy="POJO">
+    <!-- Partition key fields if POJO strategy used -->
+    <partitionKey>
+        <!-- Mapping from POJO field to Cassandra table column -->
+        <field name="companyCode" column="company" />
+        <field name="departmentCode" column="department" />
+    </partitionKey>
+
+    <!-- Cluster key fields if POJO strategy used -->
+    <clusterKey>
+        <!-- Mapping from POJO field to Cassandra table column -->
+        <field name="personNumber" column="number" sort="desc"/>
+    </clusterKey>
+</keyPersistence>
+----
+--
+
+Lets assume that `org.apache.ignite.tests.pojos.PersonId` has such implementation:
+
+[tabs]
+--
+tab:Java[]
+[source, java]
+----
+public class PersonId {
+    private String companyCode;
+    private String departmentCode;
+    private int personNumber;
+
+    public void setCompanyCode(String code) {
+        companyCode = code;
+    }
+
+    public String getCompanyCode() {
+        return companyCode;
+    }
+
+    public void setDepartmentCode(String code) {
+        departmentCode = code;
+    }
+
+    public String getDepartmentCode() {
+        return departmentCode;
+    }
+
+    public void setPersonNumber(int number) {
+        personNumber = number;
+    }
+
+    public int getPersonNumber() {
+        return personNumber;
+    }
+}
+----
+--
+
+In such case Ignite cache keys of `org.apache.ignite.tests.pojos.PersonId` type will be persisted into a set of Cassandra
+table columns representing `PARTITION` and `CLUSTER` key using this mapping rule:
+
+[opts="header"]
+|===
+| POJO field    | Table column     | Column type
+| companyCode     | company        | text
+| departmentCode  | department         | text
+| personNumber    | number              | int
+|===
+
+In addition to that, combination of columns `(company, department)` will be used as Cassandra `PARTITION` key and column
+`number` will be used as a `CLUSTER` key sorted in descending order.
+
+Finally lets move to the last section, which specifies persistence settings for Ignite cache values:
+
+[tabs]
+--
+tab:XML[]
+[source, xml]
+----
+<valuePersistence class="org.apache.ignite.tests.pojos.Person"
+                  strategy="POJO"
+                  serializer="org.apache.ignite.cache.store.cassandra.serializer.KryoSerializer">
+    <!-- Mapping from POJO field to Cassandra table column -->
+    <field name="firstName" column="first_name" />
+    <field name="lastName" column="last_name" />
+    <field name="age" />
+    <field name="married" index="true"/>
+    <field name="height" />
+    <field name="weight" />
+    <field name="birthDate" column="birth_date" />
+    <field name="phones" />
+</valuePersistence>
+----
+--
+
+Lets assume `that org.apache.ignite.tests.pojos.Person` class has the same implementation like in link:extensions-and-integrations/cassandra/usage-examples#example-4[Example 4].
+In this case Ignite cache values of `org.apache.ignite.tests.pojos.Person` type will be persisted into a set of Cassandra
+table columns using such mapping rule:
+
+[opts="header"]
+|===
+| POJO field    | Table column     | Column type
+| firstName     | first_name        | text
+| lastName      | last_name         | text
+| age           | age              | int
+| married       | married          | boolean
+| height        | height           | bigint
+| weight        | weight           | float
+| birthDate     | birth_date        | timestamp
+| phones        | phones           | blob
+|===
+
+Comparing to link:extensions-and-integrations/cassandra/usage-examples#example-4[Example 4] we can see that now `phones`
+field will be serialized to `phones` column of `blob` type using https://github.com/EsotericSoftware/kryo[Kryo, window=_blank] serializer.
+In addition to that, Cassandra secondary index will be created for the `married` column.
diff --git a/docs/_docs/persistence/external-storage.adoc b/docs/_docs/persistence/external-storage.adoc
index b163ab8..47188ad2 100644
--- a/docs/_docs/persistence/external-storage.adoc
+++ b/docs/_docs/persistence/external-storage.adoc
@@ -196,12 +196,12 @@ CAUTION: Even though Ignite supports distributed transactions, it doesn't make y
 
 === Cassandra Integration
 
-Ignite provides an out-of-the-box implementation of `CacheStore` that enables you to use Apache Cassandra as a persistent storage. This implementation utilizes Cassandra's link:http://www.datastax.com/dev/blog/java-driver-async-queries[asynchronous queries] to provide high performance batch operations such as `loadAll()`, `writeAll()` and `deleteAll()`, and automatically creates all necessary tables and namespaces in Cassandra.
+Ignite provides an out-of-the-box implementation of `CacheStore` that enables you to use Apache Cassandra as a persistent
+storage. This implementation utilizes Cassandra's link:http://www.datastax.com/dev/blog/java-driver-async-queries[asynchronous queries, window=_blank]
+to provide high performance batch operations such as `loadAll()`, `writeAll()` and `deleteAll()`, and automatically creates
+all necessary tables and namespaces in Cassandra.
 
-////
-TODO
-Refer to the dedicated section on Cassandra integration for more information.
-////
+Refer to link:extensions-and-integrations/cassandra/overview[this documentation section] for configuration and usage guidelines.
 
 ////
 == Implementing Custom CacheStore