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.
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
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
