首页 > 编程知识 正文

ehcache缓存原理(hibernate一级缓存二级缓存)

时间:2023-05-06 07:21:14 阅读:71639 作者:3750

本文仅介绍磁盘缓存方法

hibernate运行sql,将数据转换为映射的实体类,然后缓存数据。 现在,当调用abstractrowreader # performtwophaseload方法时,数据集将循环并返回TwoPhaseLoad.initializeEntity (; 此方法调用ehcache的put方法来缓存数据。

此时,ehcache将put数据实例(数据实例转换为Element实例对象)填满内存缓存,并根据在ehcache.xml中设置的策略将该数据实例转换为磁盘

Cache.class

/* * putanelementinthecache.* p/* resetstheaccessstatisticsontheelement,whichwouldbethecaseifithaspreviouslybeen * gottttion andisnowbeingputback.* p/* alsonotifiesthecacheeventlistenerthat : * ul * litheelementwasput, utonlyiftheelementwasactuallyput.* liiftheelementexistsinthecache,that an update has occurred, eveniftheelementwouldbeexpired * ifitwasrequested */ul * cacheswhichusesynchronousreplicationcanthrowremotecacheexceptionhereifthereplicationtotheclusterfails.* thisexceptionshouldbecaughtinthosecircumstances.* * @ paramelementacacheelement.ifserializableitcanfulllyparticipateinrepateinreplireplilient 代码空/代码or the key is代码空/代码, itisignoredasanoop.* @ paramdonotnotifycachereplicatorswhethertheputiscomingfromadonotnotifycachereplicatorschepeer, inwhichcasethisputshouldnotinitiatea * furthernotificationtodonotnotifycachereplicatorscachepeers * @ throwsillegalstateexceptionifthecacheisnot { @ link status # status _ alive } * @ throwsillegalargumentexceptioniftheelement privatevoidputinternal (elementelement,蓝牙复制程序,引导程序. backOffIfDiskSpoolFull (; 判断buffer是否已满element.updateUpdateStatistics; 布尔元素排除=假; if (usecachewriter (/usecachewriter=false……) else ) /最终调用DiskStore.put方法将数据添加到磁盘elementExists=! compoundstore.put(element; 通告程序互联网列表器(element,doNotNotifyCac

heReplicators, elementExists); } putObserver.end(elementExists ? PutOutcome.UPDATED : PutOutcome.ADDED); }/** * wait outside of synchronized block so as not to block readers * If the disk store spool is full wait a short time to give it a chance to * catch up. * todo maybe provide a warning if this is continually happening or monitor via JMX */ private void backOffIfDiskSpoolFull() { // 若基于内存,调用的是MemoryStore的bufferFull方法,此方法直接返回false // 若基于内存+磁盘,调用的是DiskStorageFactory的bufferFull方法 if (compoundStore.bufferFull()) { // back off to avoid OutOfMemoryError try { Thread.sleep(BACK_OFF_TIME_MILLIS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }}

 

// 计算队列大小 diskSpoolBufferSizeMB * 1024 * 1024this.queueCapacity = cache.getCacheConfiguration().getDiskSpoolBufferSizeMB() * MEGABYTE; /** * 判断缓存是否已满 * Return {@code true} if the disk write queue is full. * * @return {@code true} if the disk write queue is full.*/public boolean bufferFull() { //diskQueue表示DiskWriter线程池(ScheduledThreadPoolExecutor)中的队列DelayedWorkQueue //elementSize表示Element实例序列化后的字节大小 return (diskQueue.size() * elementSize) > queueCapacity;}

     等sleep结束后,调用DiskStore.put方法将Element转化为PlaceHolder,添加到DiskStore中,并在添加完成后调用PlaceHolder的installed()方法,installed()方法会使用DiskStorageFactory schedule一个PersistentDiskWriteTask,将该PlaceHolder写入到磁盘(在DiskStorageFactory有一个DiskWriter线程池会在一定的时候执行该Task)生成一个DiskMarker,释放PlaceHolder占用的内存。在从DiskStore移除一个Element时,它会先读取磁盘中的数据,将其解析成Element,然后释放这个Element占用的磁盘空间,并返回这个被移除的Element。在从DiskStore读取一个Element时,它需要找到DiskStore中的DiskSubstitute,对DiskMarker读取磁盘中的数据,解析成Element,然后返回。

ehcache.xml配置参数含义:

maxElementsInMemory:内存中允许存储的最大的元素个数,0代表无限个clearOnFlush:内存数量最大时是否清除。eternal :设置缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。根据存储数据的不同,例如一些静态不变的数据如省市区等可以设置为永不过时timeToIdleSeconds : 设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。timeToLiveSeconds :缓存数据的生存时间(TTL),也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。overflowToDisk :内存不足时,是否启用磁盘缓存。maxEntriesLocalDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。maxElementsOnDisk:硬盘最大缓存个数。diskPersistent:是否在VM重启时存储硬盘的缓存数据。默认值是false。diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 官方解释:This is the size to allocate the DiskStore for a spool buffer. Writes are madeto this area and then asynchronously written to disk. The default size is 30MB.Each spool buffer is used only by its cache. If you get OutOfMemory errors considerlowering this value. To improve DiskStore performance consider increasing it. Trace levellogging in the DiskStore will show if put back ups are occurring.

若遇到加载数据过慢(一般情况下是因为在同一时间 调用hibernate获取数据过大,然后hibernate调用ehcache二级缓存进行数据缓存时,ehcache判断队列中的元素已超过buffer限制,产生了sleep,造成加载数据过慢的现象),需扩大diskSpoolBufferSizeMB值

 

参考:Java Cache-EHCache系列之Store实现

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。