Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无内存交换SSD的java最快并发随机文件R/W方法_Java_File_Random_Solid State Drive - Fatal编程技术网

无内存交换SSD的java最快并发随机文件R/W方法

无内存交换SSD的java最快并发随机文件R/W方法,java,file,random,solid-state-drive,Java,File,Random,Solid State Drive,我有一个带有32GB ram的linux机箱和一组4个SSD的raid 0配置,最大吞吐量约为1GB(随机4k读取),我正在尝试确定使用java随机访问其中文件的最佳方式。到目前为止,我看到的两种主要方式是通过随机访问文件和映射的直接字节缓冲区 然而,这就是问题的症结所在。我有自己的对象内存缓存,因此对存储在文件中的对象的任何调用都应该通过磁盘而不是分页内存(我已禁用linux设备上的交换空间以防止出现这种情况)。虽然映射的直接内存缓冲区被认为是最快的,但它们依赖于交换,这并不好,因为A)我正在

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

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

另一方面,我需要大量的并发性,即我需要同时读取和写入同一文件中的多个位置(同时使用偏移量/范围锁防止数据损坏),我不确定如果没有MappedBytebuffer,我怎么能做到这一点,我总是可以对读/写操作进行查询,但我不确定这将如何对吞吐量产生负面影响

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

请不要建议使用任何DB软件,因为我已经试用了它们中的大多数,它们会增加很多复杂性和cpu开销


有人遇到过这种困境吗?

你对映射字节缓冲区的反对意见站不住脚。映射文件将不同于对象缓存,尽管它们占用地址空间,但不会占用RAM。您还可以随时同步映射的字节缓冲区(以牺牲某些性能为代价)。此外,随机访问文件最终会在封面下使用相同的设备,因此无法在那里保存任何性能


如果映射字节缓冲区无法获得所需的性能,则可能必须绕过文件系统,直接写入原始分区(DBMS就是这么做的)。要做到这一点,您可能需要编写C++代码来处理数据,并通过JNI访问。< / P> < P>您对映射字节缓冲区的异议不成立。映射文件将不同于对象缓存,尽管它们占用地址空间,但不会占用RAM。您还可以随时同步映射的字节缓冲区(以牺牲某些性能为代价)。此外,随机访问文件最终会在封面下使用相同的设备,因此无法在那里保存任何性能

如果映射字节缓冲区无法获得所需的性能,则可能必须绕过文件系统,直接写入原始分区(DBMS就是这么做的)。要做到这一点,您可能需要编写C++代码来处理数据,并通过JNI访问。 虽然映射直接内存缓冲区被认为是最快的,但它们依赖于交换

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

我正在使用对象缓存的所有可用内存

除非您的对象寿命非常长,否则这是一个坏主意,因为垃圾收集器在运行时需要做大量工作。您经常会发现,缓存越小,总体吞吐量就越高

使用MappedByteBuffer,操作系统处理数据写入磁盘的细节,我需要自己控制,即当我写入(字节[])时,数据立即直接进入磁盘

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

我不知道如果没有Mappedbytebuffer我怎么能做到这一点

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

我没有使用ACID事务

那么我想这些数据并没有那么有价值。所以,不要担心有人会被电源线绊倒

虽然映射直接内存缓冲区被认为是最快的,但它们依赖于交换

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

我正在使用对象缓存的所有可用内存

除非您的对象寿命非常长,否则这是一个坏主意,因为垃圾收集器在运行时需要做大量工作。您经常会发现,缓存越小,总体吞吐量就越高

使用MappedByteBuffer,操作系统处理数据写入磁盘的细节,我需要自己控制,即当我写入(字节[])时,数据立即直接进入磁盘

事实上,它不会,除非您已经用