Skip to content

Proposal/Idea: Decouple upstream and downstream metrics #10970

@FAYiEKcbD0XFqF2QK2E4viAHg8rMm2VbjYKdjTg

Description

I have been thinking about a problem I’ve been trying to solve with respect to Redis upstream command stats, and I think there might be an opportunity for a more general solution to decouple stats for downstreams and upstreams.

The Redis-specific problem is that per-command stats were downstream specific and did not reflect traffic mirrored to multiple upstreams ie 1 downstream N upstreams. The mirroring use-case can have both M downstreams- health-checks, multiple proxies, discovery- and N upstreams. I implemented upstream-specific RedisCommandStats and left a todo to organize them better- ie perhaps use a singleton so as to avoid passing down the stats object through every layer of the Redis filter. However, given that we have multiple filters- proxies (multiple, especially with mirroring), healthchecks, etc., it's still not ideal.

My idea is to make use of some sort of context that can be shared between multiple filters. At present, each Redis filter has its own connection pool per cluster, though Henry is working on sharing the connection pool (by using the standard tcp connection pool) between filters so as to reduce connection volume. Each filter has access to the Envoy cluster objects- which can either be a standard Envoy cluster, or a special version designed to handle the Redis Cluster protocol. It would be bad to add Redis-specific stats to the general case, but we could add a general-purpose map to ClusterInfo. This map could be used for filter-specific purposes, in this case adding a Redis-specific shared stats object for use between all of the Redis filters. This would allow us to share symbolized stat names and avoid passing around stats objects in the filters- we could just call the clusterInfo and get the stats object.

Questions:

  • Is stats upstream/downstream decoupling useful for stuff outside of Redis?
  • Would adding the metrics to the cluster be useful for code simplification outside of Redis?

I’ve put up a draft PR that demonstrates the basics of registering upstream specific data on the more general cluster object. This allows you to register at cluster setup time various classes that you want to use in specific filters, and then at request time instead of doing a lazy load with lock just check if whatever upstream-specific class your filter uses is actually there, and if null ignore. I would greatly appreciate feedback on if this is a worthwhile idea and a reasonable approach: HenryYYang#7

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions