寻找java.util.Map的替代品

Mat*_*all 13 java caching hadoop berkeley-db ehcache

问题

关注这个问题,似乎基于文件或磁盘的Map实现可能是我在那里提到的问题的正确解决方案.精简版:

  • 现在,我已经Map实现了一个ConcurrentHashMap.
  • 条目以相当固定的速率不断添加到其中.稍后详情.
  • 最终,无论如何,这意味着JVM耗尽了堆空间.

在工作中,(强烈)建议我使用SQLite解决这个问题,但在询问上一个问题之后,我认为数据库不是这项工作的正确工具.所以 - 让我知道这听起来有多疯狂 - 我认为更好的解决方案是Map存储在磁盘上.

不好的主意:自己实现这个.更好的主意:使用别人的图书馆!哪一个?

要求

必备:

  • 自由.
  • 持久性.数据需要在JVM重启之间保持不变.
  • 某种可搜索性.是的,我需要能够检索这些数据以及将其丢弃.基本结果集过滤是一个加号.
  • 与平台无关.需要在Windows或Linux计算机上进行生产部署.
  • 可以清除.磁盘空间是有限的,就像堆空间一样.我需要摆脱n几天前的条目.如果我必须手动执行此操作,这不是什么大问题.

尼斯对富人:

  • 使用方便.如果我能在本周末完成这项工作,那就太好了.
    更好的是:一天结束.这将是非常,非常巨大的,如果我能一个JAR添加到我的类路径,改new ConcurrentHashMap<Foo, Bar>();new SomeDiskStoredMap<Foo, Bar>();
    和完成.
  • 体面的可扩展性和性能.最坏的情况:新的条目(平均)每秒增加3次,每秒,每天,每天.但是,插入并不总是顺利发生.可能就是(no inserts for an hour)这样(insert 10,000 objects at once).

可能的解决方案

Ehcache和Berkeley DB现在看起来都很合理.任何方向的任何特定建议?

har*_*are 8

更新(首次发布后约4年......):请注意,在较新版本的ehcache中,缓存项的持久性仅在付费产品中可用.谢谢@boday指出这一点.

ehcache很棒.它将为您提供在内存,磁盘或内存中实现映射以及溢出到磁盘所需的灵活性.如果你使用这个非常简单的java.util.Map包装器,那么使用它非常简单:

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;

import org.apache.log4j.Logger;

import com.google.common.collect.Sets;

public class EhCacheMapAdapter<K,V> implements Map<K,V> {
    @SuppressWarnings("unused")
    private final static Logger logger = Logger
            .getLogger(EhCacheMapAdapter.class);

    public Cache ehCache;

    public EhCacheMapAdapter(Cache ehCache) {
        super();
        this.ehCache = ehCache;
    } // end constructor

    @Override
    public void clear() {
        ehCache.removeAll();
    } // end method

    @Override
    public boolean containsKey(Object key) {
        return ehCache.isKeyInCache(key);
    } // end method

    @Override
    public boolean containsValue(Object value) {
        return ehCache.isValueInCache(value);
    } // end method

    @Override
    public Set<Entry<K, V>> entrySet() {
        throw new UnsupportedOperationException();
    } // end method

    @SuppressWarnings("unchecked")
    @Override
    public V get(Object key) {
        if( key == null ) return null;
        Element element = ehCache.get(key);
        if( element == null ) return null;
        return (V)element.getObjectValue();
    } // end method

    @Override
    public boolean isEmpty() {
        return ehCache.getSize() == 0;
    } // end method

    @SuppressWarnings("unchecked")
    @Override
    public Set<K> keySet() {
        List<K> l = ehCache.getKeys();
        return Sets.newHashSet(l);
    } // end method

    @SuppressWarnings("unchecked")
    @Override
    public V put(K key, V value) {
        Object o = this.get(key);
        if( o != null ) return (V)o;
        Element e = new Element(key,value);
        ehCache.put(e);
        return null;
    } // end method


    @Override
    public V remove(Object key) {
        V retObj = null;
        if( this.containsKey(key) ) {
            retObj = this.get(key);
        } // end if
        ehCache.remove(key);
        return retObj;
    } // end method

    @Override
    public int size() {
        return ehCache.getSize();
    } // end method

    @Override
    public Collection<V> values() {
        throw new UnsupportedOperationException();
    } // end method

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        for( K key : m.keySet() ) {
            this.put(key, m.get(key));
        } // end for
    } // end method
} // end class
Run Code Online (Sandbox Code Playgroud)


Rid*_*del 5

你有没有听说过流行框架?

编辑对该术语的一些澄清.

就像James Gosling现在所说的那样,没有SQL DB像内存存储一样高效.流行框架(最常见的是prevaylerspace4j)建立在内存上,可能存储在磁盘上的存储上.他们是如何工作的?事实上,它看似简单:存储对象包含所有持久性实体.此存储只能通过可序列化操作进行更改.因此,将对象放入存储器是在隔离的上下文中执行的Put操作.由于此操作是可序列化的,因此它可以(取决于配置)也保存在磁盘上以实现长期持久性.然而,主数据存储库是存储器,其以高内存使用为代价提供了无疑的快速访问时间.

另一个优点是,由于它们非常简单,这些框架几乎不包含十分之一的类

考虑到你的问题,我立即想到了Space4J的使用(因为它提供了对很少使用的对象的"钝化"的支持,也就是说它们的索引键在内存中,但是只要它们是对象就保存在磁盘上不曾用过).

请注意,您还可以在c2wiki上找到一些信息.

  • 实际上,在最新版本中从框架中删除了钝化.但它确实支持透明的集群和索引.看看:http://forum.space4j.org/posts/list/5.page (2认同)