Golang redisredigo connection pool

Keywords: Redis Database github

Previously, single connection was used. In practical applications, the function of connection pool is often needed.

However, the support of redigo for connection pool is weak.

Connection pool

The application calls the Get method to Get the connection from the pool and uses the connected Close method to return the connected resources to the pool.

Methods:

1.func NewPool create a new pool note: this method will be removed in later versions, not recommended

2.func (*Pool) ActiveCount returns the number of active connections, including idle and in use connections.

3.func (*Pool) Close close connection

4.func (*Pool) Get get a connection

5.func (*Pool) GetContext GetContext use the context provided to get the connection

6.func (*Pool) IdleCount idle connections

7.func (*Pool) Stats connection pool statistics

For example:

func newPool(addr string) *redis.Pool {
  return &redis.Pool{
    MaxIdle: 3,
    IdleTimeout: 240 * time.Second,
    // Dial or DialContext must be set. When both are set, DialContext takes precedence over Dial.
    Dial: func () (redis.Conn, error) { return redis.Dial("tcp", addr) },
  }
}

var (
  pool *redis.Pool
  redisServer = flag.String("127.0.0.1", ":6379", "")
)

func main() {
  flag.Parse()
  pool = newPool(*redisServer)
  ...
}

The application uses the following:

func serveHome(w http.ResponseWriter, r *http.Request) {
    conn := pool.Get()
    defer conn.Close()
    ...
}

Use the Dial function to verify the connection to the AUTH command, or use the SELECT command to SELECT a database

pool := &redis.Pool{
  // Other pool configuration not shown in this example.
  Dial: func () (redis.Conn, error) {
    c, err := redis.Dial("tcp", server)
    if err != nil {
      return nil, err
    }
    if _, err := c.Do("AUTH", password); err != nil {
      c.Close()
      return nil, err
    }
    if _, err := c.Do("SELECT", db); err != nil {
      c.Close()
      return nil, err
    }
    return c, nil
  },
}

Use the TestOnBorrow function to check the health of idle connections

pool := &redis.Pool{
  // Other pool configuration not shown in this example.
  TestOnBorrow: func(c redis.Conn, t time.Time) error {
    if time.Since(t) < time.Minute {
      return nil
    }
    _, err := c.Do("PING")
    return err
  },
}

Example:

package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
	"time"
	"flag"
)


var (
	pool *redis.Pool
	//redisServer = flag.String("127.0.0.1", ":6379", "")
)


func newPool(addr string) *redis.Pool {
	return &redis.Pool{
		MaxIdle: 3,
		IdleTimeout: 240 * time.Second,
		// Dial or DialContext must be set. When both are set, DialContext takes precedence over Dial.
		Dial: func () (redis.Conn, error) { return redis.Dial("tcp", addr) },
	}
}


func Get() redis.Conn {
	return pool.Get()
}

func main() {
	flag.Parse()
	pool = newPool("127.0.0.1:6379")
	connections := pool.Get()
	defer connections.Close()

	set_res, err := connections.Do("SET", "new_test", "redigo")
	if err != nil {
		fmt.Println("err while set key :", err)
	}else {
		fmt.Println(set_res)
	}

	is_exists, err := redis.Bool(connections.Do("EXISTS", "new_test"))
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(is_exists)
	}
	get_res, err := redis.String(connections.Do("GET", "new_test"))
	if err != nil {
		fmt.Println("get err:", err)
	} else {
		fmt.Println(get_res)
	}

}

Output:

OK
true
redigo

Posted by gilliat on Sat, 26 Oct 2019 10:29:19 -0700