解决生产中与 ResourceT 相关的空间泄漏问题

主要观点:在使用 Haskell 时可能会出现空间泄漏问题,尤其在 AWS Lambda 函数中。通过一系列实验和分析,找到了 amazonka 库中导致空间泄漏的原因,并创建了最小重现器来证明和修复该问题。
关键信息

  • 观察到 Lambda 函数因内存不足而失败,内存分配为 1GB,但工作与内存利用之间存在很大差异。
  • 在 Docker 容器中 free 命令显示的是主机系统的内存大小,怀疑 AWS Lambda 函数中运行时系统读取的内存限制不正确。
  • 增加 Lambda 函数内存并添加 RTS 选项后仍出现内存不足问题,通过事件日志分析定位到 amazonka 库中的问题。
  • amazonkaSendTaskSuccess API 的实现导致在部分响应读取后未释放资源,从而引发空间泄漏。
  • 创建最小重现器来验证理论,提出两种修复方式,已向 snoyberg/http-client 提交 PR 以解决该问题。
    重要细节
  • 在 Lambda 函数中,每次请求到达时会启动新实例,若全局环境中存在未释放的内存块,接收请求后函数可能会耗尽内存。
  • amazonkahttp 函数的实现使用 ResourceT 维护资源映射,部分响应读取后未调用 release 导致资源未释放。
  • 最小重现器通过多次向 Amazon S3 发送大请求体来模拟空间泄漏,修复方式包括在每个 Amazonka.send 中调用 runResourceT 或在 http-clientresponseClose 时调用 release
阅读 7
0 条评论