AWS Lambda i kontenery – Cold Start
Jak pisałem ostatnio AWS umożliwił uruchamianie za pomocą funkcji Lambda skonteneryzowancyh aplikacji. Sprawdziłem jak wygląda czas inicjalizacji takiej funkcji. Czyli tak zwany cold start. A właściwie, jak upomniał mnie Paweł Zubkiewicz, część cold startu.
Nie robiłem wielkich badań. Każda funkcja była uruchomiona tylko kilka razy. Nie jest to więc opracowanie naukowe, ale jakieś wnioski można wysnuć. Uruchomiłem też taki sam kod, albo taką samą funkcjonalność, bez użycia Dockera. Próby przeprowadziłem dla Go i .Net Core 3.1.
Testowaną aplikacją, w obu przypadkach, był dostarczany wraz z sam cli template HelloWorld. W przypadku tworzenia obrazu inicjowałem aplikację za pomocą polecenia sam init --package-type Image --base-image amazon/dotnetcore3.1-base --name hello
dla Core i sam init --package-type Image --base-image amazon/go1.x-base --name hello
dla Go.
Testy
W logach, w których występuje Init Duration były tworzone nowe instancje funkcji, czyli następował cold start.
.Net Core
128 MB
Duration: 6705.53 ms Billed Duration: 8605 ms Memory Size: 128 MB Max Memory Used: 80 MB Init Duration: 1898.98 ms Duration: 5126.19 ms Billed Duration: 5643 ms Memory Size: 128 MB Max Memory Used: 80 MB Init Duration: 516.47 ms Duration: 5152.22 ms Billed Duration: 6162 ms Memory Size: 128 MB Max Memory Used: 80 MB Init Duration: 1009.02 ms Duration: 5443.78 ms Billed Duration: 6506 ms Memory Size: 128 MB Max Memory Used: 79 MB Init Duration: 1061.92 ms Duration: 72.55 ms Billed Duration: 73 ms Memory Size: 128 MB Max Memory Used: 80 MB Duration: 69.99 ms Billed Duration: 70 ms Memory Size: 128 MB Max Memory Used: 80 MB Duration: 181.26 ms Billed Duration: 182 ms Memory Size: 128 MB Max Memory Used: 80 MB Duration: 125.11 ms Billed Duration: 126 ms Memory Size: 128 MB Max Memory Used: 80 MB
256 MB
Duration: 2526.54 ms Billed Duration: 3394 ms Memory Size: 256 MB Max Memory Used: 80 MB Init Duration: 866.60 ms Duration: 2626.13 ms Billed Duration: 3544 ms Memory Size: 256 MB Max Memory Used: 79 MB Init Duration: 917.01 ms Duration: 2522.31 ms Billed Duration: 3475 ms Memory Size: 256 MB Max Memory Used: 80 MB Init Duration: 952.25 ms Duration: 2506.66 ms Billed Duration: 3371 ms Memory Size: 256 MB Max Memory Used: 79 MB Init Duration: 863.83 ms Duration: 72.84 ms Billed Duration: 73 ms Memory Size: 256 MB Max Memory Used: 80 MB Duration: 70.05 ms Billed Duration: 71 ms Memory Size: 256 MB Max Memory Used: 80 MB Duration: 72.04 ms Billed Duration: 73 ms Memory Size: 256 MB Max Memory Used: 80 MB Duration: 69.26 ms Billed Duration: 70 ms Memory Size: 256 MB Max Memory Used: 80 MB Duration: 72.32 ms Billed Duration: 73 ms Memory Size: 256 MB Max Memory Used: 80 MB
512 MB
Duration: 2564.81 ms Billed Duration: 3561 ms Memory Size: 512 MB Max Memory Used: 79 MB Init Duration: 995.82 ms Duration: 1370.72 ms Billed Duration: 2357 ms Memory Size: 512 MB Max Memory Used: 79 MB Init Duration: 985.71 ms Duration: 1458.95 ms Billed Duration: 2764 ms Memory Size: 512 MB Max Memory Used: 79 MB Init Duration: 1304.12 ms Duration: 1355.93 ms Billed Duration: 1896 ms Memory Size: 512 MB Max Memory Used: 80 MB Init Duration: 539.76 ms Duration: 72.07 ms Billed Duration: 73 ms Memory Size: 512 MB Max Memory Used: 80 MB Duration: 69.09 ms Billed Duration: 70 ms Memory Size: 512 MB Max Memory Used: 80 MB Duration: 75.93 ms Billed Duration: 76 ms Memory Size: 512 MB Max Memory Used: 80 MB Duration: 72.80 ms Billed Duration: 73 ms Memory Size: 512 MB Max Memory Used: 80 MB Duration: 77.07 ms Billed Duration: 78 ms Memory Size: 512 MB Max Memory Used: 80 MB
3 GB
Duration: 2061.75 ms Billed Duration: 3035 ms Memory Size: 3096 MB Max Memory Used: 83 MB Init Duration: 972.65 m Duration: 627.08 ms Billed Duration: 1522 ms Memory Size: 3096 MB Max Memory Used: 83 MB Init Duration: 894.63 ms
10 GB
Duration: 669.28 ms Billed Duration: 1640 ms Memory Size: 10240 MB Max Memory Used: 92 MB Init Duration: 970.63 ms
I przykładowe wyniki bez użycia kontenerów:
128 MB
Duration: 5098.65 ms Billed Duration: 5099 ms Memory Size: 128 MB Max Memory Used: 78 MB Init Duration: 190.95 ms Duration: 72.62 ms Billed Duration: 73 ms Memory Size: 128 MB Max Memory Used: 78 MB Duration: 69.73 ms Billed Duration: 70 ms Memory Size: 128 MB Max Memory Used: 78 MB
256 MB
Duration: 2413.01 ms Billed Duration: 2414 ms Memory Size: 256 MB Max Memory Used: 78 MB Init Duration: 173.46 ms Duration: 69.06 ms Billed Duration: 70 ms Memory Size: 256 MB Max Memory Used: 78 MB Duration: 105.78 ms Billed Duration: 106 ms Memory Size: 256 MB Max Memory Used: 78 MB
512 MB
Duration: 1210.68 ms Billed Duration: 1211 ms Memory Size: 512 MB Max Memory Used: 78 MB Init Duration: 192.26 ms Duration: 75.71 ms Billed Duration: 76 ms Memory Size: 512 MB Max Memory Used: 79 MB Duration: 93.93 ms Billed Duration: 94 ms Memory Size: 512 MB Max Memory Used: 79 MB
Golang
128 MB
Duration: 850.01 ms Billed Duration: 1609 ms Memory Size: 128 MB Max Memory Used: 53 MB Init Duration: 758.56 ms Duration: 856.34 ms Billed Duration: 1185 ms Memory Size: 128 MB Max Memory Used: 51 MB Init Duration: 328.26 ms Duration: 856.34 ms Billed Duration: 1185 ms Memory Size: 128 MB Max Memory Used: 51 MB Init Duration: 328.26 ms Duration: 881.82 ms Billed Duration: 1238 ms Memory Size: 128 MB Max Memory Used: 52 MB Init Duration: 356.02 ms Duration: 68.26 ms Billed Duration: 69 ms Memory Size: 128 MB Max Memory Used: 51 MB Duration: 68.48 ms Billed Duration: 69 ms Memory Size: 128 MB Max Memory Used: 51 MB Duration: 68.10 ms Billed Duration: 69 ms Memory Size: 128 MB Max Memory Used: 51 MB Duration: 68.50 ms Billed Duration: 69 ms Memory Size: 128 MB Max Memory Used: 51 MB
256 MB
Duration: 538.26 ms Billed Duration: 969 ms Memory Size: 256 MB Max Memory Used: 52 MB Init Duration: 430.48 ms Duration: 545.15 ms Billed Duration: 970 ms Memory Size: 256 MB Max Memory Used: 51 MB Init Duration: 424.84 ms Duration: 542.31 ms Billed Duration: 863 ms Memory Size: 256 MB Max Memory Used: 51 MB Init Duration: 320.46 ms Duration: 526.06 ms Billed Duration: 833 ms Memory Size: 256 MB Max Memory Used: 51 MB Init Duration: 306.29 ms Duration: 70.01 ms Billed Duration: 71 ms Memory Size: 256 MB Max Memory Used: 52 MB Duration: 69.35 ms Billed Duration: 70 ms Memory Size: 256 MB Max Memory Used: 52 MB Duration: 69.65 ms Billed Duration: 70 ms Memory Size: 256 MB Max Memory Used: 52 MB Duration: 69.58 ms Billed Duration: 70 ms Memory Size: 256 MB Max Memory Used: 52 MB
512 MB
Duration: 463.05 ms Billed Duration: 1683 ms Memory Size: 512 MB Max Memory Used: 53 MB Init Duration: 1219.79 ms Duration: 404.39 ms Billed Duration: 1283 ms Memory Size: 512 MB Max Memory Used: 53 MB Init Duration: 878.13 ms Duration: 390.89 ms Billed Duration: 672 ms Memory Size: 512 MB Max Memory Used: 51 MB Init Duration: 280.39 ms Duration: 413.91 ms Billed Duration: 937 ms Memory Size: 512 MB Max Memory Used: 52 MB Init Duration: 522.78 ms Duration: 439.44 ms Billed Duration: 687 ms Memory Size: 512 MB Max Memory Used: 51 MB Init Duration: 247.36 ms Duration: 397.57 ms Billed Duration: 817 ms Memory Size: 512 MB Max Memory Used: 51 MB Init Duration: 418.81 ms Duration: 70.01 ms Billed Duration: 71 ms Memory Size: 512 MB Max Memory Used: 52 MB Duration: 70.09 ms Billed Duration: 71 ms Memory Size: 512 MB Max Memory Used: 52 MB Duration: 69.96 ms Billed Duration: 70 ms Memory Size: 512 MB Max Memory Used: 52 MB Duration: 76.63 ms Billed Duration: 77 ms Memory Size: 512 MB Max Memory Used: 52 MB
Dodatkowo przykładowy start nowej instancji dla „czystego” Golang, uruchomionego bezpośrednio:
Duration: 1245.12 ms Billed Duration: 1246 ms Memory Size: 128 MB Max Memory Used: 45 MB Init Duration: 73.31 ms
Wnioski
Daleko idących na razie nie będę wysuwał. Na pewno w przypadku użycia kontenera Lambda startuje dłużej. To było do przewidzenia. Kolejny powód, żeby jednak korzystać z waniliowej postaci funkcji i nie używać kontenerów bez konieczności. Po inicjalizacji obie postaci funkcji pracują praktycznie tak samo szybko.
Zastanawia mnie dość spoty rozrzut w tych czasach inicjalizacji dla skonteneryzowanych funkcji. Być może wpływ ma czas potrzebny za pobranie obrazu z repozytorium.
Wydaje mi się też, że jest trochę lepiej niż w momencie udostępnienia tej funkcjonalności. Testowałem cold starty dla kontenerów zaraz na samym początku i odnoszę wrażenie, że były one dłuższe.