多个Actors写入同一个文件+旋转

时间:2011-03-07 01:46:37

标签: scala thread-safety webserver

我在Scala中编写了一个非常简单的Web服务器(基于Actors)。目的 从我们的前端服务器记录事件(例如,如果用户点击一个。) 按钮或页面已加载)。该文件需要每64-100mb左右旋转一次 它将被发送到s3,以便以后使用Hadoop进行分析。流量将 约50-100个电话

我脑子里浮现出一些问题:

  1. 如何确保所有actor都能以线程安全的方式写入一个文件?
  2. 在X量为mb之后旋转文件的最佳方法是什么。我应该这样做吗? 在我的代码或文件系统中(如果我从文件系统中执行此操作,我该如何验证 该文件不在写入的中间或刷新缓冲区)

2 个答案:

答案 0 :(得分:7)

一种简单的方法是使用单个文件编写器actor将所有写入序列化到磁盘。然后,您可以拥有多个请求处理程序actor,它们在从前端服务器处理日志记录事件时为其提供更新。您仍然可以在请求处理中获得并发,同时仍然将写入序列化到日志文件中。拥有多个actor会打开并发写入的可能性,这最多会损坏您的日志文件。基本上,如果你想在actor模型中使用某些东西是线程安全的,那么它应该在一个actor上执行。不幸的是,在写入磁盘时,您的任务本质上是串行的。你可以做更多涉及的事情,比如在轮换时来自多个演员的合并日志文件,但这看起来有点过分。除非你在一两秒钟内产生64-100MB,否则如果执行I / O的额外线程给你买了任何东西,我会感到惊讶。

假设有一个写作演员,计算自上次旋转以来写入的数量是非常微不足道的,我不认为跟踪演员的内部状态与轮询文件系统会产生不同的影响。

答案 1 :(得分:0)

U可以使用Only One Actor来编写来自不同线程的每个请求,因为所有请求都通过这个actor,不存在并发问题。

根据文件写入滚动,如果您的写入请求可以逐行记录,那么您可以求助于log4j或logback的FileRollingAppender事物。否则,只要在执行任何删除或更新操作之前记住锁定文件,您就可以编写自己的文件。

滚动通常意味着您将旧文件和当前文件重命名为其他名称,然后使用当前文件名创建一个新文件,最后,您始终可以使用当前文件名写入该文件。