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

fix(redis): stream read from Redis #830

Merged
merged 3 commits into from
Feb 22, 2021
Merged

Conversation

deverton
Copy link
Contributor

@deverton deverton commented Feb 8, 2021

This change makes the role sync process stream and process the data from Redis incrementally. Previously it would cache the entire data set before processing which would cause fiat to consume a large amount of heap on some data sets.

May fix spinnaker/spinnaker#6328 and fix spinnaker/spinnaker#6319

@deverton deverton force-pushed the mem-reduce branch 2 times, most recently from dcc184f to 685e4ae Compare February 9, 2021 02:30
@deverton deverton marked this pull request as ready for review February 9, 2021 02:40
log.error("Storage exception reading all entries.", e);
}
return null;
private RawUserPermission getRawUserPermissionsFromRedis(String userId) {
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a lot of overlap between this and getFromRedis that it would be nice to consolidate

@cfieber
Copy link
Contributor

cfieber commented Feb 10, 2021

I like the approach - had a comment about the overlap of getFromRedis and getRawPermissionFromRedis - I'd like to see there only be one of those.

Some of the things in getFromRedis are intentionally not pipelined to avoid executing large batches of commands at once against redis and just issuing commands at a time wrapped with redisRead. That is an intentional tradeoff of speed vs throughput by trying to spread request processing on redis that I think is worthwhile to keep.

@deverton
Copy link
Contributor Author

In testing so far we've not seen any problems with Redis (well, Elasticache) keeping up with the command rate but I understand the point.

Combining the two functions would be ideal, but then what time out would apply during a sync process? Do you timeout the whole sync? Or just the individual value being synced at the time?

This change makes the role sync process stream and process the data from Redis incrementally. Previously it would cache the entire data set before processing which would cause `fiat` to consume a large amount of heap on some data sets.

May fix spinnaker/spinnaker#6328 and fix spinnaker/spinnaker#6319
Dan Everton added 2 commits February 15, 2021 15:56
This change shares the read from Redis code between `get()`, `getAllById()`, and `getAllByRoles()`.

Impact to performance should be minimal as the unrestrictied user permissions cache is now used in the `getAllBy*` cases. There is however an additional `SISMEMBER` call per-user fetched rather than a single `SSCAN` and test on the Java side.
@deverton
Copy link
Contributor Author

Updated the PR to unify the methods. This deletes a lot of code so I'm a bit suspicious about it still being correct, but in the testing I've done it seems fine. There's no more batching of user fetches though which seems like it should slow things down but doesn't seem to. It does open up the possibility of using parallelStream() and a fork-join pool to sync users in parallel though.

@cfieber cfieber merged commit 086e192 into spinnaker:master Feb 22, 2021
@deverton deverton deleted the mem-reduce branch February 24, 2021 20:30
@deverton deverton restored the mem-reduce branch February 24, 2021 20:31
deverton added a commit to deverton/fiat that referenced this pull request Feb 24, 2021
This change makes the role sync process stream and process the data from Redis incrementally. Previously it would cache the entire data set before processing which would cause `fiat` to consume a large amount of heap on some data sets.

May fix spinnaker/spinnaker#6328 and fix spinnaker/spinnaker#6319

This change shares the read from Redis code between `get()`, `getAllById()`, and `getAllByRoles()`.

Impact to performance should be minimal as the unrestrictied user permissions cache is now used in the `getAllBy*` cases. There is however an additional `SISMEMBER` call per-user fetched rather than a single `SSCAN` and test on the Java side.
@deverton deverton deleted the mem-reduce branch March 4, 2021 20:31
@deverton
Copy link
Contributor Author

deverton commented Mar 4, 2021

To follow up, we've been running this change in production for a while now and the memory reduction is pretty reasonable though it really only affects the peak usage.

Average Max
Before 8 GB 22 GB
After 8 GB 15 GB

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

Successfully merging this pull request may close these issues.

Timeout on /auth/roles/sync with large amount of roles Fiat Role Sync Slow and Requires High Memory
4 participants