redis/go-redis

CLIENT SETNAME not working for idle connections.

akshayk-ktk opened this issue · 5 comments

Expected Behavior

If there are connections made by the client to the redis server and redis options client name is specified then all the connections should have the client name.

Current Behavior

Only a few connections which get used get assigned the client name.

Steps to Reproduce

  1. Start Redis Server on local.
  2. Run the go script given below.
  3. Check the client list.

Context (Environment)

Example is given from local redis but same issue I am facing in elasticache redis also. The number of connections were crossing threshold and we were getting alerts.

Wanted to check which applications were using most connections but found out that connection name is not available when doing client list.

Detailed Description

I have tried for both redis.Client and redis.ClusterClient and facing issue for both.

Not sure if this is the expected behaviour or a bug, any help here is much appreciated.

go-redis version - github.com/redis/go-redis/v9 v9.5.3

package main

import (
	"context"
	"log"
	"time"

	"github.com/redis/go-redis/v9"
)

func main() {
	options := redis.Options{
		Network:      "tcp",
		Addr:         ":6379",
		ClientName:   "local-go-client",
		PoolSize:     20,
		PoolTimeout:  1 * time.Minute,
		MinIdleConns: 10,
		MaxIdleConns: 15,
		OnConnect: func(ctx context.Context, cn *redis.Conn) error {
			status, err := cn.ClientSetName(ctx, "local-go-client").Result()
			if err != nil {
				log.Println("err", err)
				return err
			}
			log.Println("setname status is", status)
			return nil
		},
	}
	c := redis.NewClient(&options)

	ctx := context.Background()
	pingReply, err := c.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}

	log.Println("Ping Reply", pingReply)

	time.Sleep(5 * time.Minute)
}

OS - MacOS Sonoma 14.6.1

Redis Server Output

admin:testing % redis-server                                                                          
34445:C 14 Sep 2024 01:24:58.875 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
34445:C 14 Sep 2024 01:24:58.875 * Redis version=7.2.5, bits=64, commit=00000000, modified=0, pid=34445, just started
34445:C 14 Sep 2024 01:24:58.875 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
34445:M 14 Sep 2024 01:24:58.876 * Increased maximum number of open files to 10032 (it was originally set to 256).
34445:M 14 Sep 2024 01:24:58.876 * monotonic clock: POSIX clock_gettime
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 7.2.5 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 34445
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           https://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

34445:M 14 Sep 2024 01:24:58.876 # WARNING: The TCP backlog setting of 511 cannot be enforced because kern.ipc.somaxconn is set to the lower value of 128.
34445:M 14 Sep 2024 01:24:58.877 * Server initialized
34445:M 14 Sep 2024 01:24:58.877 * Ready to accept connections tcp

Client List Output

image
package main

import (
	"context"
	"log"
	"time"

	"github.com/redis/go-redis/v9"
)

func main() {
	options := redis.Options{
		Network:      "tcp",
		Addr:         ":6379",
		ClientName:   "local-go-client",
		PoolSize:     20,
		PoolTimeout:  1 * time.Minute,
		MinIdleConns: 10,
		MaxIdleConns: 15,
		OnConnect: func(ctx context.Context, cn *redis.Conn) error {
			status, err := cn.ClientSetName(ctx, "local-go-client").Result()
			if err != nil {
				log.Println("err", err)
				return err
			}
			log.Println("setname status is", status)
			return nil
		},
		OnClose: func(ctx context.Context, cn *redis.Conn) error {
			// Ensure the client name is set for idle connections too
			_, err := cn.ClientSetName(ctx, "local-go-client").Result()
			if err != nil {
				log.Println("Error setting client name for idle connection:", err)
			}
			return nil
		},
	}
	c := redis.NewClient(&options)

	ctx := context.Background()
	pingReply, err := c.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}

	log.Println("Ping Reply", pingReply)

	// Keep the connection alive for testing
	time.Sleep(5 * time.Minute)
}

Hi @ljluestc ,

I did not find the OnClose key in the fields in the redis options. Can you confirm what version are you using?

I have the same problem with @akshayk-ktk and didn't find any onClose hook that can be attached, as mentioned by @ljluestc

I am encountering the same issue. I would like to track down and understand who is connecting to my Elasticache instance while working on a connection pool monitoring. Majority of my connections in idle are nameless. I'm glad I encountered this issue because I feel like I configured my code appropriately but I can't account for these nameless connections.

Example Output:

(unnamed),10.107.130.66,11
(unnamed),10.107.138.163,19
(unnamed),10.107.143.37,14
jobclient,10.107.130.66,1
jobclient,10.107.138.163,1
jobclient,10.107.143.37,4
jobprocessor,10.107.130.66,8
jobprocessor,10.107.138.163,3
jobprocessor,10.107.143.37,2
web,10.107.130.66,8
web,10.107.138.163,7
web,10.107.143.37,9