1

我正在尝试在 linux 平台上的 java 中的大量多线程环境中异步记录。什么是合适的数据结构(无锁)来引入低线程争用?我需要记录 GB 的消息。我需要以异步/无锁方式执行此操作,因此我不会破坏主要逻辑(调用记录器 API 的代码)的性能。

4

5 回答 5

2

Logback 有一个可能满足您需求的 AsyncAppender。

于 2013-01-15T15:09:37.563 回答
1

我会使用Java Chronicle,主要是因为我编写了它,但我建议在这里使用它,因为您可以使用最少的操作系统调用编写无锁和无垃圾日志记录。这需要每个线程一个日志,但我假设您已经将这些保持在最低限度。

我已经使用这个库从两个线程中写入 1 GB/秒。如果日志记录对您来说是一个瓶颈,您可能会发现拥有更多线程并没有您想象的那么大。

顺便说一句:您让我了解了如何从多个线程/进程更新日志,但实施和测试需要一段时间。

于 2013-01-15T15:10:35.153 回答
1

最简单的方法是写入多个文件 - 每个线程一个。

确保将时间戳放在每条记录的开头,这样更容易将它们合并到单个日志文件中。

示例 unix 命令:

cat *.log | sort | less

但是为了获得更好/更有用的答案,您确实需要通过添加更多细节来澄清您的问题。

于 2013-01-15T14:52:34.980 回答
0

避免队列争用是不可能的,因为您的日志线程很可能会比您的写入器(磁盘 i/o)线程可以跟上的速度更快,但是通过一些智能等待策略和线程固定,您可以最大限度地减少延迟并最大限度地提高吞吐量。

看看由 Coral Blocks(我隶属于它)开发的CoralLog ,它使用无锁队列,平均可以在 52 纳秒内记录一条 64 字节的消息。它每秒能够写入超过 500 万条消息。

于 2014-06-12T14:50:47.387 回答
0

为了减少争用,您可以首先将日志消息放在每个线程专用的缓冲区中。当缓冲区已满时,将其放入由单独的日志线程处理的队列中,然后合并来自不同线程的消息并将它们写入文件。请注意,在任何情况下都需要单独的线程,以免在将下一个缓冲区写入磁盘时减慢工作线程。

于 2013-01-16T09:00:26.067 回答