redis在golang中采用来做缓存,下面提供golang操作redis实例。
示例
基础使用
package main
import (
"log"
"time"
"github.com/gomodule/redigo/redis"
)
func main() {
conn, err := redis.Dial("tcp", "100.80.0.128:6379", redis.DialPassword("foobared"))
if err != nil {
log.Fatal(err)
}
defer conn.Close()
keys, _ := redis.Strings(conn.Do("keys", "*"))
log.Println(keys)
//conn.Do("set", "abc:starttime", time.Now().Format("2006-01-02 15:04:05"), "NX")
conn.Do("set", "abc:starttime", time.Now().Format("2006-01-02 15:04:05"))
starttime, _ := redis.String(conn.Do("GET", "abc:starttime"))
log.Println(starttime)
for i := 0; i < 10; i++ {
conn.Do("LPUSH", "abc:list", i)
}
for i := 0; i < 11; i++ {
r, err := redis.Int64(conn.Do("rpop", "abc:list"))
if err == nil {
log.Println(r)
} else {
log.Println(err)
}
}
//for i := 0; i < 2; i++ {
// log.Println(redis.Strings(conn.Do("BRPOP", "abc:list", 0)))
// log.Println(redis.StringMap(conn.Do("BRPOP", "abc:list", 0)))
//}
// map
//conn.Do("hmset", "abc:set", "key1", "val1", "key2", "val2", "key3", "val3")
conn.Do("hmset", "abc:set", redis.Args{}.Add("key1").Add("val1").Add("key2").Add("val2"))
s, _ := redis.StringMap(conn.Do("hgetall", "abc:set"))
log.Println(s)
}
队列
redis 分布式锁实现示例
package main
import (
"flag"
"fmt"
"log"
"math/rand"
"os"
"time"
"github.com/gomodule/redigo/redis"
"github.com/google/uuid"
)
var (
lockKey = "abc:consumer:master"
)
func getRedisConn() (redis.Conn, error) {
conn, err := redis.Dial("tcp", "100.80.0.128:6379", redis.DialPassword("foobared"))
if err != nil {
log.Fatal(err)
return nil, nil
}
return conn, nil
}
// Productor 生产者
func Productor() {
if conn, err := getRedisConn(); err == nil {
defer func(conn redis.Conn) {
err := conn.Close()
if err != nil {
log.Fatal("close redis connection for productor err", err)
}
log.Println("custom redis connection for productor closed.")
}(conn)
pid := os.Getegid()
for {
time.Sleep(time.Second * time.Duration(rand.Intn(10)))
v := fmt.Sprintf("%d %s", pid, time.Now().Format("2006-01-02 15:04:05"))
conn.Do("lpush", "abc:tasks", v)
log.Println("push", v)
}
} else {
log.Fatal(err)
}
}
// Consumer 消费者
func Consumer() {
conn, err := getRedisConn()
if err != nil {
log.Println(err)
return
}
defer func(conn redis.Conn) {
err := conn.Close()
if err != nil {
log.Fatal("close redis connection for consumer err", err)
}
log.Println("custom redis connection for consumer closed.")
}(conn)
for {
ruid, err := redis.String(conn.Do("get", lockKey))
if err != nil || ruid != uid {
log.Println("I am Slaver")
time.Sleep(5 * time.Second)
continue
}
if str, err := redis.Strings(conn.Do("brpop", "abc:tasks", 2)); err != nil {
continue
} else {
log.Printf("%#v\n", str)
}
}
}
var (
t string
uid string
)
func init() {
flag.StringVar(&t, "t", "p", "[p|c] productor or customer")
flag.Parse()
uid = uuid.New().String()
}
func main() {
rand.Seed(time.Now().Unix())
conn, err := getRedisConn()
if err != nil {
log.Println(err)
return
}
defer func(conn redis.Conn) {
err := conn.Close()
if err != nil {
log.Fatal("close redis connection for lock err", err)
}
log.Println("custom redis connection for lock closed.")
}(conn)
// 分布式锁,保证消费者只有一个
go func() {
ticker := time.NewTicker(time.Second * 20)
for {
ok, err := redis.String(conn.Do("set", lockKey, uid, "EX", 25, "NX"))
if err != nil || ok != "OK" {
ruid, err := redis.String(conn.Do("get", lockKey))
if err == nil && ruid == uid {
log.Println("I am Master, get")
// 续期
ok, err := conn.Do("Expire", lockKey, 30)
if err != nil {
log.Println("expire---", ok, err)
return
}
} else {
log.Println("I am Slave")
}
} else {
log.Println("I am Master, set")
}
<-ticker.C
}
}()
if t == "p" {
log.Println("start Productor...")
Productor()
} else {
log.Println("start Consumer...")
Consumer()
}
}