crystal-lang / distribution-scripts

40 stars 23 forks source link

Demoting alpine images to alpine 3.12 #127

Closed beta-ziliani closed 2 years ago

beta-ziliani commented 2 years ago

Solves crystal/#10366 by partially undoing #79 .

jhass commented 2 years ago

Did you try upgrading to 3.14?

beta-ziliani commented 2 years ago

@jhass yes, same thing

jhass commented 2 years ago

Bummer :(

luislavena commented 2 years ago

Chiming on this 👋🏽

A side effect of the 3.13 upgrade resulted in reduced performance of statically linked binaries.

A simple HTTP Hello world with 3.13 produces half number of requests (synthetic benchmark) of the exact same code built under Alpine 3.12 using the same compiler version.

Here is the used dockerfile (change 3.12 to 3.13): https://gist.github.com/luislavena/1036d0d9bc4ecb17a28755c709dfdd27#file-crystal-alpine-static-dockerfile

Wasn't able to dig deeper but something changed in newer versions of Alpine that could be connected.

image

bcardiff commented 2 years ago

Hmmm. It seems something broke, probably with this PR because I think is the only changing the linux packaging by the maintenance build failed

https://app.circleci.com/pipelines/github/crystal-lang/crystal/6845/workflows/8886d606-0aaa-46df-96c1-bf188d0ac34a/jobs/63908

./build/crystal is not statically linked
    /lib/ld-musl-x86_64.so.1 (0x7f6054f30000)
luislavena commented 2 years ago

Perhaps relevant @bcardiff, but ldd and file reports Linked executables with Alpine 3.12 as dynamically linked compared to newer versions of Alpine:

$ file bin/myapp-alpine3.12
bin/myapp-alpine3.12: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, with debug_info, not stripped

$ ldd bin/myapp-alpine3.12
        statically linked

This does not happen with 3.13 or 3.14:

❯ file bin/myapp-alpine3.13
bin/myapp-alpine3.13: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped

❯ ldd bin/myapp-alpine3.13
        not a dynamic executable
❯ file bin/myapp-alpine3.14
bin/myapp-alpine3.14: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped

❯ ldd bin/myapp-alpine3.14
        not a dynamic executable
luislavena commented 2 years ago

Also, it appears my previous analysis is no longer accurate (as today, November 20).

Synthetic micro benchmark of basic HTTP server against localhost, this time Crystal 1.2.1 on multiple versions of Alpine:

# A very basic HTTP server
require "http/server"

server = HTTP::Server.new do |context|
  context.response.content_type = "text/plain"
  context.response.print "Hello world!"
end

Signal::INT.trap do
  puts "Shutdown requested."
  server.close
end

ipaddr = server.bind_tcp("0.0.0.0", 8080)

puts "Listening on http://#{ipaddr.address}:#{ipaddr.port}/"
server.listen

Crystal 1.2.1 on Alpine 3.12 (best of 3 bench):

❯ plow -c 5 -d 30s http://localhost:8080/
Benchmarking http://localhost:8080/ for 30s using 5 connection(s).
@ Real-time charts is listening on http://[::]:18888

Summary:
  Elapsed    30.001s
  Count      1493553
    2xx      1493553
  RPS      49783.348
  Reads    4.795MB/s
  Writes   2.754MB/s

Statistics   Min     Mean    StdDev     Max
  Latency   17µs     97µs     56µs    7.944ms
  RPS       45915  49783.62  1104.21  51078.05

Latency Percentile:
  P50    P75    P90    P95    P99   P99.9  P99.99
  93µs  122µs  151µs  175µs  318µs  502µs  1.126ms

Latency Histogram:
  93µs     1431235  95.83%
  160µs      53010   3.55%
  284µs       7203   0.48%
  428µs       1639   0.11%
  577µs        376   0.03%
  1.083ms       74   0.00%
  1.424ms       14   0.00%
  1.811ms        2   0.00%

Crystal 1.2.1 on Alpine 3.13 (best of 3 bench):

❯ plow -c 5 -d 30s http://localhost:8080/
Benchmarking http://localhost:8080/ for 30s using 5 connection(s).
@ Real-time charts is listening on http://[::]:18888

Summary:
  Elapsed        30s
  Count      1475226
    2xx      1475226
  RPS      49173.273
  Reads    4.736MB/s
  Writes   2.720MB/s

Statistics    Min       Mean    StdDev     Max
  Latency     16µs      98µs     58µs    5.209ms
  RPS       44555.55  49172.22  1531.21  50450.54

Latency Percentile:
  P50    P75    P90    P95    P99   P99.9  P99.99
  94µs  123µs  154µs  177µs  323µs  503µs  1.103ms

Latency Histogram:
  97µs     1454405  98.59%
  175µs      18257   1.24%
  333µs       1943   0.13%
  488µs        474   0.03%
  792µs         97   0.01%
  1.349ms       30   0.00%
  2.169ms       15   0.00%
  5.136ms        5   0.00%

Crystal 1.2.1 on Alpine 3.14 (best of 3 bench):

❯ plow -c 5 -d 30s http://localhost:8080/
Benchmarking http://localhost:8080/ for 30s using 5 connection(s).
@ Real-time charts is listening on http://[::]:18888

Summary:
  Elapsed        30s
  Count      1479025
    2xx      1479025
  RPS      49300.800
  Reads    4.749MB/s
  Writes   2.727MB/s

Statistics    Min       Mean    StdDev     Max
  Latency     17µs      98µs     56µs    3.627ms
  RPS       45856.49  49299.64  1104.19  50453.53

Latency Percentile:
  P50    P75    P90    P95    P99   P99.9  P99.99
  93µs  123µs  153µs  176µs  336µs  497µs  1.031ms

Latency Histogram:
  95µs     1414667  95.65%
  148µs      53648   3.63%
  246µs       8811   0.60%
  418µs       1694   0.11%
  678µs        164   0.01%
  1.12ms        30   0.00%
  1.631ms        9   0.00%
  2.45ms         2   0.00%