Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ever-increasing memory consumption when HTTP URLs have random identifiers #2876

Closed
pimguilherme opened this issue Jan 25, 2023 · 2 comments
Closed

Comments

@pimguilherme
Copy link

pimguilherme commented Jan 25, 2023

Brief summary

Hi! I am not sure this is an intended and well known behavior from the research I did on these issues, but would you mind helping me take a look at it please?

It looks like when we use URLs with random parts in iterations, the memory increases in a way that eventually consumes all memory of the machine.

a simple example like this:

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  discardResponseBodies: true,
  scenarios: {
    part_1: {
      executor: 'constant-arrival-rate',
      rate: 5000,
      timeUnit: '1s',
      duration: '5m',
      preAllocatedVUs: 50,
      maxVUs: 600,
    },
  },
};

export default function (data) {
  // Alterar para url de PRD
  const response = http.post(`https://httpbin.test.k6.io/post/${Date.now() + Math.floor(Math.random() * 1000)}`, JSON.stringify({}));

  check(response, {
    'status is 200': (r) => r.status === 200,
  });
}

Yields a memory consumption of 2.7G in 5 minutes, in a trend that is ever-increasing:

qua 25 jan 2023 17:50:20 -03
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
pimguil+  227310  130  2.2 1014976 355248 pts/2  Sl+  17:50   0:05 ./k6 run --tag testid=TEST --summary-export=summary-test.json --no-summary --no-usage-report --no-thresholds --out json=/dev/null test.js

qua 25 jan 2023 17:53:40 -03
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
pimguil+  227310 22.3 11.8 2540480 1886412 pts/2 Sl+  17:50   0:45 ./k6 run --tag testid=TEST --summary-export=summary-test.json --no-summary --no-usage-report --no-thresholds --out json=/dev/null test.js

qua 25 jan 2023 17:55:20 -03
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
pimguil+  227310 21.8 17.1 3440168 2744712 pts/2 Sl+  17:50   1:06 ./k6 run --tag testid=TEST --summary-export=summary-test.json --no-summary --no-usage-report --no-thresholds --out json=/dev/null test.js

I thought that maybe that's how it work, and it may be.. but in any case, if I run the same test without a random number in the URL:

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  discardResponseBodies: true,
  scenarios: {
    part_1: {
      executor: 'constant-arrival-rate',
      rate: 5000,
      timeUnit: '1s',
      duration: '5m',
      preAllocatedVUs: 50,
      maxVUs: 600,
    },
  },
};

export default function (data) {
  // Alterar para url de PRD
  const response = http.post(`https://httpbin.test.k6.io/post/test`, JSON.stringify({}));

  check(response, {
    'status is 200': (r) => r.status === 200,
  });
}

Then usage is impressively lower:

qua 25 jan 2023 17:58:47 -03
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
pimguil+  227837  166  1.9 1013696 318436 pts/2  Sl+  17:58   0:05 ./k6 run --tag testid=TEST --summary-export=summary-test.json --no-summary --no-usage-report --no-thresholds --out json=/dev/null test.js


qua 25 jan 2023 18:02:07 -03
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
pimguil+  227837 17.9  3.7 1290996 596092 pts/2  Sl+  17:58   0:36 ./k6 run --tag testid=TEST --summary-export=summary-test.json --no-summary --no-usage-report --no-thresholds --out json=/dev/null testnt.js


qua 25 jan 2023 18:03:07 -03
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
pimguil+  227837 16.9  3.7 1290996 598812 pts/2  Sl+  17:58   0:44 ./k6 run --tag testid=TEST --summary-export=summary-test.json --no-summary --no-usage-report --no-thresholds --out json=/dev/null test.js

This is just an example, but it scales quite a lot if we ramp up the VUs and rates (we were aiming at 20000 RPS).. But anyway here we have a difference of steady 500MB vs 2.7GB which doesn't stop growing.

Could you please help us understand what possibilities we have here? We have tried a bunch of options.. this particular example was run wiht:
--no-summary --no-usage-report --out json=....

Thanks!

k6 version

v0.42.0

OS

20.04.1-Ubuntu

Docker version and image (if applicable)

No response

Steps to reproduce the problem

Create a test file like this:

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  discardResponseBodies: true,
  scenarios: {
    part_1: {
      executor: 'constant-arrival-rate',
      rate: 5000,
      timeUnit: '1s',
      duration: '5m',
      preAllocatedVUs: 50,
      maxVUs: 600,
    },
  },
};

export default function (data) {
  // Alterar para url de PRD
  const response = http.post(`https://httpbin.test.k6.io/post/${Date.now() + Math.floor(Math.random() * 1000)}`, JSON.stringify({}));

  check(response, {
    'status is 200': (r) => r.status === 200,
  });
}

Execute it to the end and note memory consumption is very big.

If you want, Increase the test time to see that memory will never stop growing.

Expected behaviour

The memory consumption should not grow unbounded.

Actual behaviour

The memory consumption grows indefinetely

@na--
Copy link
Member

na-- commented Jan 25, 2023

This is a duplicate of #2836 and #2762

You can see my previous explanation in #2836 (comment) why it happens and how it can be avoided with URL grouping. I am sorry that you hit this issue, we really need to prioritize #2765 soon to make it more obvious when this happens, and probably make the information about time series and URL grouping more prominent (grafana/k6-docs#883).

@pimguilherme
Copy link
Author

thanks a lot @na-- for the very prompt and welcoming response!! I have confirmed the http.url method resolves this scenario, so I guess not really an issue 😅, just really a configuration thing..

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants