我正在尝试读取日志文件并解析它只消耗CPU。我有一个服务器读取230MB /秒的巨大文本文件,只读取文本文件不解析。当我尝试解析文本文件时,使用单线程,我可以解析文件大约50-70MB /秒。
我想提高吞吐量,实现并发工作。在此代码中,我达到130 MB /秒。在高峰期,我看到190MB /秒。我尝试过BlockedQueue,Semaphore,ExecutionService等。你有什么建议让我达到200MB /秒的吞吐量。
import { Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators} from '@angular/forms';
import { Location } from '@angular/common';
constructor(public location: Location,public fb:FormBuilder,public global_service:GlobalService,public router: Router) {
}
答案 0 :(得分:1)
您可能会受益于Java 8中引入的Files.lines()
方法和Stream范例。它将使用系统公共fork / join池。试试这个模式:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class LineCounter
{
public static void main(String[] args) throws IOException
{
Files.lines(Paths.get("/your/file/here"))
.parallel()
.forEach(LineCounter::processLine);
}
private static void processLine(String line) {
// do the processing
}
}
答案 1 :(得分:0)
假设你不在乎线的顺序:
final String MARKER = new String("");
BlockingQueue<String> q = new LinkedBlockingDeque<>(1024);
for (int i = 0; i < concurrency; i++)
executorService.execute(() -> {
for (;;) {
try {
String s = q.take();
if(s == MARKER) {
q.put(s);
return;
}
reader.splitNginxLinewithIntern(s);
} catch (InterruptedException e) {
return;
}
}
});
String line;
while ((line = reader.readLine()) != null) {
q.put(line);
}
q.put(MARKER);
executorService.awaitTermination(10, TimeUnit.MINUTES);
这会启动许多线程,每个线程都运行一个特定的任务;该任务是从队列中读取并运行split方法。读者只需输入队列,通知它何时完成并等待终止。
如果您要使用RxJava2和rxjava2-extras,那只是
Strings.from(reader)
.flatMap(str -> Flowable
.just(str)
.observeOn(Schedulers.computation())
.doOnNext(reader::splitNginxLinewithIntern)
)
.blockingSubscribe();
答案 2 :(得分:0)
你需要多线程,你需要让读者线程将解析委托给工作线程,这是明确的。关键是如何以尽可能少的开销进行委托。
@Tassos提供的代码看起来像是一个可靠的改进。
您可以尝试的另一件事是更改委派粒度,而不是单独委派每一行,而是构建例如100行,从而将委派/同步开销减少了100倍(但后来需要一个String []数组或类似的,这不应该太大)。