How To Use Redis with Golang

How To Use Redis with Golang

How To Use Redis with Golang

Utilizing Redis with Golang is easy and can have dramatic affects on the performance of your application.

Redis is an open source, in-memory data structure store, used as a database, cache and message broker. Redis supports a number of data structures including strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs and more. The advantages of using Redis over other caching stores, such as Memcached, is that Redis offers persistence.

There are many ways the use of Redis can enhance the performance of your Golang application. some example are below:

  • Application cache. When an application process uses an external data source, its performance can be bottlenecked by the throughput and latency of said data source. When a slower external data source is used, frequently accessed data is often moved temporarily to a faster storage that is closer to the application to boost the application’s performance. This faster intermediate data storage is called the application’s cache.

  • Show your newest items using a live in-memory cache which is very fast. LPUSH is used to insert a content ID at the head of the list stored at a key. LTRIM is used to limit the number of items in the list to 500. If the customer needs to page beyond this cache only then are they sent to the database.

  • Keeping statistics of all kinds is common, say you want to keep track of visitors to a particular item. The INCRBY command makes it easy to atomically keep counters; GETSET to atomically clear the counter; the expire attribute can be used to tell when a key should be deleted.

  • Session Cache. One common use cases for Redis is using it as a session cache. Caching user session data is an integral part of building responsive applications that can scale. Because every user interaction requires access to the session’s data, keeping it in the cache ensures the fastest response times to the application user.

  • Real time analysis, for sessions, stats, anti spam and more. Using Redis primitives, it’s much simpler to implement a session or other real-time tracking system.

  • Pub/Sub. Keeping a map of who is interested in updates to what data is a common task in systems. Redis has a pub/sub feature to make this easy by using commands like SUBSCRIBE, UNSUBSCRIBE, and PUBLISH.

  • Queues. Queues are useful in many cases. In addition to the push and pop type commands, Redis has blocking queue commands, so a program can wait on work being added to the queue by another program.

Connecting to Redis with Golang

By using one of the available Redis / Golang drivers, you can easily communicate with a Redis databases.

For example, if you would like to connect Redis, then you would use the generic SQL package that exists in the Golang standard library and also a Redis specific package which makes use of the standard library package methods and interfaces.

One of the available Redis drivers is the Redigo Go client for Redis.(https://github.com/garyburd/redigo)

The Redigo Pool struct maintains a pool of Redis connections. The application calls the Get method to get a connection from the pool and the connection’s Close method to return the connection’s resources to the pool.

func newPool() *redis.Pool {
return &redis.Pool{
	MaxIdle:   80,
	MaxActive: 12000, // max number of connections
	Dial: func() (redis.Conn, error) {
        c, err := redis.Dial("tcp", ":6379")
        if err != nil {
            panic(err.Error())
        }
        return c, err
	},
}
    }
var pool = newPool()
c := pool.Get()
defer c.Close()

The Redigo package has a print-like API with support for all Redis commands, which makes makes executing Redis commands from your Golang application easy.

The Conn interface has a generic method for executing Redis commands:

Do(commandName string, args ...interface{}) (reply interface{}, err error)

The Redis command reference at (http://redis.io/commands) lists the available commands. An example of using the Redis APPEND command is:

n, err := c.Do("APPEND", "key", "value")

Pipelining

Redis Connections support pipelining using the Send, Flush and Receive methods.

Send(commandName string, args ...interface{}) error
Flush() error
Receive() (reply interface{}, err error)

Send writes the command to the connection’s output buffer. Flush flushes the connection’s output buffer to the server. Receive reads a single reply from the server. The following example shows a simple pipeline.

c.Send("SET", "foo", "bar")
c.Send("GET", "foo")
c.Flush()
c.Receive() // reply from SET
v, err = c.Receive() // reply from GET

The Do method of the Redigo package combines the functionality of the Send, Flush and Receive methods. The Do method starts by writing the command and flushing the output buffer. Next, the Do method receives all pending replies including the reply for the command just sent by Do. If any of the received replies is an error, then Do returns the error.

c.Send("MULTI")
c.Send("INCR", "foo")
c.Send("INCR", "bar")
r, err := c.Do("EXEC")
fmt.Println(r) // prints [1, 1]

Scan

The Redigo Scan function copies from src to the values pointed at by dest.

func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error)

Scan uses RedisScan if available, otherwise: The values pointed at by dest must be an integer, float, boolean, string, []byte, interface{} or slices of these types. Scan uses the standard strconv package to convert bulk strings to numeric and boolean types.

If a dest value is nil, then the corresponding src value is skipped.

If a src element is nil, then the corresponding dest value is not modified.

To enable easy use of Scan in a loop, Scan returns the slice of src following the copied values.

String function

func String(reply interface{}, err error) (string, error)

String is a helper function that converts a Redis command reply to a string. If err is not equal to nil, then String returns “”, err. Otherwise String converts the reply to a string.

c.Do("SET", "hello", "world")
s, err := redis.String(c.Do("GET", "hello"))
fmt.Printf("%#v\n", s)

Output:

"world"

Hopefully, as you can see, working with and getting the benefit of Redis high performance databases with Golang is easy.

comments powered by Disqus