java最快的SSD并发随机文件读/写方法,无需内存交换

标签 java file random solid-state-drive

我有一个 Linux 盒子,配备 32GB 内存和一组 4 个 SSD,采用 raid 0 配置,最大吞吐量约为 1GB(随机 4k 读取),我正在尝试确定访问其上文件的最佳方式随机并发地使用java。到目前为止,我看到的两种主要方法是通过随机访问文件和映射直接字节缓冲区。

这就是它变得棘手的地方。我有自己的对象内存缓存,因此对存储在文件中的对象的任何调用都应该通过磁盘而不是分页内存(我已经禁用了 Linux 机器上的交换空间以防止这种情况发生)。虽然映射的直接内存缓冲区被认为是最快的,但它们依赖于交换,这不好,因为A)我将所有可用内存用于对象缓存,而使用mappedbytebuffers会产生大量的序列化开销,这就是对象缓存的目的(我的程序已经受到CPU限制)B)使用mappedbytebuffers,操作系统处理数据写入磁盘时的细节,我需要自己控制它,即。当我写入(byte[])时,它会立即直接写入磁盘,这是为了防止断电时数据损坏,因为我没有使用 ACID 事务。

另一方面,我需要大量并发,即。我需要同时读取和写入同一文件中的多个位置(同时使用偏移/范围锁来防止数据损坏)我不确定如何在没有映射字节缓冲区的情况下做到这一点,我总是可以查询读取/写入,但我不确定这会对我的吞吐量产生怎样的负面影响。

最后,当我创建新的 byte[] 对象进行读取或写入时,我不能遇到这种情况,这是因为我每秒执行几乎 100000 次读/写操作,分配和垃圾收集所有这些对象会杀死我的程序这是时间敏感的并且已经受到 CPU 限制,重用 byte[] 对象是可以的。

请不要推荐任何数据库软件,因为我已经尝试过其中的大多数软件,它们会增加很多复杂性和 CPU 开销。

有人遇到过这样的困境吗?

最佳答案

Whilst mapped direct memory buffers are supposedly the fastest they rely on swapping

不,如果你有足够的内存就不会。该映射将内存中的页面与磁盘上的页面相关联。除非操作系统决定需要恢复 RAM,否则页面不会被换出。如果您的 RAM 不足,禁用交换只会导致 fatal error ,而不是性能下降。

I am using all the free memory for the object cache

除非你的对象生命周期非常长,否则这是一个坏主意,因为垃圾收集器在运行时必须做很多工作。您经常会发现较小的缓存会带来较高的整体吞吐量。

with mappedbytebuffers the OS handles the details of when data is written to disk, I need to control this myself, ie. when I write(byte[]) it goes straight out to disk instantly

实际上,它不会,除非您使用 sync 选项挂载了文件系统。然后,您仍然面临因驱动器故障(尤其是在 RAID 0 中)而导致数据丢失的风险。

I'm not sure how I can do this without mappedbytebuffers

RandomAccessFile 将执行此操作。但是,您将在每次写入时至少支付一次内核上下文切换费用(如果您为同步写入安装了文件系统,则每次写入都将涉及磁盘往返)。

I am not using ACID transactions

那么我想这些数据并没有那么有值(value)。因此,无需担心有人会被电源线绊倒。

关于java最快的SSD并发随机文件读/写方法,无需内存交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14880878/

相关文章:

java - 代码中的计算给出了奇数答案,小数点旁边有很多数字

Java 字符串 replaceAll()

python - 如何让python不断保存文件io

python - 我如何在Python中获得一个随机日期以及3天后的日期?

css - 如果我想随机化颜色,但在随机化发生时使用 onload 方法制作了一组颜色,该怎么办?

Websphere 管理控制台的 Java 堆空间内存不足

JAVA 在每次出现特定符号时在字符串中换行

java - 什么会导致这种 Java 行为?

python - 为什么 open ('file' ,'w' ) 说文件不存在?

c# - 随机位置的字符