Skip to content

Add separate instrumentation for redis.asyncio.client #807

@ahmedhr

Description

@ahmedhr

Reduce overhead of aioredis version when using redis.asyncio

Description
Evaluating the existing aioredis version raises a few exception when aioredis is not installed and since you are not using aioredis this check is invalid now.

Expected Behavior
For redis.asyncio.client, we need to separate out the instrumentation function, currently the aioredis intrumentation is used

Steps to Reproduce
we should have a separate instrument_aioredis_client and _wrap_AioRedis_method_wrapper function for redis.asyncio.client. And remove aioredis_version = get_package_version_tuple("aioredis").

Since get_package_version_tuple raises multiple exceptions and finally go to

            else:
                from redis.asyncio.client import Pipeline

when we execute multiple commands, the overhead is too much, check the below profiling.

import newrelic.agent
import redis.asyncio as redis
import asyncio
import pstats
import time

from redis.asyncio.connection import ConnectionPool

pool = ConnectionPool.from_url('redis://127.0.0.1:6379/?decode_responses=true')

redis_conn = redis.Redis(connection_pool=pool)
newrelic.agent.initialize()

async def profile__nr_wrapper_AioRedis_method_():
    pr = cProfile.Profile()
    pr.enable()

    start_time = time.time()
    for _ in range(1000):
        await redis_conn.get("Test one")

    print(f"Time taken: {time.time() - start_time}")
    pr.disable()
    ps = pstats.Stats(pr).sort_stats("cumulative")
    ps.strip_dirs().print_stats("profile__nr_wrapper_AioRedis_method_")


asyncio.run(profile__nr_wrapper_AioRedis_method_())

Output:

Time taken: 1.4444618225097656
         4708172 function calls (4707770 primitive calls) in 1.438 seconds

   Random listing order was used
   List reduced from 438 to 1 due to restriction <'profile__nr_wrapper_AioRedis_method_'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      202    0.000    0.000    1.343    0.007 kindex_radius.py:128(profile__nr_wrapper_AioRedis_method_)

Total time taken is 1.44 and 1.343 is of nr_wrapper_AioRedis_method

Also get_package_version_tuple is the main culprit of the issue.

and without newrelic.agent.initialize() or installing aioredis*(prevents redis.async.client function to run - A different bug that'll also be solved)

Output without newrelic.agent.initialize() :

Time taken: 0.054537057876586914
         66135 function calls in 0.054 seconds

   Random listing order was used
   List reduced from 218 to 1 due to restriction <'profile__nr_wrapper_AioRedis_method_'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      202    0.000    0.000    0.003    0.000 kindex_radius.py:128(profile__nr_wrapper_AioRedis_method_)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIncorrect or flawed agent behavior.needs-triageRequires initial review by maintainers.staleNo recent activity.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions