我需要能夠以每秒5000次以上的速度寫入我的數據庫。目前,我無法管理該數字的10%以上。使用Hibernate 2nd Level Cache和HSQL令人失望的插入/更新率
我使用Spring將我的數據源(HSQL)和Hibernate配置爲我的Jpa提供程序。
我的實體都是平坦的(沒有複雜的對象樹),我採用了Hibernate Second Level Caching(EhCache),併發策略設置爲ConcurrencyStrategy.READ-WRITE。
這裏是我的數據源豆我的春節 - 語境:
<bean id="commandsTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="commandEmf"/>
<tx:annotation-driven transaction-manager="commandsTransactionManager" />
<!-- Commmands Data Source Configuration -->
<bean id="commandsDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc-commands.driverClassName}"/>
<property name="url" value="${jdbc-commands.url}"/>
<property name="username" value="${jdbc-commands.username}"/>
<property name="password" value="${jdbc-commands.password}"/>
<property name="initialSize" value="10"/>
<property name="maxActive" value="100"/>
<property name="maxWait" value="-1"/>
</bean>
<bean name="lazyConnectionDataSourceProxy" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource" ref="commandsDataSource" />
</bean>
<!-- Commands Container Managed JPA Entity Manager Factory -->
<bean id="commandEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="commandsDataSource"/>
<property name="persistenceUnitName" value="commands"/>
<property name="jpaPropertyMap" ref="jpaPropertyMap"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:showSql="false" p:generateDdl="true" p:database="HSQL" p:databasePlatform="org.hibernate.dialect.HSQLDialect">
</bean>
</property>
</bean>
<util:map id="jpaPropertyMap" key-type="java.lang.String" value-type="java.lang.Object">
<entry key="hibernate.hbm2ddl.auto" value="${jdbc-commands.ddlmode}" />
<entry key="hibernate.cache.use_second_level_cache" value="true" />
<entry key="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory"/>
</util:map>
這裏是我的實體類的一個示例。 'AbstractAnnotatedAggregateRoot'是來自Axon Framework的Abstract Entity類,它提供了Aggregate和Repository實現框架。聚合實質上是必須實現他們自己的Jpa才能持久化的實體。
@Entity
@Table(name = "users")
@Cache(region="usersCache", usage= CacheConcurrencyStrategy.READ_WRITE)
public class User extends AbstractAnnotatedAggregateRoot {
private static final long serialVersionUID = -6536766172448063298L;
private String username;
private String password;
private Integer subscription;
private String firstName;
private String lastName;
private Calendar subscriptionDate;
private Date lastAccessTime;
public User(){}
public User(StringAggregateIdentifier email){
super(email);
registerEvent(new UserCreatedEvent(email.asString()));
}
@Column(unique = true)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
registerEvent(new UserNameUpdatedEvent(this.username));
}
@Column(nullable = false)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
registerEvent(new UserPasswordUpdatedEvent(this.password));
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
registerEvent(new UserFirstNameUpdatedEvent(this.firstName));
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
registerEvent(new UserLastNameUpdatedEvent(this.lastName));
}
public String getEmail() {
return getIdentifier().asString();
}
@Temporal(TemporalType.DATE)
public Calendar getSubscriptionDate() {
return subscriptionDate;
}
public void setSubscriptionDate(Calendar subscriptionDate) {
this.subscriptionDate = subscriptionDate;
registerEvent(new UserSubscriptionDateUpdatedEvent(this.subscriptionDate));
}
@Temporal(TemporalType.TIMESTAMP)
public Date getLastAccessTime() {
return lastAccessTime;
}
public void setLastAccessTime(Date lastAccessTime) {
this.lastAccessTime = lastAccessTime;
registerEvent(new UserLastAccessTimeUpdatedEvent(this.lastAccessTime));
}
public Integer getSubscription() {
return subscription;
}
public void setSubscription(Integer subscription) {
this.subscription = subscription;
registerEvent(new UserSubscriptionUpdatedEvent(this.subscription));
}
}
爲了完整起見,這裏是我ehcache.xml中的文件緩存區域配置:
<cache name="usersCache" maxElementsInMemory="10000"
maxElementsOnDisk="10000" eternal="false" overflowToDisk="false"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="300"
timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU"
statistics = "true">
</cache>
在軸突框架,我派遣命令,試圖改變總的狀態。這些命令在由Spring的PlatformTransactionManager管理的事務的範圍內。
Command Dispatch同步發生,我需要每秒處理5,000條命令。每個命令都會從緩存中獲取聚合,在其上更改一個值,然後在分派下一個Command之前保持更改。問題是在獲取/更新/插入行時需要時間,考慮到由HYSQL和H2這樣的插入速度所帶來的INSERT速度,我認爲這會更快。
任何想法,以加快速度,我將不勝感激。
感謝
您是否嘗試過不使用緩存?只是爲了看看它是否真的有所作爲?我有類似的東西,並且緩存實際上是在隨時都被刷新的情況下。我刪除了它,並獲得了很多改進的性能。這不是一個答案,只是一個問題:) – Ewald
有趣的 - 刪除緩存沒有任何區別。我仍然在管理500次寫入,沒有緩存。 – totalcruise
這很有趣,不是嗎?也許這個問題也應該是爲什麼緩存沒有什麼區別。這不幸超出了我的專業知識。 – Ewald