我有一个带有 32GB ram 和一组 4 个 SSD 的 linux 机器,在 raid 0 配置中,最大吞吐量约为 1GB(随机 4k 读取),我正在尝试确定随机并同时访问文件的最佳方式使用java。到目前为止,我看到的两种主要方式是通过随机访问文件和映射的直接字节缓冲区。
这是它变得棘手的地方。我有自己的对象内存缓存,因此对存储在文件中的对象的任何调用都应该通过磁盘而不是分页内存(我已禁用我的 linux 机器上的交换空间以防止这种情况发生)。虽然映射的直接内存缓冲区被认为是最快的,但它们依赖于交换,这并不好,因为 A)我将所有空闲内存用于对象缓存,而使用映射字节缓冲区会产生大量的序列化开销,这就是对象缓存的存在防止。(我的程序已经受 CPU 限制) B)使用映射字节缓冲区,操作系统处理数据何时写入磁盘的详细信息,我需要自己控制它,即。当我 write(byte[]) 时,它会立即直接输出到磁盘,这是为了防止电源故障时数据损坏,因为我没有使用 ACID 事务。
另一方面,我需要大量并发,即。我需要同时读取和写入同一个文件中的多个位置(同时使用偏移/范围锁来防止数据损坏)我不确定如果没有映射字节缓冲区我怎么能做到这一点,我总是可以查询读取/写,但我不确定这会对我的吞吐量产生什么负面影响。
最后,当我为读取或写入创建新的 byte[] 对象时,我不会遇到这种情况,这是因为我每秒执行几乎 100000 次读取/写入操作,分配和垃圾收集所有这些对象会杀死我的程序,这是时间敏感且已经受到 CPU 限制,重用 byte[] 对象就可以了。
请不要推荐任何数据库软件,因为我已经尝试过其中的大多数软件,它们增加了很多复杂性和 CPU 开销。
有人遇到过这种困境吗?