如何确定 CacheJdbcBlobStore table 条目的正确大小?
How to determine the right size of table entries for CacheJdbcBlobStore?
我正在尝试为我的 Apache Ignite 应用程序设置持久缓存存储。我尝试使用的缓存存储是 CacheJdbcBlobStore。这是我在原型中使用的软件列表:
- JDK1.8.0_66
- 阿帕奇 Tomcat 7.0.68
- Apache 点燃 1.6.0
- 超级数据库 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)
我的问题是:如何确定 table 条目(尤其是 val 列)的大小?目前我放下10k。如果我把尺寸设置得太高,那会很浪费,但是如果我把尺寸设置得太低,我迟早会得到上面提到的异常。谢谢。
也许您不必担心 table 个条目的列大小。例如,在 HyperSQL 数据库中,如果您按以下方式创建 table:
create table if not exists ENTRIES (akey VARBINARY(100) primary key, val BLOB(10k))
10k 是列 val 的最大大小,而不是将采用的实际 space。因此,如果实际长度低于最大限制,则不会造成浪费。
在 Oracle 中,您可以创建 table,如下所示:
create table ENTRIES (akey VARCHAR2(100) primary key, val BLOB);
同样,您不必担心列 val 的大小。 BLOB类型的列的大小在Oracle中可以看作是无限的(Maximum size: (4 GB - 1) * DB_BLOCK_SIZE initialization parameter (8 TB to 128 TB))。实际取space取决于缓存的实际大小。没有space会浪费
我正在尝试为我的 Apache Ignite 应用程序设置持久缓存存储。我尝试使用的缓存存储是 CacheJdbcBlobStore。这是我在原型中使用的软件列表:
- JDK1.8.0_66
- 阿帕奇 Tomcat 7.0.68
- Apache 点燃 1.6.0
- 超级数据库 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)
我的问题是:如何确定 table 条目(尤其是 val 列)的大小?目前我放下10k。如果我把尺寸设置得太高,那会很浪费,但是如果我把尺寸设置得太低,我迟早会得到上面提到的异常。谢谢。
也许您不必担心 table 个条目的列大小。例如,在 HyperSQL 数据库中,如果您按以下方式创建 table:
create table if not exists ENTRIES (akey VARBINARY(100) primary key, val BLOB(10k))
10k 是列 val 的最大大小,而不是将采用的实际 space。因此,如果实际长度低于最大限制,则不会造成浪费。
在 Oracle 中,您可以创建 table,如下所示:
create table ENTRIES (akey VARCHAR2(100) primary key, val BLOB);
同样,您不必担心列 val 的大小。 BLOB类型的列的大小在Oracle中可以看作是无限的(Maximum size: (4 GB - 1) * DB_BLOCK_SIZE initialization parameter (8 TB to 128 TB))。实际取space取决于缓存的实际大小。没有space会浪费