ehcache源码学习笔记(1)store实现

 

 enchache缓存的store主要在org.sf.ehcache.store包下:该包下有七个类或接口

  1. Store.java:存储抽象接口
  2. ---MemoryStore.java :将缓存数据保存到内存中
  3. ----FifoMemoryStore.java :先进先出策略缓存置换
  4.  ----LruMemoryStore.java:最近最久为使用策略
  5.  ----LfuMemoryStore.java:最不经常使用策略
  6.  --DiskStore.java:配置了overflowtodisk或diskPersistent后,在需要的时候使用,会将内存中缓存信息保存到硬盘上
  7. MemoryStoreEvictionPolicy.java定义内存存储数据替换策略

简单查看基于MemoryStore的实现四个Field,如下:

 

四个Field中,map就是最终的key-value storer,只不过需要根据缓存置换策略的不同使用不同的Map实现,最终策略的实现也委托给了map中置换策略。这里不做深究,重点我们看一下DiskStore的实现:

先看看DiskStore.java中几个重要Field:

 

1. diskElements 对应于保存到Disk上的Element在内存中的映射,类似于快照的概念

2. freeSpace 保存中diskElement或spoolElement中remove掉的Element,主要用于从文件中删除数据时减少数据在文件内的移动,下次有新数据需要插入有限从这些freespace中获取合适大小的空间

3. spool为缓冲池,缓存需要flush到disk的element,而不是每次都进行IO

我们先看看put(Element)的实现:

 

 

即:put的时候是往缓冲区仍东西,并没有立刻同步到disk,再看看remove(Element)

 

可见remove需要同时从spool中remove();和从diskElement中remove(),这儿使用了三个同步快,感觉并不能保证操作期间的一致性。

以上的这些,都是在内存里面的操作,现在我们看看他具体讲缓存数据flush到disk的过程: 

即最终通过java的序列化机制结合RandomAccessFile将cached对象的信息保存到disk,从而为下一次服务器启动overflowtodisk的缓存数据能够return back。并且最后, diskElements.put(key, diskElement);标志了flush到disk去也需要同步到diskElements对象中去,以保证Disk中数据和其在内存中的快照数据保持一致。

接下来比较关注的一点就是放到spool中的数据何时flush到disk上了: 

即开启一个守护线程,每隔指定时间将spool中的缓存数据flush到disk,并且该守护线程优先级2低于普通线程,故只有再服务器不忙的时候才有可能执行。

最后在看看合disk对应的dataFile和indexFile两个field,可以发现前者对应所有flush到disk的element,后者保存了diskElements和freeSpace两个对象的序列化后信息,在服务器下次启动的时候能够直接反序列化回来,从而不需要读取dataFile逐个DiskElement反序列化。

另外还有一个缓存数据过期清除的线程,也是后台守护线程定时执行,从disk及DiskElement、spool中清除过期数据,释放空间。

问题:

1. 为什么不直接对定时将快照Map diskElements flush到disk ,有点直接使用indexFile的意思,而不需要dataFile?难道原因是序列化一个大的Map消耗较大或者比较耗时(这个还真是不知道)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值