映射在不同JVM之间共享

时间:2017-03-08 22:31:54

标签: java dictionary concurrency

我需要java.util.Map的实现,可以在不同主机上的不同JVM之间共享。所有主机(以及JVM)都可以访问相同的共享文件系统,所以我需要这样的东西:

Map<String,String> sharedMap = new SharedMapInFile("/shared/mymap.map");

我已经看了一下MapDB(http://www.mapdb.org/),但是不支持在不同的JVM之间共享(参见:https://groups.google.com/forum/#!topic/mapdb/VKVy84MZJko)。

有什么想法吗? TIA!

2 个答案:

答案 0 :(得分:1)

如果您的共享文件系统可以将映射文件利用到操作系统级别的内存中,那么

Chronicle Map可以做到这一点。 E. g:

Map<String, String> sharedMap = ChronicleMap
    .of(String.class, String.class)
    .averageKey(...).averageValue(...)
    .entries(...)
    .createPersistedTo(new File("/shared/mymap.map"));

这可能很方便,但效率很低,因为每个Map.put()操作需要通过网络发送3页12k字节。另外,请注意,如果操作系统没有将映射的内存长时间写回到编写器主机上的文件系统,那么将一个条目放在一个主机上的映射和能够在另一个主机上读取该条目之间的延迟可能会很高。 。请参阅Linux中的/proc/sys/vm/dirty_expire_centisecs

因此,在主机之间建立直接网络连接(例如使用Netty)并仅发送密钥和值可能会更有效率,尽管这是一种不太方便的解决方案。

答案 1 :(得分:0)

您可以使用数据库作为“地图”来实现此目的。它执行共享地图的功能,并且非常有效。如果需要,您可以轻松创建一个实现&#39; Map&#39;接口,以便它可以像HashMap一样使用(如果需要这样的东西)。

Sqlite对此很好,因为它创建了一个简单的文件,如果您在共享文件系统上,则可以访问该文件(但要注意它并不能很好地处理并发问题)。任何其他数据库,如MySQL或Postgres也可以实现这一点(并具有更好的并发性)。以下是使用Sqlite的示例:

Class.forName("org.sqlite.JDBC");
String connectTo = "jdbc:sqlite:"+myDbName; //filename goes here
java.sql.Connection conn = DriverManager.getConnection(connectTo);

Statement st = conn.createStatement()
ResultSet result = st.executeQuery("select value from tablename where key='myKey'"); //ie some sql statement that gets what you need
result.getString(1);
and so on...