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

NETOBSERV-754: Optimize cache usage #476

Merged
merged 3 commits into from
Nov 7, 2023

Conversation

jotak
Copy link
Member

@jotak jotak commented Oct 25, 2023

Description

Cut down memory usage; controller-runtime may cache whole cluster configmap / secret for a single client.Get call: prevent that.

Dependencies

n/a

Checklist

If you are not familiar with our processes or don't know what to answer in the list below, let us know in a comment: the maintainers will take care of that.

  • Is this PR backed with a JIRA ticket? If so, make sure it is written as a title prefix (in general, PRs affecting the NetObserv/Network Observability product should be backed with a JIRA ticket - especially if they bring user facing changes).
  • Does this PR require product documentation?
    • If so, make sure the JIRA epic is labelled with "documentation" and provides a description relevant for doc writers, such as use cases or scenarios. Any required step to activate or configure the feature should be documented there, such as new CRD knobs.
  • Does this PR require a product release notes entry?
    • If so, fill in "Release Note Text" in the JIRA.
  • Is there anything else the QE team should know before testing? E.g: configuration changes, environment setup, etc.
    • If so, make sure it is described in the JIRA ticket.
  • QE requirements (check 1 from the list):
    • Standard QE validation, with pre-merge tests unless stated otherwise.
    • Regression tests only (e.g. refactoring with no user-facing change).
    • No QE (e.g. trivial change with high reviewer's confidence, or per agreement with the QE team).

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Oct 25, 2023

@jotak: This pull request references NETOBSERV-754 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.15.0" version, but no target version was set.

In response to this:

Description

Cut down memory usage; controller-runtime may cache whole cluster configmap / secret for a single client.Get call: prevent that.

Dependencies

n/a

Checklist

If you are not familiar with our processes or don't know what to answer in the list below, let us know in a comment: the maintainers will take care of that.

  • Is this PR backed with a JIRA ticket? If so, make sure it is written as a title prefix (in general, PRs affecting the NetObserv/Network Observability product should be backed with a JIRA ticket - especially if they bring user facing changes).
  • Does this PR require product documentation?
  • If so, make sure the JIRA epic is labelled with "documentation" and provides a description relevant for doc writers, such as use cases or scenarios. Any required step to activate or configure the feature should be documented there, such as new CRD knobs.
  • Does this PR require a product release notes entry?
  • If so, fill in "Release Note Text" in the JIRA.
  • Is there anything else the QE team should know before testing? E.g: configuration changes, environment setup, etc.
  • If so, make sure it is described in the JIRA ticket.
  • QE requirements (check 1 from the list):
  • Standard QE validation, with pre-merge tests unless stated otherwise.
  • Regression tests only (e.g. refactoring with no user-facing change).
  • No QE (e.g. trivial change with high reviewer's confidence, or per agreement with the QE team).

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@codecov
Copy link

codecov bot commented Oct 25, 2023

Codecov Report

Attention: 37 lines in your changes are missing coverage. Please review.

Comparison is base (f7345c8) 54.90% compared to head (7b7bd5f) 55.61%.
Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #476      +/-   ##
==========================================
+ Coverage   54.90%   55.61%   +0.71%     
==========================================
  Files          49       52       +3     
  Lines        6453     6660     +207     
==========================================
+ Hits         3543     3704     +161     
- Misses       2666     2701      +35     
- Partials      244      255      +11     
Flag Coverage Δ
unittests 55.61% <83.25%> (+0.71%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
controllers/flowcollector_controller.go 54.96% <100.00%> (-0.18%) ⬇️
pkg/narrowcache/source.go 100.00% <100.00%> (ø)
pkg/test/kube_mock.go 74.69% <100.00%> (-10.49%) ⬇️
pkg/watchers/watcher.go 68.55% <100.00%> (ø)
pkg/narrowcache/config.go 86.95% <86.95%> (ø)
pkg/narrowcache/client.go 80.25% <80.25%> (ø)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Owns(&appsv1.Deployment{}).
Owns(&appsv1.DaemonSet{}).
Owns(&ascv2.HorizontalPodAutoscaler{}).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of removing this is that we will not get notification for reconciliation if the HPA is manually modified.
https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/builder#Builder.Owns

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah tbh I'm not sure why I removed HPA, my point is really about configmap, I'll put HPA back.
It's a trade-off, might be loosing some reconcile events, but the gain overcomes the disadvantages

main.go Outdated
@@ -132,6 +133,11 @@ func main() {
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "7a7ecdcd.netobserv.io",
Client: client.Options{
Cache: &client.CacheOptions{
DisableFor: []client.Object{&corev1.ConfigMap{}, &corev1.Secret{}},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will reduce cache memory but will increase a lot queries to kubeAPI.
Are we sure about this? This make many GET request to kubeAPI each reconciliation loop.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but it will DRASTICALLY reduce cache memory especially on clusters with many cm/secrets, because this caches the whole cluster configmaps/secrets. I think the additional GET are peanuts compared to this (cf slack thread https://app.slack.com/client/T027F3GAJ/C02939DP5L5/thread/C02939DP5L5-1698237974.684409 )

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jotak jotak added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Oct 25, 2023
@github-actions
Copy link

New images:

  • quay.io/netobserv/network-observability-operator:2fd7345
  • quay.io/netobserv/network-observability-operator-bundle:v0.0.0-2fd7345
  • quay.io/netobserv/network-observability-operator-catalog:v0.0.0-2fd7345

They will expire after two weeks.

To deploy this build:

# Direct deployment, from operator repo
IMAGE=quay.io/netobserv/network-observability-operator:2fd7345 make deploy

# Or using operator-sdk
operator-sdk run bundle quay.io/netobserv/network-observability-operator-bundle:v0.0.0-2fd7345

Or as a Catalog Source:

apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: netobserv-dev
  namespace: openshift-marketplace
spec:
  sourceType: grpc
  image: quay.io/netobserv/network-observability-operator-catalog:v0.0.0-2fd7345
  displayName: NetObserv development catalog
  publisher: Me
  updateStrategy:
    registryPoll:
      interval: 1m

@github-actions github-actions bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Oct 25, 2023
@jotak
Copy link
Member Author

jotak commented Oct 25, 2023

Here's the test I'm doing:

  • Deploy operator + default flowcollector
  • Run this script that creates 500 big configmaps:
oc new-project test
for i in {1..500}; do k create cm test-cm-$i -n test --from-file=bundle/manifests/flows.netobserv.io_flowcollectors.yaml ; done

Results
On current main, I'm seeing operator memory flying from 95 MB to almost 400 MB
Capture d’écran du 2023-10-25 11-39-40

With this PR, memory stays flat at 33 MB
Capture d’écran du 2023-10-25 17-44-59

@jotak
Copy link
Member Author

jotak commented Oct 26, 2023

@OlivierCazade I'll investigate creating a custom cache instead of removing it entirely for CM/Secrets

@jotak
Copy link
Member Author

jotak commented Oct 27, 2023

So, after investigating doing a custom cache, it's not satisfying, I'm going back to totally disabling cache for CM and secrets: improvements go far beyond losses, and this is even better when considering Kube API traffic. Let me detail:

I'm tracking here the operator <-> kube API traffic with our metrics (dogfooding FTW)

Scenario using current operator

Capture d’écran du 2023-10-27 07-27-12

You can see huge traffic when I'm creating 200 CMs (900kBps during 2 minutes), and also noticeable traffic at operator startup and when updating 10 CMs (~150-200 kBps for 30s or so).

Now with this PR (notice the scale)
Capture d’écran du 2023-10-27 07-37-55

You see: much less traffic at startup (35kBps - because it's not initializing CM informers cache), and no traffic when CMs are created / updated.

The question that remains is: what happens during reconciles? Well, yes, there is a bit more traffic generated: around 7kBps versus 3kBps with cache. We can expect more when we need to watch loki/kafka certificates. But that's still far below the huge difference made by all the unneeded configmap changes being watched all the time cluster-wide.

So what's the difference with our current main if I create a custom cache ? No difference here, we'll still have this huge traffic with Kube API. It only allows to save memory, but not traffic, because the way it's done, it's still going to track all cluster CMs - we can only play on eliminating undesired data to not store them in cache, but we'll still be informed of every CM map change.

@jotak
Copy link
Member Author

jotak commented Oct 27, 2023

FTR here's my WIP attempt to create a custom cache, but I prefer to stop here since it's still not as good as disabling cache: jotak@26c3fbc

OlivierCazade
OlivierCazade previously approved these changes Oct 27, 2023
Copy link
Contributor

@OlivierCazade OlivierCazade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank for the investigations Joel

@jotak
Copy link
Member Author

jotak commented Oct 27, 2023

Thanks @OlivierCazade
@nathan-weinberg I guess it's on you :-)

@nathan-weinberg
Copy link
Contributor

/ok-to-test

@openshift-ci openshift-ci bot added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Oct 27, 2023
@github-actions
Copy link

New images:

  • quay.io/netobserv/network-observability-operator:e90e8d4
  • quay.io/netobserv/network-observability-operator-bundle:v0.0.0-e90e8d4
  • quay.io/netobserv/network-observability-operator-catalog:v0.0.0-e90e8d4

They will expire after two weeks.

To deploy this build:

# Direct deployment, from operator repo
IMAGE=quay.io/netobserv/network-observability-operator:e90e8d4 make deploy

# Or using operator-sdk
operator-sdk run bundle quay.io/netobserv/network-observability-operator-bundle:v0.0.0-e90e8d4

Or as a Catalog Source:

apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: netobserv-dev
  namespace: openshift-marketplace
spec:
  sourceType: grpc
  image: quay.io/netobserv/network-observability-operator-catalog:v0.0.0-e90e8d4
  displayName: NetObserv development catalog
  publisher: Me
  updateStrategy:
    registryPoll:
      interval: 1m

@nathan-weinberg
Copy link
Contributor

I ran a node-density-heavy job with this PR image, comparing it with our current baseline tracked by UUID 46dbc801-3b5d-471e-8172-6a71c0eedccb

In that baseline run[1], we see the following values for the memory of the controller pod:

memoryUsageRSS netobserv-controller-manager-54bd69cc9f-gwjp6 avg(value) 157 MB
memoryUsageWorkingSet netobserv-controller-manager-54bd69cc9f-gwjp6 avg(value) 193 MB

In the new run[2], we see the following values:

memoryUsageRSS netobserv-controller-manager-7b4887475d-89444 avg(value) 156 MB
memoryUsageWorkingSet netobserv-controller-manager-7b4887475d-89444 avg(value) 196 MB

While the values do not look that much improved, the second run processed many more flows (almost double) than the original run[3]

nFlowsProcessedPerMinuteTotals avg(value) 95.48% 584710.4091 1143012.915

@jotak let me know your thoughts around this data - another idea I had was running our cluster-density test case which typically requires raising the controller memory limit to 800MB and seeing if we can run it using your PR image with the default limit of 400MB

[1]https://docs.google.com/spreadsheets/d/11_ppiK42Y1KIssmmYLt9L678EtZEiQ0Qn3EdIOFD4SA/edit?usp=sharing
[2]https://docs.google.com/spreadsheets/d/1Bqvyyog2H0WKPgJZOZ2SvtKnQ8m773f5tu5Qrorzi9k/edit?usp=sharing
[3]https://docs.google.com/spreadsheets/d/1p72gIC8i4T4Rh-7qu5XDCjuQ2nzRgs6N_78OVZJ7ZJI/edit?usp=sharing

@jotak
Copy link
Member Author

jotak commented Oct 30, 2023

So it seems like there are side-effects that I didn't see I first - I did my performance tests with monolithic Loki, but it seems it's doesn't work correctly when using the loki operator instead. @nathan-weinberg you might be blocked by that.
I'm working on it ...

@openshift-ci openshift-ci bot removed the lgtm label Oct 30, 2023
@github-actions github-actions bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Oct 30, 2023
@github-actions
Copy link

New images:

  • quay.io/netobserv/network-observability-operator:2c8f84d
  • quay.io/netobserv/network-observability-operator-bundle:v0.0.0-2c8f84d
  • quay.io/netobserv/network-observability-operator-catalog:v0.0.0-2c8f84d

They will expire after two weeks.

To deploy this build:

# Direct deployment, from operator repo
IMAGE=quay.io/netobserv/network-observability-operator:2c8f84d make deploy

# Or using operator-sdk
operator-sdk run bundle quay.io/netobserv/network-observability-operator-bundle:v0.0.0-2c8f84d

Or as a Catalog Source:

apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: netobserv-dev
  namespace: openshift-marketplace
spec:
  sourceType: grpc
  image: quay.io/netobserv/network-observability-operator-catalog:v0.0.0-2c8f84d
  displayName: NetObserv development catalog
  publisher: Me
  updateStrategy:
    registryPoll:
      interval: 1m

@github-actions github-actions bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Oct 31, 2023
@jotak jotak added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Oct 31, 2023
@github-actions
Copy link

New images:

  • quay.io/netobserv/network-observability-operator:9adc98c
  • quay.io/netobserv/network-observability-operator-bundle:v0.0.0-9adc98c
  • quay.io/netobserv/network-observability-operator-catalog:v0.0.0-9adc98c

They will expire after two weeks.

To deploy this build:

# Direct deployment, from operator repo
IMAGE=quay.io/netobserv/network-observability-operator:9adc98c make deploy

# Or using operator-sdk
operator-sdk run bundle quay.io/netobserv/network-observability-operator-bundle:v0.0.0-9adc98c

Or as a Catalog Source:

apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: netobserv-dev
  namespace: openshift-marketplace
spec:
  sourceType: grpc
  image: quay.io/netobserv/network-observability-operator-catalog:v0.0.0-9adc98c
  displayName: NetObserv development catalog
  publisher: Me
  updateStrategy:
    registryPoll:
      interval: 1m

@jotak
Copy link
Member Author

jotak commented Oct 31, 2023

@OlivierCazade @nathan-weinberg FYI I've changed a lot of things in my last commit. Disabling cache like I did before was breaking our certificate watching. So I had to implement a whole new thing which should be optimal: still using cache, but no more than what is needed.
My concern about it is that's it's a whole new piece that needs to be battle-tested. There must be solid perf/consumption advantage to make it worth it.

@nathan-weinberg
Copy link
Contributor

@jotak can you rebase so we can run the regressions?

- Uses lower-level watches rather than informers, to watch more selectively
by single resource
- Used exclusively for GET/WATCH , Configmaps/Secrets
- Other kinds of queries still use the usual client
@github-actions github-actions bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Nov 6, 2023
@jotak jotak added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Nov 6, 2023
Copy link

github-actions bot commented Nov 6, 2023

New images:

  • quay.io/netobserv/network-observability-operator:deecd40
  • quay.io/netobserv/network-observability-operator-bundle:v0.0.0-deecd40
  • quay.io/netobserv/network-observability-operator-catalog:v0.0.0-deecd40

They will expire after two weeks.

To deploy this build:

# Direct deployment, from operator repo
IMAGE=quay.io/netobserv/network-observability-operator:deecd40 make deploy

# Or using operator-sdk
operator-sdk run bundle quay.io/netobserv/network-observability-operator-bundle:v0.0.0-deecd40

Or as a Catalog Source:

apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
  name: netobserv-dev
  namespace: openshift-marketplace
spec:
  sourceType: grpc
  image: quay.io/netobserv/network-observability-operator-catalog:v0.0.0-deecd40
  displayName: NetObserv development catalog
  publisher: Me
  updateStrategy:
    registryPoll:
      interval: 1m

@jotak
Copy link
Member Author

jotak commented Nov 6, 2023

@jotak can you rebase so we can run the regressions?

done

@nathan-weinberg
Copy link
Contributor

Ran the regressions against this PR: https://mastern-jenkins-csb-openshift-qe.apps.ocp-c1.prod.psi.redhat.com/job/ocp-common/job/ginkgo-test/213434/console

Only failing tests had to do with expecting downstream metrics source instead of upstream, so those should be passing once the changes making it downstream.

@nathan-weinberg
Copy link
Contributor

/label qe-approved

@openshift-ci openshift-ci bot added the qe-approved QE has approved this pull request label Nov 6, 2023
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Nov 6, 2023

@jotak: This pull request references NETOBSERV-754 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.15.0" version, but no target version was set.

In response to this:

Description

Cut down memory usage; controller-runtime may cache whole cluster configmap / secret for a single client.Get call: prevent that.

Dependencies

n/a

Checklist

If you are not familiar with our processes or don't know what to answer in the list below, let us know in a comment: the maintainers will take care of that.

  • Is this PR backed with a JIRA ticket? If so, make sure it is written as a title prefix (in general, PRs affecting the NetObserv/Network Observability product should be backed with a JIRA ticket - especially if they bring user facing changes).
  • Does this PR require product documentation?
  • If so, make sure the JIRA epic is labelled with "documentation" and provides a description relevant for doc writers, such as use cases or scenarios. Any required step to activate or configure the feature should be documented there, such as new CRD knobs.
  • Does this PR require a product release notes entry?
  • If so, fill in "Release Note Text" in the JIRA.
  • Is there anything else the QE team should know before testing? E.g: configuration changes, environment setup, etc.
  • If so, make sure it is described in the JIRA ticket.
  • QE requirements (check 1 from the list):
  • Standard QE validation, with pre-merge tests unless stated otherwise.
  • Regression tests only (e.g. refactoring with no user-facing change).
  • No QE (e.g. trivial change with high reviewer's confidence, or per agreement with the QE team).

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Copy link
Contributor

@OlivierCazade OlivierCazade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks Joel.
LGTM

@openshift-ci openshift-ci bot added the lgtm label Nov 7, 2023
@jotak
Copy link
Member Author

jotak commented Nov 7, 2023

/approve

Copy link

openshift-ci bot commented Nov 7, 2023

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jotak

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved label Nov 7, 2023
@openshift-merge-bot openshift-merge-bot bot merged commit 611e471 into netobserv:main Nov 7, 2023
11 checks passed
@jotak jotak deleted the configmap-no-cache branch November 7, 2023 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved jira/valid-reference lgtm ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. qe-approved QE has approved this pull request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants