多个 Xodus 应用到 access/share 单个目录

Multiple Xodus app to access/share single directory

根据这个 post

的评论

"I have xodus directory I wan to share between two applications.. But one with read /write access and other with read-only access.. Is the any other way to create Environment apart from Environments.newInstance("xodusDir"); for read-only access to xodus database.. I need only read only access to xodus from other application.."

回答

"This would be possible with upcoming version 1.3.0."

这是否意味着可以有多个进程创建指向同一目录的环境/持久存储:

  Environment environment = getEnvironment(xodusRoot, dir);
  final PersistentEntityStore store = PersistentEntityStores.newInstance(environment);

使用此拓扑:

这可能吗,或者有解决方法吗?

据我所知,xd.lck 阻止两个实例访问同一个 Xodus 目录。

从版本 1.3.0 开始,您可以在 read-only 模式下打开数据库而忽略锁:

final EnvironmentConfig config = new EnvironmentConfig().
            setLogDataReaderWriterProvider("jetbrains.exodus.io.WatchingFileDataReaderWriterProvider").
            setLogCacheShared(false).
            setMemoryUsagePercentage(1);
final Environment env = Environments.newInstance(dir, config);
final PersistentEntityStore store = PersistentEntityStores.newInstance(env);

它不仅会忽略锁,还会使用java.nio.file.WatchService自动获取新数据。

一个实例Environment/EntityStore可以像往常一样打开(主要),也可以像上面那样打开多个实例(次要)。您的代理服务器应正确分配流量,以便辅助实例不会收到写入请求。显然,您的应用程序必须解决此类架构无法避免的最终一致性问题。

可以在任何JVM 中打开辅助实例。如果您在用于打开主实例的同一 JVM 中打开辅助实例,请注意内存使用情况,因为辅助实例不使用共享日志缓存。主实例(如果不使用 setMemoryUsagePercentage)可以消耗最大堆内存的 50%。如果整体内存使用百分比不超过 50-55% 就很好(尽管这取决于您使用的 GC 和 GC 设置)。

如果您在单独的 JVM 中打开辅助实例,则跳过上面代码中的 setLogCacheSharedsetMemoryUsagePercentage 设置。您唯一需要配置的是监视 DataReaderWriterProvider。

在 1.3.91 版本中,您甚至可以 运行 JVM 在不同主机上使用辅助实例。每个主机都应该在其文件系统上有一个数据库副本,可以按如下方式打开它:

final EnvironmentConfig config = new EnvironmentConfig().
            setLogDataReaderWriterProvider("jetbrains.exodus.io.WatchingFileDataReaderWriterProvider");
final Environment env = Environments.newInstance(dir, config);
final PersistentEntityStore store = PersistentEntityStores.newInstance(env);

您必须对基础架构做的唯一额外事情是提供数据库更改的定期同步。版本 1.3.91 已经过测试,可以在 rsync 上正常工作。在大多数情况下,每 5-10 秒同步一次就可以了,尽管高写入工作负载会导致一些同步延迟。