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

feat(balancer) add path, uri_capture, and query as hash sources #8701

Merged
merged 1 commit into from
Jun 1, 2022

Conversation

flrgh
Copy link
Contributor

@flrgh flrgh commented Apr 19, 2022

This adds path, uri_capture, and query_arg as hash sources for upstreams.

There are some code simplicity vs performance vs absolute correctness tradeoffs to consider here:

  • path sources its value from $uri, which is normalized according to NGINX rules and not kong.tools.uri.normalize($request_uri). The balancer hash is not directly exposed via any public API and is much less sensitive to compatibility issues than other areas of the codebase (i.e. kong.router), so I think it's okay to not be 100% consistent here.
  • query_arg uses ngx.req.get_uri_args, which is semi-expensive as it creates a new table (similar to hash_on_header now). A feature of an upcoming OpenResty release allows optimizing away the table creation (link), which I've accounted for. The benefit of doing this over using ngx.var.arg_{{name}} is that NGINX handles decoding for us, and that it works for multi-value query string args.

@flrgh flrgh requested a review from a team as a code owner April 19, 2022 18:36
@flrgh flrgh force-pushed the feat/new-balancer-hash-sources branch 2 times, most recently from 07b54f8 to 314c86f Compare April 19, 2022 19:53
@RobSerafini RobSerafini requested a review from locao May 6, 2022 21:12
@RobSerafini RobSerafini added this to the 3.0 milestone May 6, 2022
@flrgh flrgh force-pushed the feat/new-balancer-hash-sources branch 2 times, most recently from 1221be5 to d96568d Compare May 11, 2022 00:04
@flrgh flrgh force-pushed the feat/new-balancer-hash-sources branch 2 times, most recently from 4e86042 to 8c5a917 Compare May 11, 2022 16:38
Copy link
Member

@Tieske Tieske left a comment

Choose a reason for hiding this comment

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

Why would one use a path as the hash input? that doesn't make sense to me. Wouldn't it be better to enable using a path-parameter?

Say I have 20 paths defined, all starting like this; /myapp/[userid]/.... Now the cardinality of the hash is high because there are 20 individual paths, each getting their own hash.

If we'd use just the captured [userid] element, we'd ensure that all traffic related to a single user would end up on a single backend. This would make more sense imo.

That said, I don't know the origin of this request.

kong/runloop/balancer/init.lua Show resolved Hide resolved
@flrgh
Copy link
Contributor Author

flrgh commented May 13, 2022

Why would one use a path as the hash input? that doesn't make sense to me. Wouldn't it be better to enable using a path-parameter?

Say I have 20 paths defined, all starting like this; /myapp/[userid]/.... Now the cardinality of the hash is high because there are 20 individual paths, each getting their own hash.

If we'd use just the captured [userid] element, we'd ensure that all traffic related to a single user would end up on a single backend. This would make more sense imo.

Agree 100%

That said, I don't know the origin of this request.

Ah, you're one step ahead of me in my explanation 😉. This request comes from an enterprise customer who has explicitly named path as one of their use-cases.

@flrgh flrgh changed the title feat(balancer) add path and query as hash sources feat(balancer) add path, uri_capture, and query as hash sources May 13, 2022
@flrgh
Copy link
Contributor Author

flrgh commented May 13, 2022

@Tieske I've added router URI capture support :)

The work for supporting path is already done and it has minimal impact (no new entity fields/migrations like query/URI capture), so I've left it in for now. It's probably not as useful as URI capture but IMO still has valid use cases.

@flrgh flrgh requested a review from Tieske May 13, 2022 16:55
@Tieske
Copy link
Member

Tieske commented May 16, 2022

The work for supporting path is already done and it has minimal impact (no new entity fields/migrations like query/URI capture), so I've left it in for now. It's probably not as useful as URI capture but IMO still has valid use cases.

What usecase would they be useful for?

@flrgh
Copy link
Contributor Author

flrgh commented May 16, 2022

The work for supporting path is already done and it has minimal impact (no new entity fields/migrations like query/URI capture), so I've left it in for now. It's probably not as useful as URI capture but IMO still has valid use cases.

What usecase would they be useful for?

It's the same use-case as uri_capture in my opinion: send repeat, homogeneous requests to the same upstream target in order to account for transient state and/or maximize cache hit ratio. If I'm a user with this goal, but I don't need the level of control that uri_capture would provide, I can just use path.

@flrgh flrgh force-pushed the feat/new-balancer-hash-sources branch from 2c8c1d8 to 34ba8bf Compare May 16, 2022 18:23
Copy link
Member

@Tieske Tieske left a comment

Choose a reason for hiding this comment

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

still not convinced about the path option, I'm afraid it's bloat. Then again it's minimal and isolated in a specific corner of the code. So not that big a deal.

@flrgh flrgh added the pr/ready This PR is considered ready and can be merged at anytime (given it received no subsequent changes) label May 20, 2022
@flrgh flrgh force-pushed the feat/new-balancer-hash-sources branch from 34ba8bf to a802b1f Compare May 25, 2022 18:36
@flrgh
Copy link
Contributor Author

flrgh commented May 25, 2022

rebased onto latest master + fixed merge conflicts

@flrgh flrgh force-pushed the feat/new-balancer-hash-sources branch from a802b1f to d519d81 Compare May 25, 2022 20:57
@flrgh flrgh added pr/do not merge and removed pr/ready This PR is considered ready and can be merged at anytime (given it received no subsequent changes) labels May 31, 2022
@flrgh
Copy link
Contributor Author

flrgh commented May 31, 2022

Kong moderators: please hold off on merge for one more rebase+test cycle. I didn't think we'd be upgrading to OpenResty 1.21.4 in this release cycle, so I'm going to remove the version gate on this perf optimization and rebase+re-push. One moment...

EDIT: Code change is done--good to go after CI finishes.

@flrgh flrgh force-pushed the feat/new-balancer-hash-sources branch from d519d81 to 5b7b46e Compare May 31, 2022 16:56
@flrgh flrgh force-pushed the feat/new-balancer-hash-sources branch from 5b7b46e to 3a094d0 Compare May 31, 2022 17:06
@flrgh flrgh added pr/ready This PR is considered ready and can be merged at anytime (given it received no subsequent changes) and removed pr/do not merge labels May 31, 2022
@flrgh
Copy link
Contributor Author

flrgh commented Jun 1, 2022

@aboudreault anything else I should address before merge, or is this good to go?

@aboudreault
Copy link
Contributor

what's left to do will be in EE so you can merge

@aboudreault aboudreault merged commit 4ca9ce4 into master Jun 1, 2022
@aboudreault aboudreault deleted the feat/new-balancer-hash-sources branch June 1, 2022 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog core/balancer core/db/migrations core/db pr/ready This PR is considered ready and can be merged at anytime (given it received no subsequent changes) size/XL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants