Databases 8 min read

Boost Ranking Performance with Redis Sorted Sets and Go

This article explains why MySQL struggles with large‑scale ranking, introduces Redis sorted sets as a high‑performance alternative, and provides complete Go code examples—including direct command usage and a struct‑based wrapper—to implement, query, and manage ranked data efficiently.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Boost Ranking Performance with Redis Sorted Sets and Go

Why use Redis sorted sets for ranking

Ranking is a common requirement, but using MySQL for large data sets wastes performance. Redis sorted sets (ZSET) provide an efficient way to store and retrieve ordered scores.

Key Redis commands

zrange – view ranking in ascending order

zrevrange – view ranking in descending order

zadd – add a member with a score

zrem – remove a member

zrank – get rank (ascending)

zrevrank – get rank (descending)

Simple Go example using raw commands

c1, err := redis.Dial("tcp", "127.0.0.1:6379")
if err != nil {
    panic(err)
}
defer c1.Close()
_, err = c1.Do("zrange", "rank_name", "0", "-1", "withscores")
if err != nil {
    return
}
for i := 0; i < 100; i++ {
    c1.Do("zadd", "rank_name", rand.Intn(1000), "张"+strconv.Itoa(i))
}
do, err := redis.ByteSlices(c1.Do("zrange", "rank_name", 0, -1, "withscores"))
if err != nil {
    return
}
for _, v := range do {
    fmt.Println(string(v))
}

The execution result shows data sorted by score.

Basic Redis helper functions

package main

import (
    "fmt"
    "github.com/garyburd/redigo/redis"
)

func main() {
    conn := redisConnect()
    defer conn.Close()
    setString(conn, "country", "China")
    getString(conn, "country")
}

func redisConnect() redis.Conn {
    conn, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("connect redis error:", err)
        return nil
    }
    fmt.Println("connect redis success!")
    return conn
}

func setString(conn redis.Conn, field string, value interface{}) {
    _, _ = conn.Do("SET", field, value)
}

func getString(conn redis.Conn, field string) {
    res, _ := redis.String(conn.Do("GET", field))
    fmt.Printf("Get %s: %s 
", field, res)
}

Struct‑based wrapper for Redis operations

package main

import (
    "fmt"
    "github.com/garyburd/redigo/redis"
    "log"
    "reflect"
)

func main() {
    conn := RedisConnect()
    defer conn.Close()
    db := Conn{conn}
    db.SetSortSet("score", 96, "Coulson")
    db.SetSortSet("score", 92, "Tom")
    db.SetSortSet("score", 97, "Jack")
    fmt.Println(db.GetSortSetLength("score"))
    nameRank, scoreRank := db.RankSortSet("score", "asc")
    fmt.Println(nameRank, scoreRank)
    fmt.Println(db.GetSortSetByField("score", "Tom"))
}

func RedisConnect() redis.Conn {
    conn, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("connect redis error:", err)
        return nil
    }
    fmt.Println("connect redis success!")
    return conn
}

type Conn struct {
    redis.Conn
}

func (c *Conn) DelKey(key string) {
    _, err := c.Do("DEL", key)
    if err != nil {
        log.Printf("Failed to del the key: %s 
", key)
    }
    fmt.Printf("success to del the key: %s! 
", key)
}

func (c *Conn) SetSortSet(key string, value int, field string) {
    _, err := c.Do("ZADD", key, value, field)
    if err != nil {
        log.Printf("Already exist duplicate keys: `%s` 
", key)
        panic(err)
    }
    log.Printf("success to set key: %s %d %s", key, value, field)
}

func (c *Conn) GetSortSetLength(key string) interface{} {
    res, err := c.Do("ZCARD", key)
    if err != nil {
        panic(err)
    }
    return res
}

func (c *Conn) RankSortSet(key string, limit interface{}) (nameArr []string, valueArr []string) {
    cmd, index := "ZREVRANGE", -1
    switch {
    case limit == "asc":
        cmd = "ZRANGE"
        index = -1
    case limit == "desc":
        cmd = "ZREVRANGE"
        index = -1
    case reflect.TypeOf(limit).Name() == "int" && int(reflect.ValueOf(limit).Int()) > 0:
        index = int(reflect.ValueOf(limit).Int()) - 1
    default:
        cmd = "ZREVRANGE"
        index = -1
    }
    scoreMap, err := redis.StringMap(c.Do(cmd, "score", 0, index, "withscores"))
    if err != nil {
        log.Printf("Failed to rank by key %s 
", key)
    }
    for name := range scoreMap {
        nameArr = append(nameArr, name)
        valueArr = append(valueArr, scoreMap[name])
    }
    return nameArr, valueArr
}

func (c *Conn) GetSortSetByField(field string, value interface{}) interface{} {
    res, err := redis.Int(c.Do("ZSCORE", field, value))
    if err != nil {
        log.Printf("can't find %v of %v 
", field, value)
    }
    return res
}

func (c *Conn) DelSortSetByField(field string, value interface{}) interface{} {
    res, err := c.Do("ZREM", field, value)
    if err != nil {
        log.Printf("failed to del %v by %v 
", field, value)
    }
    return res
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

RedisGorankingSorted Set
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.