我需要知道是否有任何嵌入式DBMS(最好是Java,不一定是关系型),它支持同一组db文件上的多个编写器应用程序(进程)。 BerkeleyDB supports multiple readers but just one writer.我需要多个作家和多个读者。
更新:
这不是多重连接问题。我的意思是我不需要多个连接到正在运行的DBMS应用程序(进程)来写入数据。我需要多个DBMS应用程序(进程)来提交相同的存储文件。
HSQLDB,H2,JavaDB(Derby)和MongoDB不支持此功能。
我认为可能存在一些禁止此操作的文件系统限制。如果是这样,是否存在允许单个文件上有多个编写器的文件系统?
用例:用例是一个高吞吐量的集群系统,旨在将其高容量业务日志条目存储到SAN存储中。将业务日志存储在每个服务器的单独文件中是不合适的,因为整个业务日志需要查询和索引功能。
因为"a SAN typically is its own network of storage devices that are generally not accessible through the regular network by regular devices",我希望使用SAN网络带宽进行日志记录,同时将群集LAN带宽用于其他服务器到服务器以及客户端到服务器的通信。
答案 0 :(得分:12)
除非你以某种方式改变你的要求,否则你基本上没有运气。
首先,特别是在Unix系统上,没有什么可以阻止多个进程写入相同的文件。在单一系统上,这不会是一个问题,如果两个或多个写入在文件中的相同空间与实际写入的空间发生冲突,您将只有一个典型的竞争条件。由于它在单个系统上,因此在字节级别具有完美的分辨率。
因此,游戏在多个进程写入同一文件方面是如何协调的?如何确保他们不会互相走路。在Unix中,有一个基于操作系统的锁定机制可用于防止这种情况,但通常大多数系统实现一个中央服务器并协调它们通过该系统的所有写入,然后它在写入磁盘的同时减轻和处理任何冲突。
你的问题有两个。
一,你建议独立的日志流程不合作,他们不会共享信息并协调他们对卷的写入。那把扳手(一把大扳手)扔到那里工作。
其次,您建议不仅要将多个进程写入同一个卷,而且要写入的卷通过SAN共享。那是另一个扳手。
与NFS不同,SAN不支持“文件系统”。相反,他们支持“存储”。基本上是块级设备。一旦你通过一堆卷管理恶作剧,SAN实际上从操作系统的角度来看是非常“愚蠢的”。
我很确定你实际上可以在多台机器上安装一个卷,但我不确定是否可以实际写入多个设备。这有很好的理由。
简单来说,SAN是块级存储。例如,一个块是4K字节。这是SAN的“原子”工作单元。想要更改单个字节的数据?从SAN读取4K块,更改字节,然后写回4k块。
如果您有多台计算机认为他们对SAN存储具有“通用”访问权限,并将其视为文件系统,那么您的文件系统已损坏,已损坏。就这么简单。这些机器会在其他机器上写下他们认为块应该是什么样子的东西并用它们的本地版本粉碎它们。灾害。废墟。不开心。
即使让一台机器写入SAN而另一台机器从中读取它也很棘手。它也很慢,因为读者可以对磁盘内容做一些假设,所以它需要读取和重新读取块(它不能缓存任何东西,如文件系统TOC等,因为,它们'由于作家的活动而在它背后重新改变 - 所以,再次阅读......再次......)。
像NFS这样的事情“解决”了这个问题,因为你不再使用原始存储。而是使用实际的文件系统。
最后,将独立日志文件从服务器中流出是没有错的。他们仍然可以被查询。您只需重复查询并合并结果即可。
如果你有5台机器流,并且你想要“在12:00 pm到12:05 pm之间的所有活动”,那么进行5次查询,每个日志存储一次,并合并结果。至于如何有效地查询日志数据,这是一个索引问题,而不是根据您的查询方式无法克服。如果按时间查询,则按时间(每分钟,每小时,等等)创建文件,然后扫描它们。如果您的系统“很少阅读”,这不是什么大问题。如果你需要更复杂的索引,那么你需要提出其他的东西。
您可以使用数据库来编写文件和索引,但我怀疑您会发现许多人喜欢从他们无法控制的文件中读取,或者在其下面进行更改。
CouchDB可能有用,或者类似的东西,因为它具有特定的抗崩溃性,始终是一致的数据库格式。它的数据文件总是可由数据库实例读取。这可能是你的选择。
但我仍然会做多个查询并合并它们。
答案 1 :(得分:7)
让各个进程将其日志传输到单独的文件/数据库以避免损坏。然后,您可以拥有一个守护进程,该进程从所有这些文件/ DB中异步读取并写入单个统一文件/ DB。如果必须索引或查询日志,请在统一文件/ DB上执行。这里唯一的问题是您将无法实时访问日志。在整合日志之前会有一些滞后。
更新了以下详细信息:
------------- ------------- ------------- | | | | | | | Process-1 | | Process-2 | ... | Process-N | | | | | | | ------------- ------------- ------------- | | | | | | V V V ( log-1 ) ( log-2 ) ... ( log-N ) \ \ / \ \ / - - - - \ | / - - - - \ | / \ | - \ | / ||| VVV ------------- | | | Process-X | | | ------------- | V V -------------- V | | ( log-X ) ------>>>| Log Reader | | | --------------
答案 2 :(得分:3)
答案 3 :(得分:3)
尝试FirebirdSQL(原Borland Interbase)。它有“Superserver”和“Classic”模式。前者是传统的多线程数据库服务器,而后者遵循经典的单进程每连接模型。不同的进程主要通过OS级锁定数据文件来协调。据我所知,您可以将经典服务器嵌入到您自己的代码中。您的应用程序将只是一个经典的过程。
http://www.firebirdfaq.org/faq25/
http://www.firebirdfaq.org/Firebird-Embedded-Linux-HOWTO.html
更新:没有读过Java部分。在这种情况下,你可能会对其他任何答案感觉更好。
更新:当我说“锁定”时,我并不是说它会立即锁定整个数据库。即使在经典模式下,它仍然是一个成熟的RDBMS。但是,我不太清楚该软件是否足以说清楚幕后发生了什么。
答案 4 :(得分:2)
H2 Database为fast,似乎是suitable。
答案 5 :(得分:2)
Java DB是Sun支持的开源Apache Derby 100%Java技术数据库的分发版。它完全是事务性的,安全的,易于使用的,基于标准的 - SQL,JDBC API和Java EE - 但很小,只有2.5 MB。
Java DB 包含在 Java SE JDK中,并且是Sun GlassFish Enterprise Server的开发人员数据库。
可以在Client/Server (or even Embedded Server)模式下运行以允许多个连接。
更新:小错误,Java DB不像我最初写的那样是Java SE而是JDK。
更新2:既然问题已经澄清了,我的理解是OP实际上正在寻找类似“共享存储数据库服务器”(和嵌入式)的东西,我实际上并不认为Java DB属于此类别。说实话,我想知道这是否存在。我知道有些数据库集群解决方案使用共享存储(Oracle RAC,DB2),但我不明白这个问题是关于数据库集群的。此外,根据我的知识,此类解决方案无法嵌入。但我会更多地挖掘这一点(并密切关注这个问题)。
答案 6 :(得分:2)
(in-memory)SQLite 3 databases 怎么样?
答案 7 :(得分:1)
2Gregg - Nope,Berkeley DB就是那个嵌入式
2Amir - 正如Alix Axel所说,SQlite值得尝试。
我最近用嵌入式方式测试了上面提到的几个数据库引擎,Java和SQLite全都打败了!在事务中插入/更新的相当大的数据量非常快。不要读那些旧问题。
因此,如果SQLite的锁定和并发适合您,那么请尝试一个。恕我直言,具有多个日志/写入器和单个异步读取器/合并器的模型是唯一合理的解决方案。
答案 8 :(得分:0)
更正:MongoDB支持直接和通过mongos的多路写入器。
答案 9 :(得分:0)
多进程访问(每个进程都相同,可以读写)是Chronicle Map的杀手级功能。从不同进程创建Chronicle Maps时,您应该只指定相同的持久性文件:
ChronicleMap<Key, Value> map = ChronicleMap
.of(Key.class, Value.class)
.entries(...)
...
.createPersistedFile(sharedDbFile); // <- here
如果您没有这样的持久性,则应将此文件放在Linux中的tmpfs或/dev/shm/
目录中。并发/进程间访问不受此影响。
除了具有多进程访问功能外,Chronicle Map通常具有非常好的并发属性,因为它使用锁定条带化和多级锁定。