Opened 3 weeks ago

Closed 9 days ago

#36879 closed Cleanup/optimization (fixed)

Add Django cache identification to Redis client metadata

Reported by: Vasil Chomakov Owned by: ar3ph
Component: Core (Cache system) Version: dev
Severity: Normal Keywords: redis cache observability
Cc: Vasil Chomakov, ar3ph Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Vasil Chomakov)

Proposal: Add Django cache identification to Redis client metadata

Context

Redis documentation recommends that clients identify themselves via connection metadata to help operators monitor, debug, and reason about production systems (for example using CLIENT SETINFO / CLIENT INFO):

https://redis.io/docs/latest/commands/client-setinfo/

This information is intended to help Redis operators understand what software is connecting to their servers, especially in shared or multi-tenant environments.

Django’s Redis cache backend is built on top of redis-py, which means Redis connections created by Django are currently indistinguishable from other redis-py-based clients in shared Redis deployments. This makes it harder for Redis operators to attribute traffic, diagnose issues, or understand cache usage patterns when multiple applications or frameworks share the same Redis instance.

Proposal

Django could provide additional, non-invasive client identification for Redis cache connections to indicate that the connection originates from Django’s cache framework.

redis-py exposes a driver_info API that may be used to attach Django-specific context to the connection, in line with Redis’s client identification recommendations.

Goals

  • Align with Redis client identification best practices
  • Allow Redis operators to distinguish Django cache connections
  • Improve observability in shared Redis environments

Example (illustrative)

A Redis connection created by Django’s cache backend might expose metadata equivalent to:

  • Client library: redis-py
  • Framework: django-cache

Scope

  • This is a feature proposal, not a patch submission
  • No behavioral changes to caching semantics are proposed
  • Any implementation would rely solely on redis-py’s supported APIs

Change History (17)

comment:1 by Vasil Chomakov, 3 weeks ago

Description: modified (diff)

comment:2 by ar3ph, 3 weeks ago

I poked around and got a working solution. Although in future versions of redis-py, lib_name and lib_version are deprecated, DriverInfo is not available for latest redis-py release v7.1.0.

In django/core/cache/backends/redis.py:

class RedisCacheClient:
    def _get_connection_class(self, lib):
        class DjangoConnection(lib.Connection):
            def __init__(self, *args, **kwargs):
                super().__init__(*args, **kwargs)
                self.lib_name = "django"
                self.lib_version = django.get_version()

        return DjangoConnection
   def __init__(
        servers,
        serializer=None,
        pool_class=None,
        parser_class=None,
        **options,
    ):
    ...
    
    self._connection_class = self._get_connection_class(self._lib)
    ...
    self._pool_options = {
            "parser_class": parser_class,
            "connection_class": self._connection_class,
            **options,
        }

I can make a PR once this ticket is accepted. And we'll have to update again once DriverInfo for redis-py is released.

comment:3 by ar3ph, 3 weeks ago

Cc: ar3ph added

comment:4 by ar3ph, 3 weeks ago

or I can make it default to use driver_info when lib_name and lib_ver are no longer supported.

comment:5 by ar3ph, 3 weeks ago

Has patch: set

comment:6 by Vasil Chomakov, 3 weeks ago

I suggest using DriverInfo when available (can be successfully imported) and falling back to lib_name and lib_version if redis-py does not yet support it.

IMPORTANT: Note that when manually set, lib_name and lib_version should look like this:

  • lib_name = redis-py(django-cache_v{django-cache-version})
  • lib_version = {redis-py-version}

per Redis CLIENT SETINFO documentation: https://redis.io/docs/latest/commands/client-setinfo/

comment:7 by ar3ph, 3 weeks ago

Here is a django-redis example. Perhaps the best solution is to just change the lib-name to include our upstream driver.

The lib-name will become like redis-py(django_v6.1.0)

in reply to:  6 comment:8 by ar3ph, 3 weeks ago

Replying to Vasil Chomakov:

I suggest using DriverInfo when available (can be successfully imported) and falling back to lib_name and lib_version if redis-py does not yet support it.

IMPORTANT: Note that when manually set, lib_name and lib_version should look like this:

  • lib_name = redis-py(django-cache_v{django-cache-version})
  • lib_version = {redis-py-version}

per Redis CLIENT SETINFO documentation: https://redis.io/docs/latest/commands/client-setinfo/

Should the driver be called django-cache? My opinion is to just call it django, b/c django-cache is not a separated package.

comment:9 by Vasil Chomakov, 3 weeks ago

I agree, django_v{django-version} is descriptive enough.
So when using DriverInfo, just setting the upstream driver to django_v6.1.0 would suffice.
When DriverInfo is not available:

  • lib_name = redis-py(django_v6.1.0)
  • lib_version = {redis-py-version}

in reply to:  9 comment:10 by ar3ph, 3 weeks ago

Replying to Vasil Chomakov:

I agree, django_v{django-version} is descriptive enough.
So when using DriverInfo, just setting the upstream driver to django_v6.1.0 would suffice.
When DriverInfo is not available:

  • lib_name = redis-py(django_v6.1.0)
  • lib_version = {redis-py-version}

I finished this in the proposed PR. Note that lib_version defaults to redis-py version. So nothing for us to do there.

Last edited 3 weeks ago by ar3ph (previous) (diff)

comment:11 by Harsh007, 3 weeks ago

Owner: set to Harsh007
Status: newassigned

comment:12 by ar3ph, 3 weeks ago

Owner: changed from Harsh007 to ar3ph

comment:13 by Jacob Walls, 13 days ago

Patch needs improvement: set
Triage Stage: UnreviewedAccepted
Type: New featureCleanup/optimization

The request makes sense, but I'm not sure we've identified the least invasive solution.

comment:14 by ar3ph, 13 days ago

Thanks. I'll look into the implementation.

comment:15 by ar3ph, 13 days ago

I've updated my PR to avoid dynamic class creation, only changing the pool_options now as a better alternative.

comment:16 by Jacob Walls, 10 days ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:17 by Jacob Walls <jacobtylerwalls@…>, 9 days ago

Resolution: fixed
Status: assignedclosed

In 72ae25a:

Fixed #36879 -- Identified Django client in Redis client metadata.

Note: See TracTickets for help on using tickets.
Back to Top