doushi9780 2018-06-04 18:19
浏览 119

使用Docker在简单的Go服务器上获得巨大性能

I've tried several things to get to the root of this, but I'm clueless.

Here's the Go program. It's just one file and has a /api/sign endpoint that accepts POST requests. These POST requests have three fields in the body, and they are logged in a sqlite3 database. Pretty basic stuff.

I wrote a simple Dockerfile to containerize it. Uses golang:1.7.4 to build the binary and copies it over to alpine:3.6 for the final image. Once again, nothing fancy.

I use wrk to benchmark performance. With 8 threads and 1k connections for 50 seconds (wrk -t8 -c1000 -d50s -s post.lua http://server.com/api/sign) and a lua script to create the post requests, I measured the number of requests per second between different situations. In all situations, I run wrk from my laptop and the server is in DigitalOcean VPS (2 vCPUs, 2 GB RAM, SSD, Debian 9.4) that's very close to me.

  • Directly running the binary produced 2979 requests/sec.

  • Docker (docker run -it -v $(pwd):/data -p 8080:8080 image) produced 179 requests/sec.

As you can see, the Docker version is over 16x slower than running the binary directly. Everything else is the same during both experiments.

I've tried the following things and there is practically no improvement in performance in the Docker version:

  • Tried using host networking instead of bridge. There was a slight increase to around 190 requests/sec, but it's still miserable.

  • Tried increasing the limit on the number of file descriptors in the container version with --ulimit nofile=262144:262144. No improvement.

  • Tried different go versions, nothing.

  • Tried debian:9.4 for the final image instead of alpine:3.7 in the hope that it's musl that's performing terribly. Nothing here either.

  • (Edit) Tried running the container without a mounted volume and there's still no performance improvement.

I'm out of ideas at this point. Any help would be much appreciated!

  • 写回答

1条回答 默认 最新

  • douchilian1009 2018-06-04 18:57
    关注

    Using an in-memory sqlite3 database completely solved all performance issues!

    db, err = sql.Open("sqlite3", "file=dco.sqlite3?mode=memory")
    

    I knew there was a disk I/O penalty hit associated with Docker's abstractions (even on Linux; I've heard it's worse on macOS), but I didn't know it would be ~16x.

    Edit: Using an in-memory database isn't really an option most of the time. So I found another sqlite-specific solution. Before all database operations, do this to switch sqlite to WAL mode instead of the default rollback journal:

    PRAGMA journal_mode=WAL;
    PRAGMA synchronous=NORMAL;
    

    This dramatically improved the Docker version's performance to over 2.7k requests/sec!

    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘