Redis介绍
Redis是一个开源的内存数据库,Redis提供了多种不同类型的数据结构,很多业务场景下的问题都可以很自然地映射到这些数据结构上。除此之外,通过复制、持久化和客户端分片等特性,我们可以很方便地将Redis扩展成一个能够包含数百GB数据、每秒处理上百万次请求的系统。
Redis支持的数据结构
Redis支持诸如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、带范围查询的排序集合(sorted sets)、位图(bitmaps)、hyperloglogs、带半径查询和流的地理空间索引等数据结构(geospatial indexes)。
Redis应用场景
- 缓存系统,减轻主数据库(MySQL)的压力。
- 计数场景,比如微博、抖音中的关注数和粉丝数。
- 热门排行榜,需要排序的场景特别适合使用ZSET。
- 利用LIST可以实现队列的功能。
Redis与Memcached比较
Memcached中的值只支持简单的字符串,Reids支持更丰富的5中数据结构类型。 Redis的性能比Memcached好很多 Redis支持RDB持久化和AOF持久化。 Redis支持master/slave模式。
Go操作Redis
安装
Go语言中使用第三方库https://github.com/go-redis/redis连接Redis数据库并进行操作。使用以下命令下载并安装:
go get -u github.com/go-redis/redis
连接
// 声明一个全局的redisdb变量 var redisdb *redis.Client // 初始化连接 func initClient() (err error) { redisdb = redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password set DB: 0, // use default DB }) _, err = redisdb.Ping().Result() if err != nil { return err } return nil }
基本使用
set/get示例
func redisExample() { err := redisdb.Set("score", 100, 0).Err() if err != nil { fmt.Printf("set score failed, err:%v\n", err) return } val, err := redisdb.Get("score").Result() if err != nil { fmt.Printf("get score failed, err:%v\n", err) return } fmt.Println("score", val) val2, err := redisdb.Get("name").Result() if err == redis.Nil { fmt.Println("name does not exist") } else if err != nil { fmt.Printf("get name failed, err:%v\n", err) return } else { fmt.Println("name", val2) } }
zset示例
func redisExample2() { zsetKey := "language_rank" languages := []*redis.Z{ &redis.Z{Score: 90.0, Member: "Golang"}, &redis.Z{Score: 98.0, Member: "Java"}, &redis.Z{Score: 95.0, Member: "Python"}, &redis.Z{Score: 97.0, Member: "JavaScript"}, &redis.Z{Score: 99.0, Member: "C/C++"}, } // ZADD num, err := redisdb.ZAdd(zsetKey, languages...).Result() if err != nil { fmt.Printf("zadd failed, err:%v\n", err) return } fmt.Printf("zadd %d succ.\n", num) // 把Golang的分数加10 newScore, err := redisdb.ZIncrBy(zsetKey, 10.0, "Golang").Result() if err != nil { fmt.Printf("zincrby failed, err:%v\n", err) return } fmt.Printf("Golang‘s score is %f now.\n", newScore) // 取分数最高的3个 ret, err := redisdb.ZRevRangeWithScores(zsetKey, 0, 2).Result() if err != nil { fmt.Printf("zrevrange failed, err:%v\n", err) return } for _, z := range ret { fmt.Println(z.Member, z.Score) } // 取95~100分的 op := &redis.ZRangeBy{ Min: "95", Max: "100", } ret, err = redisdb.ZRangeByScoreWithScores(zsetKey, op).Result() if err != nil { fmt.Printf("zrangebyscore failed, err:%v\n", err) return } for _, z := range ret { fmt.Println(z.Member, z.Score) } } 输出结果如下: $ ./06redis_demo zadd 0 succ. Golang‘s score is 100.000000 now. Golang 100 C/C++ 99 Java 98 JavaScript 97 Java 98 C/C++ 99 Golang 100