登录redis数据库
redis-cli -h 127.0.0.1 -p 6379 -a xxx (-a 密码)
查看redis版本
redis-cli -v
验证redis安装成功
redis 127.0.0.1:6379>PING
PONG
初始化redis
方式一:
import (
"github.com/go-redis/redis"
)
func main () {
// 初始化时可以指定连接redis的读写超时时间,默认都是3s
client := redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "root",
DB: 0,
})
//延迟到程序结束关闭链接
defer client.Close()
//ping
pong, err := client.Ping().Result()
if err != nil {
fmt.Println("ping error", err.Error())
return
}
fmt.Println("ping result:", pong)
}
方式二:
import (
"github.com/gomodule/redigo/redis"
"time"
"fmt"
)
type Redis struct {
pool *redis.Pool
}
var redis *Redis
//MaxIdle: 池子里的最大空闲连接数
//MaxActive:池子里最大可用连接数
//IdleTimeout: 超过这个duration的空闲连接,会被关闭
//DialReadTimeout:读取redis数据的超时时间
//DialWriteTimeout:写入redis数据的超时时间
//DialConnectTimeout:连接redis的超时时间
func initRedis() {
redis = new(Redis)
redis.pool = &redis.Pool{
MaxIdle: 256,
MaxActive: 0,
IdleTimeout: time.Duration(120),
Dial: func() (red.Conn, error) {
return red.Dial(
"tcp",
"127.0.0.1:6379",
redis.DialReadTimeout(time.Duration(1000)*time.Millisecond),
redis.DialWriteTimeout(time.Duration(1000)*time.Millisecond),
redis.DialConnectTimeout(time.Duration(1000)*time.Millisecond),
)
},
}
}
redis锁
github链接:https://github.com/bsm/redislock
import (
"fmt"
"time"
"github.com/bsm/redislock"
"github.com/go-redis/redis/v7"
)
func main() {
// Connect to redis.
client := redis.NewClient(&redis.Options{
Network: "tcp",
Addr: "127.0.0.1:6379",
})
defer client.Close()
// Create a new lock client.
locker := redislock.New(client)
// Try to obtain lock.
// RetryCount是重试次数,RetryBackoff重试的间隔时间
option := redislock.Options{
RetryCount: 1,
RetryBackoff: 100ms,
Metadata: "",
Context: nil,
}
// Obtain第一个参数是key,第二个参数是获取锁的时间100s,超时后自动释放
lock, err := locker.Obtain("key", 100*time.Second, option)
if err == redislock.ErrNotObtained {
fmt.Println("Could not obtain lock!")
} else if err != nil {
log.Fatalln(err)
}
// Don't forget to defer Release.
defer lock.Release()
fmt.Println("I have a lock!")
// Sleep and check the remaining TTL.
time.Sleep(50 * time.Second)
if ttl, err := lock.TTL(); err != nil {
log.Fatalln(err)
} else if ttl > 0 {
fmt.Println("Yay, I still have my lock!")
}
// Extend my lock.
if err := lock.Refresh(100*time.Millisecond, nil); err != nil {
log.Fatalln(err)
}
// Sleep a little longer, then check.
time.Sleep(100 * time.Millisecond)
if ttl, err := lock.TTL(); err != nil {
log.Fatalln(err)
} else if ttl == 0 {
fmt.Println("Now, my lock has expired!")
}
}
redis存储的5种数据类型
参考连接:https://redis.readthedocs.io/en/2.4/sorted_set.html
1、String: 字符串
2、Hash: 散列
3、List: 列表
4、Set: 无重复集合
5、Sorted Set: 有序无重复集合(数据都带优先级)
// 根据key判断存储类型[String、Hash、List、Set、Sorted Set]
keyType, err = p.client.Type(key).Result()
string类型
redis 127.0.0.1:6379>SET amberStr "amber"
redis 127.0.0.1:6379>GET amberStr
"amber"
golang实现string
key := "amberStr"
err = client.Set(key, "amber", time.Hour).Err()
value, err := client.Get(key).Result()
hash类型
redis 127.0.0.1:6379> HMSET amberHS one "Hello" two "World"
"OK"
redis 127.0.0.1:6379> HGET amberHS one
"Hello"
redis 127.0.0.1:6379> HGET amberHS two
"World"
redis 127.0.0.1:6379> DEL runoob
golang实现hash
key := "amberHASH"
client.HSet(key, "name", "amber")
client.HSet(key, "age", 18)
//get hash
hashGet, _ := client.HGet(key, "name").Result()
fmt.Println("HGet name", hashGet)
//获取所有hash 返回map
hashGetAll, _ := client.HGetAll(key).Result()
fmt.Println("HGetAll", hashGetAll)
list类型
redis 127.0.0.1:6379> rpush amberLS hello
(integer) 1
redis 127.0.0.1:6379> rpush amberLS world
(integer) 2
redis 127.0.0.1:6379> rpush amberLS !
(integer) 3
redis 127.0.0.1:6379> lrange amberLS 0 10
1) "hello"
2) "world"
3) "!"
redis 127.0.0.1:6379> DEL amberLS
golang实现list
key := "amberLS"
client.RPush(key, "hello", 10, "world", 15, "golang", 20).Err()
//lpop 取出并移除左边第一个元素
first, _ := client.LPop(key).Result()
//blpop 取出并移除左边第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
first2, _ := client.BLPop(time.Second*60, key).Result()
//数据长度
listLen, _ := client.LLen(key).Result()
fmt.Println("list length", listLen)
//获取列表
listGet, _ := client.LRange(key, 1, 2).Result()
fmt.Println("索引1-2的2个元素元素", listGet)
set类型
#重复的元素不会添加进去
redis 127.0.0.1:6379>SADD amberSet "amber"
redis 127.0.0.1:6379>SMEMBERS amberSet
redis 127.0.0.1:6379> SETNX unique "one"
(integer) 1
redis 127.0.0.1:6379> SETNX unique "two"
(integer) 0
redis 127.0.0.1:6379> GET unique
"one"
golang实现set
key := "amberSet"
client.SAdd(key, "cat")
client.SAdd(key, "dog")
client.SAdd(key, "monkey")
client.SAdd(key, ["rabbit", "tiger"])
// 添加元素,无法设定指定失效时间,只能通过调用expire
_, err = client.SAdd(key, ["cat","dog"]).Result()
//获取集合的所有成员
setList, _ := client.SMembers(key).Result()
//移除集合里的元素
client.SRem(key, "cat")
//移除并返回set的一个随机元素
setFirst, _ := client.SPop(key).Result()
//获取集合的所有的元素
setList, _ := client.SMembers(key).Result()
//移除并返回set的一个随机元素,因为set是无序的
setFirst, _ := client.SPop(key).Result()
//返回集合中元素的数量
count, _ := client.Scard(key).Result()
//删除集合中指定元素,若元素不存在则忽略,返回值是删除元素的数量,不存在的不统计在内
count, _ := client.SRem(key,"dog").Result()
//删除整个set集合
client.Del(key).Result()
//设置集合的过期时间
client.Expire(key, time.Hour).Result()
//设置锁
client.SetNX("key", "true", time.Second).Result()
ZSet类型
注意这里优先级是数字,在对象前面
redis 127.0.0.1:6379> zadd amberZSet 10 dog
(integer) 1
redis 127.0.0.1:6379> zadd amberZSet 20 kitty
(integer) 1
redis 127.0.0.1:6379> zadd amberZSet 30 monkey
(integer) 1
redis 127.0.0.1:6379> zadd amberZSet 30 monkey
(integer) 0
redis 127.0.0.1:6379> > ZRANGEBYSCORE amberZSet 0 1000
1) "dog"
2) "kitty"
3) "monkey"
golang实现zset
key := "amberSet"
ranking := []*redis.Z{
&redis.Z{Score: 100.0, Member: "dog"},
&redis.Z{Score: 80.0, Member: "cat"},
&redis.Z{Score: 70.0, Member: "kitty"},
&redis.Z{Score: 75.0, Member: "monkey"},
}
client.ZAdd(zsetKey, ranking...)
//cat+5分
newScore, err := client.ZIncrBy(key, 5.0, "cat").Result()
fmt.Println("加5分后的最新分数", newScore)
//取zset里的前4名热度的动物,这里仅是取出来
zset, _ := client.ZRevRangeWithScores(key, 0, 3).Result()
fmt.Println("zset前4名", zset)
//随机pop优先级最大/最小的key和value,redis5.0以后支持
keyValue, _ := client.ZPopMax(key).Result()
keyValue, _ := client.ZPopMin(key).Result()
代码示例SetNX
func setnx() error{
if success, err := client.SetNX("one", "true", 0).Result(); err != nil {
errInfo = fmt.Sprintf("fail to set one to redis with error: %v", err)
return fmt.Errorf(errInfo)
} else if !success {
errInfo = fmt.Sprintf("one has been setnx by other")
return nil
}
}
//err报错说明连接redis可能出现问题
//success=false说明key已经被使用
//SetNX第一个参数key,第二个参数是value,第三个参数是key存在时间超过指定时间会被删除,0代表永不超时