Go with Redis
Get latest articles directly in your inbox
If you are aware about both Golang and Redis - you’ll know they both are fast⚡️and easy to learn ✅. Well, Redis is written in C - it is built to be fast right 😉. Who doesn’t want to make their app fast? Let’s dive in to learn using Redis with Golang.
Intro to Redis
In case you are not aware about Redis, Let me introduce by stating official explanation which is quite self explanatory -
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries
Why Redis?
- Fastest in-memory database.
- Open source
- Built-in replication
- Persistent
- Highly stable and used by alll big companies.
Read more on why Redis here.
One of the common use cases of Redis is in caching. Caching is the process of storing some data in a cache which is a temporary storage component where the data is stored. This stored data can then be served for faster responses.
Example - Suppose you maintain a counter which updates on every web page request. This is a frequently used operation. This is exactly where you would use Redis. You would not want to make DB query each time to update and fetch it. (why? because they are slow ⌛️)
Okay, now you probably love redis and are ready to use it. Let’s see how you can use redis in your Go applications.
Using Redis in Go
Let’s create a main.go
- initialize redis and perform basic set/get operation.
Note : We will be using redigo library to use redis in golang. Install it using-
go get github.com/gomodule/redigo/redis
package main
import (
"fmt"
"log"
"github.com/gomodule/redigo/redis"
)
func main() {
// here 6379 is the default port of redis - you can change it if you want!
conn, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
log.Fatal(err)
}
// ensures connection is closed before main() ends
defer conn.Close()
// Here, we set a simple Key-Value with key as name and value as Mohit
// Do sends a command to the server and returns the received reply.
_, err = conn.Do("SET", "name", "Mohit")
if err != nil {
log.Fatal(err)
}
// Retrieve the value we stored and parse as String
name, err := redis.String(conn.Do("GET", "name"))
if err != nil {
log.Fatal(err)
}
fmt.Println(name)
}
On running go run main.go
, we get -
Mohit
Congrats 🎉, you just performed your first redis read/write query.
This was easy, now let’s try to insert and retrieve structs. Here, we create a simple User struct with two attributes - name(string)
and age(int)
.
Update your main.go as below.
package main
import (
"fmt"
"log"
"github.com/gomodule/redigo/redis"
)
type User struct {
Name string `redis:"name"`
Age int `redis:"age"`
}
func main() {
// here 6379 is the default port of redis - you can change it if you want!
conn, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
log.Fatal(err)
}
// ensures connection is closed before main() ends
defer conn.Close()
// Here, we set object has values with key
// HMSET - https://redis.io/commands/hmset
_, err = conn.Do("HMSET", "user:1", "name", "Mohit", "age", 23)
if err != nil {
log.Fatal(err)
}
// Retrieve the individual value we stored and parse as String
name, err := redis.String(conn.Do("HGET", "user:1", "name"))
if err != nil {
log.Fatal(err)
}
// Retrieve the individual value we stored and parse as Int
age, err := redis.Int(conn.Do("HGET", "user:1", "age"))
if err != nil {
log.Fatal(err)
}
// Retrieve whole object at once and parse it as struct.
// You can parse it into a struct using a helper function.
response, err := redis.Values(conn.Do("HGETALL", "user:1"))
if err != nil {
log.Fatal(err)
}
// Parsing into struct
var user User
err = redis.ScanStruct(response, &user)
if err != nil {
log.Fatal(err)
}
fmt.Println(name, age)
fmt.Println(user)
}
On running go run main.go
, we get -
Mohit 23
{Mohit 23}
You get the idea, you can explore other data types in redis and use them.
Note: Conn
object we use is not safe for concurrent use. In production apps, usually a redis Pool connections are used, where each pool executes command and returns the result from different goroutines.
Let’s reimplement the previous code using redis Pool.
package main
import (
"fmt"
"log"
"time"
"github.com/gomodule/redigo/redis"
)
type User struct {
Name string `redis:"name"`
Age int `redis:"age"`
}
// Create a new Pool with certain set of parameters.
// You can modify/add more as per your usecase - https://godoc.org/github.com/gomodule/redigo/redis#Pool
func NewPool(address string, connTimeoutInMs, readTimeoutInMs, maxIdle int) *redis.Pool {
return &redis.Pool{
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", address,
redis.DialConnectTimeout(time.Duration(connTimeoutInMs)*time.Millisecond),
redis.DialReadTimeout(time.Duration(readTimeoutInMs)*time.Millisecond),
)
if err != nil {
return nil, err
}
return c, err
},
IdleTimeout: 240 * time.Second,
MaxIdle: maxIdle,
}
}
func main() {
pool := NewPool("localhost:6379", 100, 100, 3)
// Fetch a single Redis connection from the pool
conn := pool.Get()
// ensures connection is closed before main() ends
defer conn.Close()
// Here, we set a simple Key-Value with key as name and value as Mohit
_, err := conn.Do("HMSET", "user:1", "name", "Mohit", "age", 23)
if err != nil {
log.Fatal(err)
}
// Retrieve the value we stored and parse as String
name, err := redis.String(conn.Do("HGET", "user:1", "name"))
if err != nil {
log.Fatal(err)
}
age, err := redis.Int(conn.Do("HGET", "user:1", "age"))
if err != nil {
log.Fatal(err)
}
response, err := redis.Values(conn.Do("HGETALL", "user:1"))
if err != nil {
log.Fatal(err)
}
var user User
err = redis.ScanStruct(response, &user)
if err != nil {
log.Fatal(err)
}
fmt.Println(name, age)
fmt.Println(user)
}
On running go run main.go
, we get what we expected -
Mohit 23
{Mohit 23}
Explore other Redis Commands -
- DEL - Deleting a Key
- SETEX - Setting a key with an expiry
- RENAME - Renaming the current existing key
- FLUSHALL - Flushing everything so far saved
There are lot of other commands which you can use. Find them here.
I hope you are now ready to use Redis in your applications. Feel free to comment on how you use Redis. Do drop a 👍 and share it with your friends.
Books to learn Golang
Liked the article? Consider supporting me ☕️
I hope you learned something new. Feel free to suggest improvements ✔️
I share regular updates and resources on Twitter. Let’s connect!
Keep exploring 🔎 Keep learning 🚀
Liked the content? Do support :)