我需要将记录存储到持久存储中并按需检索它。要求如下:
你们觉得怎么样?由于延迟问题,我无法使用标准数据库。像HSQLDB / H2这样的内存数据库具有性能约束。此外,记录是简单的字符串对象,不符合SQL条件。我正在考虑某种基于平面文件的解决方案。有任何想法吗?任何开源项目?我相信,必须有人在此之前解决了这个问题。
答案 0 :(得分:7)
有许多不同的工具和方法,但我认为它们都不能满足所有要求。
对于低延迟,您只能依赖内存数据访问 - 磁盘在物理上太慢(以及SSD也是如此)。如果数据不适合单个机器的内存,我们必须将数据分配给更多节点,总结足够的内存。
对于持久性,我们必须将数据写入磁盘。假设最佳组织 这可以作为后台活动完成,而不会影响延迟。 但是对于可靠性(故障转移,HA或其他),磁盘操作不能完全独立于访问方法:我们必须在修改数据时等待磁盘以使shure我们的操作不会消失。 并发也会增加一些复杂性和延迟。
数据模型不限制此处:大多数方法都支持基于唯一键的访问。
我们必须决定,
解决方案可能
可以找到NoSQL工具列表,例如。 here。
Voldemort的performance tests报告亚毫秒响应时间,这些可以很容易地实现,但我们也必须小心硬件(如上面提到的网络属性)。
答案 1 :(得分:5)
答案 2 :(得分:4)
如果所有数据都适合内存,MySQL可以在内存而不是磁盘(MySQL Cluster,Hybrid Storage)中运行。然后它可以为您处理将自己存储到磁盘。
答案 3 :(得分:4)
像CouchDB这样的东西呢?
答案 4 :(得分:3)
我会使用 BlockingQueue 。 简单,内置于Java
我使用芝加哥商品交易所的实时数据做类似的事情
数据被发送到一个地方供实时使用......并发送到另一个地方(通过TCP),
使用BlockingQueue(生产者/消费者)将数据持久保存到数据库(Oracle,H2)
消费者使用延迟提交来避免数据库中 fdisk同步问题。
(默认情况下H2类型数据库是异步提交并避免该问题)
我记录持续存在于消费者中以跟踪队列大小以确保
它能够跟上制作人的步伐。对我来说效果很好。
答案 5 :(得分:2)
在内存数据库中也是一个好主意。实际上MySQL也提供了基于内存的表。
答案 6 :(得分:2)
Tuple space / JavaSpace会有效吗?另请查看其他企业数据结构,例如Oracle Coherence和Gemstone。
答案 7 :(得分:1)
您是否真的证明使用像MySQL或SQL Server这样的进程外SQL数据库太慢,或者这是假设?
您可以将SQL数据库方法与内存缓存结合使用,以确保检索根本不会访问数据库。尽管记录是纯文本的,但我仍然建议在平面文件解决方案中使用SQL(例如,在表模式中使用文本列),因为RDBMS将执行文件系统无法进行的优化(例如,缓存最近访问的页面等)
但是,如果没有关于您的访问模式,预期吞吐量等的更多信息,我无法提供更多建议。
答案 8 :(得分:1)
如果你输掉一两个记录多少钱?他们来自哪里?您与来源有交易关系吗?
如果您有严格的可靠性要求,那么我认为您可能需要准备支付一些DB开销。
也许您可以将持久性问题与内存中的问题分开。使用pup-sub方法。一个用户在内存中寻找,另一个用户为后续启动保留数据?
如果您可以购买而不是构建,那么WebSphere eXtreme Scale(没有Java EE依赖性)等分布式cahcing产品可能会相关。
答案 9 :(得分:1)
如果在发生崩溃的情况下丢失了几个条目会有多糟糕?
如果不是那么糟糕,以下方法可能适合您:
为每个条目创建平面文件,文件名等于id。对于不那么多连续条目的可能的一个文件。
确保您的控制器具有良好的缓存和/或使用Java中实现的现有缓存之一。
与文件系统专家交谈如何快速实现这一目标
这很简单,也可能很快。 当然,你会失去交易,包括ACID原则。
答案 10 :(得分:1)
如果您正在寻找一个简单的键值存储,并且不需要复杂的SQL查询,Berkeley DB可能值得一看。
另一个替代方案是Tokyo Cabinet,一个现代DBM实现。
答案 11 :(得分:1)
亚毫秒的r / w意味着你不能依赖磁盘,你必须小心网络延迟。忘记基于标准SQL的解决方案,主存还是不存在。在ms中,您不能在GBit网络上获得超过100 KB的空间。问一位电信工程师,他们习惯于解决这些问题。
答案 12 :(得分:1)
MapDB提供持久保存到磁盘的高性能HashMaps / TreeMaps。它是一个可以嵌入Java程序的库。
答案 13 :(得分:0)
Chronicle Map是一个ConcurrentMap
实现,它将密钥和值存储在内存映射文件中。所以你有持久的JVM重启。
ChronicleMap.get()
始终快于1 us,有时快达100 ns /操作。它是班上的the fastest解决方案。
答案 14 :(得分:-1)
您需要的所有记录和密钥是否同时适合内存?如果是这样,你可以使用HashMap< String,String>,因为它是Serializable。