导学:
如何学习?
本人建议先安装redis,如何在命令敲一遍,最后再用go来实现效果更好。实战!实战!不实战就是凉凉!!!!!!!
1.1什么是redis?
redis:远程字典服务,是一种运行在内存上的非关系型数据库,它支持的数据类型有:字符串,哈希表,列表,集合(集合分有序/无序)。redisd的所有操作均是原子性的,redis不仅多个操作支持事务,而且还有非常高的读写性能。为什么redis性能比redis高,一个重要的原因就是redis运行在内存上面,从物理层就比mysql更有优势;除此之外,redis使用的算法是以哈希为主,时间复杂度为O(1),mysql则主要使用B+树算法,时间复杂度为O(logn)当然了,redis是通过空间复杂度来换取时间复杂度。
1.2redis可以干什么?
在redis是什么中,我们没有提到redis具有key过期这一特性。其实这个特性的是广泛使用在验证服务上面,例如卡密,验证码等等。。。
当然了,redis是一个高性能nosql数据库,主要功能就是来存取数据。在一些对性能要求较高的地方,使用的比较多。不过redis也是有缺点的,如果存储的数据过多,那么势必会导致性能有所下降,计算成本也会增加。
1.3使用go操作redis
查看go的官方文档,我们可以使用使用包:github.com/garyburd/redigo/redis来操作我们的redis。
下载redis包:
go get github.com/garyburd/redigo/redis
1.4连接redis
首先得有redis才能连接,就像MySQL一样,我们先得在机器上安装redis
redis的GitHub开源地址:
安装教程:
连接代码如下:
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
c, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
fmt.Println("conn redis failed,", err)
return
}
fmt.Println("redis conn success")
defer c.Close()//夹尾巴
}
开启连接,记得夹尾巴,哈哈哈
1.4.1 string的get 、set操作
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
c, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
fmt.Println("conn redis failed,", err)
return
}
defer c.Close()
_, err = c.Do("Set", "abc", 100)
if err != nil {
fmt.Println(err)
return
}
r, err := redis.Int(c.Do("Get", "abc"))
if err != nil {
fmt.Println("get abc failed,", err)
return
}
fmt.Println(r)
}
注意:
Redis被配置为保存数据库快照,但它目前不能持久化到硬盘。用来修改集合数据的命令不能用。请查看Redis日志的详细错误信息。
原因:
强制关闭Redis快照导致不能持久化。
解决方案:
运行config set stop-writes-on-bgsave-error no 命令后,关闭配置项stop-writes-on-bgsave-error解决该问题。
1.4.2 string批量操作
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
c, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
fmt.Println("conn redis failed,", err)
return
}
defer c.Close()
_, err = c.Do("MSet", "abc", 100, "efg", 300)
if err != nil {
fmt.Println(err)
return
}
r, err := redis.Ints(c.Do("MGet", "abc", "efg"))
if err != nil {
fmt.Println("get abc failed,", err)
return
}
for _, v := range r {
fmt.Println(v)
}
}
1.4.3 设置key过期时间
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
c, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
fmt.Println("conn redis failed,", err)
return
}
defer c.Close()
_, err = c.Do("expire", "abc", 10)
if err != nil {
fmt.Println(err)
return
}
}
1.4.4 list操作
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
c, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
fmt.Println("conn redis failed,", err)
return
}
defer c.Close()
_, err = c.Do("lpush", "book_list", "abc", "ceg", 300)
if err != nil {
fmt.Println(err)
return
}
r, err := redis.String(c.Do("lpop", "book_list"))
if err != nil {
fmt.Println("get abc failed,", err)
return
}
fmt.Println(r)
}
1.4.5 hash表
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
c, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
fmt.Println("conn redis failed,", err)
return
}
defer c.Close()
_, err = c.Do("HSet", "books", "abc", 100)
if err != nil {
fmt.Println(err)
return
}
r, err := redis.Int(c.Do("HGet", "books", "abc"))
if err != nil {
fmt.Println("get abc failed,", err)
return
}
fmt.Println(r)
}
1.4.6 redis连接池
package main
import(
"fmt"
"github.com/garyburd/redigo/redis"
)
var pool *redis.Pool //创建redis连接池
func init(){
pool = &redis.Pool{ //实例化一个连接池
MaxIdle:16, //最初的连接数量
// MaxActive:1000000, //最大连接数量
MaxActive:0, //连接池最大连接数量,不确定可以用0(0表示自动定义),按需分配
IdleTimeout:300, //连接关闭时间 300秒 (300秒不使用自动关闭)
Dial: func() (redis.Conn ,error){ //要连接的redis数据库
return redis.Dial("tcp","localhost:6379")
},
}
}
func main(){
c := pool.Get() //从连接池,取一个链接
defer c.Close() //函数运行结束 ,把连接放回连接池
_,err := c.Do("Set","abc",200)
if err != nil {
fmt.Println(err)
return
}
r,err := redis.Int(c.Do("Get","abc"))
if err != nil {
fmt.Println("get abc faild :",err)
return
}
fmt.Println(r)
pool.Close() //关闭连接池
}