把 mattn/go-sqlite3 换成了 ncruces/go-sqlite3

陪她去流浪 桃子 阅读次数:59

前者是 CGO 绑定,后者是 WASM 运行时。相关的对比及性能测试可以参考:cvilsmeier/go-sqlite-bench: Benchmarks for Golang SQLite Drivers

前两天有朋友找到我说要部署一份我的博客系统,让我编译一个 Linux/AMD64 版本(实际上我一直是用的这个版本,只不过是 GitHub Actions 编译到容器里面的,但可以 cp 出来),我再次尝试在 MacOS 上直接 go build,再一次又被 CGO 气死了:没有看到任何 build tags 的 sqlite3.Error 竟然无法编译,找不到定义。

而恰好前几天又正好在群里和雨帆⛵️聊起 sqlite3 的问题,仔细看了前面的对比以及文档,发现 WASM 版本 CGO 版本竟然性能几乎无异,所以就动手切换了。实际上改动的代码只有几行1,因为它俩都是兼容 database/sql 接口标准的。

使用的库测试项测试结果Delta

mattn/go-sqlite3

首页
1
2
3
4
5
6
7
8
9
$ wrk https://blog.mac.twofei.com/
Running 10s test @ https://blog.mac.twofei.com/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    49.88ms   14.55ms 110.15ms   70.69%
    Req/Sec   100.23     15.07   140.00     73.00%
  2008 requests in 10.06s, 18.91MB read
Requests/sec:    199.69
Transfer/sec:      1.88MB
N/A
文章
1
2
3
4
5
6
7
8
9
$ wrk https://blog.mac.twofei.com/1/
Running 10s test @ https://blog.mac.twofei.com/1/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     7.50ms    2.57ms  37.84ms   71.15%
    Req/Sec   670.53     42.64   737.00     86.00%
  13358 requests in 10.01s, 81.92MB read
Requests/sec:   1334.46
Transfer/sec:      8.18MB
N/A

ncruces/go-sqlite3

首页
1
2
3
4
5
6
7
8
9
$ wrk https://blog.mac.twofei.com/
Running 10s test @ https://blog.mac.twofei.com/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    94.73ms   27.77ms 210.57ms   72.21%
    Req/Sec    52.77     12.82    90.00     70.71%
  1056 requests in 10.07s, 9.94MB read
Requests/sec:    104.88
Transfer/sec:      0.99MB
-47%
文章
1
2
3
4
5
6
7
8
9
$ wrk https://blog.mac.twofei.com/1/
Running 10s test @ https://blog.mac.twofei.com/1/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    12.22ms    4.09ms  42.32ms   70.56%
    Req/Sec   411.22     27.02   474.00     74.00%
  8201 requests in 10.02s, 50.30MB read
Requests/sec:    818.50
Transfer/sec:      5.02MB
-38%

“首页”因为几乎没有缓存的原因,相比于“单篇文章”来说性能非常差,在我的预期内。但是从 CGO 换成 WASM 竟然整体性能掉了一半让我震惊。换还是不换呢❓

换,当然要换,对于我这样的小破站来说,即便是只有几百 QPS 的性能也完全没问题。最主要的是:编译速度/跨平台编译容易程度都极大地提高了。还有一点,几百 QPS 显然是另有隐情。

所以我就 profile 了一下 cpu:

好了,知道问题所在了:七年前(至少)写的查“相关文章”的接口没有缓存(大量管理性能 INOR!= 语句),瓶颈全在这儿。

加了缓存后,效果改善就“很大”了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ wrk https://blog.mac.twofei.com/1/ 
Running 10s test @ https://blog.mac.twofei.com/1/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   447.34us    1.11ms  54.96ms   94.86%
    Req/Sec    20.70k    14.85k   36.16k    51.98%
  415804 requests in 10.10s, 320.85MB read
  Non-2xx or 3xx responses: 383097
Requests/sec:  41167.80
Transfer/sec:     31.77MB

直接起飞到了 4万 QPS。但是仔细观察,发现错误非常多,nginx 的 upstream 不够用了。我直接访问 localhost:

1
2
3
4
5
6
7
8
9
$ wrk http://localhost:2564/1/
Running 10s test @ http://localhost:2564/1/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.34ms    1.33ms  35.59ms   95.15%
    Req/Sec     4.03k   216.01     4.33k    94.06%
  80920 requests in 10.10s, 493.67MB read
Requests/sec:   8012.03
Transfer/sec:     48.88MB

这次就只有 8000+ 了(全部成功)。

好了,今天的优化至此结束。