如何确定CacheJdbcBlobStore的表条目的正确大小?

时间:2016-05-25 14:10:22

标签: ignite

我正在尝试为Apache Ignite应用程序设置持久性缓存存储。我尝试使用的缓存存储是CacheJdbcBlobStore。这是我在原型中使用的软件列表:

  • JDK 1.8.0_66
  • Apache Tomcat 7.0.68
  • Apache Ignite 1.6.0
  • HyperSQL 2.3.4

我的数据源在Spring中设置如下:

<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
    <property name="url" value="jdbc:hsqldb:http://localhost"/>
    <property name="username" value="sa"/>
    <property name="password" value=""/>
</bean>

Ignite配置:

<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
    <property name="cacheConfiguration">
        <list>
            <bean class="org.apache.ignite.configuration.CacheConfiguration">
                <property name="cacheMode" value="REPLICATED"/>
                <property name="name" value="session-cache"/>
                <property name="cacheStoreFactory">
                    <bean class="org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory">
                        <property name="dataSourceBean" value="myDataSource" />
                    </bean>
                </property>
                <property name="readThrough" value="true" />
                <property name="writeThrough" value="true" />                               
            </bean>
        </list>
    </property>
</bean>

但是,当我运行应用程序时,我得到以下异常:

ERROR - root                       - Failed to update web session: null
class org.apache.ignite.IgniteException: Failed to save session: C56AF4E1DA01A439E43E512950D32D45
Caused by: javax.cache.integration.CacheWriterException: class org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException: Failed to update keys (retry update if possible).: [C56AF4E1DA
01A439E43E512950D32D45]
Caused by: class org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException: Failed to update keys (retry update if possible).: [C56AF4E1DA01A439E43E512950D32D45]
                Suppressed: class org.apache.ignite.IgniteCheckedException: Failed to put object [key=C56AF4E1DA01A439E43E512950D32D45, val=WebSessionEntity [id=C56AF4E1DA01A439E43E512950D32D45, createTime=1464182374328, accessTime=1464182374330, maxInactiveInterval=1800, attributes=[]]]
                        at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.put(GridCacheStoreManagerAdapter.java:583)
                        at org.apache.ignite.internal.processors.cache.GridCacheMapEntry.innerUpdate(GridCacheMapEntry.java:2358)
                        at org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridDhtAtomicCache.updateSingle(GridDhtAtomicCache.java:2246)
                        ... 37 more
                Caused by: javax.cache.integration.CacheWriterException: Failed to put object [key=C56AF4E1DA01A439E43E512950D32D45, val=WebSessionEntity [id=C56AF4E1DA01A439E43E512950D32D45, createTime=1464182374328, accessTime=1464182374330, maxInactiveInterval=1800, attributes=[]]]
                        at org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStore.write(CacheJdbcBlobStore.java:281)
                        at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.put(GridCacheStoreManagerAdapter.java:575)
                        ... 39 more
                Caused by: java.sql.SQLDataException: data exception: string data, right truncation;  table: ENTRIES column: AKEY
                        at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
                        at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
                        at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
                        at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
                        at org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStore.write(CacheJdbcBlobStore.java:277)
                        ... 40 more

我发现你需要将createTableQuery属性添加到jdbc.CacheJdbcBlobStoreFactory:

<bean class="org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory">
    ...
    <property name="createTableQuery" value="create table if not exists ENTRIES (akey VARBINARY(100) primary key, val BLOB(10k))" />
</bean>

以覆盖默认值:

create table if not exists ENTRIES (akey binary primary key, val binary)

我的问题是:您如何确定表条目的大小(尤其是val列)?目前我放下了10k。如果我将尺寸设置得太高,那将是浪费,但如果我把尺寸设得太低,我迟早会得到上面提到的例外。谢谢。

1 个答案:

答案 0 :(得分:1)

也许您不必担心表ENTRIES的列大小。例如,在HyperSQL数据库中,如果按以下方式创建表:

create table if not exists ENTRIES (akey VARBINARY(100) primary key, val BLOB(10k))

10k是列val的最大大小,而不是将要采用的实际空间。因此,如果实际长度低于最大限制,则不会浪费。

在Oracle中,您可以创建如下表:

create table ENTRIES (akey VARCHAR2(100) primary key, val BLOB);

同样,你不必担心列val的大小。在Oracle中,类型为BLOB的列的大小可视为无限(Maximum size: (4 GB - 1) * DB_BLOCK_SIZE initialization parameter (8 TB to 128 TB))。实际占用的空间取决于缓存的实际大小。不会浪费任何空间。