GO------小白之redis

  1. 云栖社区>
  2. 博客>
  3. 正文

GO------小白之redis

wini_fred 2018-09-04 14:02:00 浏览672
展开阅读全文

redis 是一个开源的、使用c编写的支持网络交互的、科技与内存也可持久化的key-value数据库

go getgithub.com/garyburd/redigo

利用redis.Dail进行监听、返回一个连接器、可以使用go的类型断言将返回的interface转为对应的类型

可以利用pipe操作并发操作

可以进行发布订阅

事物操作

mysql和redis的区别:

MySQL的数据存储在data目录下frm ibd后缀的文件中、存储在机器/服务器的硬盘中、所以MySQL读写数据都需要从硬盘读取、磁盘的容量、带宽的大小就影响了网站的访问速度、读取的方式、也就是sql语句、次数和效率也会影响读取效率

当访问量和并发都很大的时候、MySQL就撑不住了、MySQL的连接池并发数max为500-1000

可以选择慢查询优化、cdn、页面静态化、ngix负载均衡策略、分布式数据库来进行sql优化、也可以使用高速缓存、例如redis。

redis :高并发、内存高速cache、处理读写io的高并发容忍、将通常被使用来将那些经常被访问的内容缓存到内存中、主从同步(将数据同步到多台从数据库上、提高读取性能)

redis不仅仅支持简单的k-v类型的数据、还支持list、set、zset、hash等数据结构的存储

redis单个value的最大限制是1GB

redis在3.0版本后支持在服务器端构建分布式存储、redis Cluster是一个实现了分布式且允许单点故障的高级版本

链接数据库:redis.Dail("tcp","127.0.0.1:6379")

1、以redigo为例、当然还有redix、redix在操作查询删除添加时、用的是conn.Cmd

import (

    "github.com/garyburd/redigo/redis"

    "fmt"

)

func connDb() {

    //redis作为中间件的数据库、需要和服务器相连

    //创建监听器、创建连接请求

    conn, err := redis.Dial("tcp", "127.0.0.1:6379")

    if err != nil {

        fmt.Println("redis.Dial error", err)

        return

    }

    defer conn.Close()

    saveDb( conn )

    readFromDB( conn )

    deleFromDB( conn )

}

//写入

func saveDb( conn redis.Conn ){

    //EX 为这个值得过期时间

    //批量写入、单个写入的话、MSET改为SET

    _,err := conn.Do("MSET","name","superWang","SEX","F","EX","50")

    if err != nil{

        fmt.Println("conn.Do error",err)

    }

    fmt.Println("save success")

}

func readFromDB( conn redis.Conn){

    //单个读取数据,conn.Do的第一个参数为命令类型、因为我们是读取、所以是GET、其余参数为想要查找的值

    username,err := redis.String(conn.Do("GET","name"))

    userSex,_ := redis.String(conn.Do("GET","SEX"))

    if err != nil{

        fmt.Println("redis.String error",err)

    }else {

        fmt.Printf("Get mykey: %v \n",username)

    }

    fmt.Printf("Get mykey: %v \n",userSex)

    //批量读取

    usernameall,_ := redis.Strings(conn.Do("MGET","SEX","name"))

    fmt.Printf("Get mykey: %v \n",usernameall)

}

func deleFromDB( conn redis.Conn){

    _,err := conn.Do("DEL","name","SEX")

    if err != nil{

        fmt.Println("deleFromDB error",err)

    }

    fmt.Println("delete success")

}

func main(){

    connDb()

}

运行结果为


img_3e312c86f128c9cece54f3f9130189a8.png

解释一下EX过期时间:如果设置了这个时间、则在当前的key过期时间为设置时间、不设置则当前的key永远有效

看了很多文章、找了很多解释、想弄明白为什么要选择json作为读写到redis的通用配置格式

go的配置格式右ini,json,yaml,xml等等、xml比较繁琐、ini不适用于太多层次结构的

json中的RawMassage、它主要用来告诉go延迟解析

2、利用json类型转换的写入读取:

package main

import (

    "github.com/garyburd/redigo/redis"

    "fmt"

    "encoding/json"

)

func connDb() {

    //redis作为中间件的数据库、需要和服务器相连

    //创建监听器、创建连接请求

    conn, err := redis.Dial("tcp", "127.0.0.1:6379")

    if err != nil {

        fmt.Println("redis.Dial error", err)

        return

    }

    defer conn.Close()

    saveJsonDataToDB( conn )

    readJsonDataFromDB( conn )

}

//写json

func saveJsonDataToDB( conn redis.Conn ){

    imap := map[string]string{ "name" : "waiwaigo","phone":"1342132132" }

    //将map进行类型转换、转换成字符切片

    value,_ := json.Marshal(imap)

    n,err := conn.Do("SETNX","jsonkey",value)

    if err != nil {

        fmt.Println("conn.Do SETNX error  ", err)

        return

    }

    if n == int64(1){

        fmt.Println("success")

    }

}

//读json

func readJsonDataFromDB( conn redis.Conn){

    var imspGet map[string]string

    valueGet ,err := redis.Bytes(conn.Do("GET","jsonkey"))

    if err != nil {

        fmt.Println("redis.Bytes error  ", err)

        return

    }

    //将读取的数据转换为map类型

    errshal := json.Unmarshal(valueGet,&imspGet)

    if errshal != nil {

        fmt.Println("son.Unmarshal error  ", err)

        return

    }

    for i,v :=range imspGet{

        fmt.Println(i,v)

    }

}

func main(){

    connDb()

}

3、列表操作

package main

import (

    "github.com/garyburd/redigo/redis"

    "fmt"

)

func connDb() {

    //redis作为中间件的数据库、需要和服务器相连

    //创建监听器、创建连接请求

    conn, err := redis.Dial("tcp", "127.0.0.1:6379")

    if err != nil {

        fmt.Println("redis.Dial error", err)

        return

    }

    defer conn.Close()

    saveListToDB( conn )

    readListFromDB( conn )

}

//写json

func saveListToDB( conn redis.Conn ) {

    //写入列表、命令为lpush

    _, err := conn.Do("lpush", "username", "zhangsan")

    if err != nil {

        fmt.Println("conn.Do lpush error  ", err)

        return

    }

    _, err = conn.Do("lpush", "username", "lisi")

    if err != nil {

        fmt.Println("conn.Do lpush error  ", err)

        return

    }

    _, err = conn.Do("lpush", "username", "wangwu")

    if err != nil {

        fmt.Println("conn.Do lpush error  ", err)

        return

    }

}

//读列表

func readListFromDB( conn redis.Conn ){


    //想要读取的下标值、这块我也不是太清楚、因为如果把1去掉就显示两个值,如果是0和2、就显示三个值

    values,_ := redis.Values(conn.Do("lrange","username","1","2"))

    //计算列表中一共有几条数据

    fmt.Printf("count : %d \n",len(values))

    for _,v :=range values{

        fmt.Println( string(v.([]byte)))

    }

}

func main(){

    connDb()

}

对于redis一般操作时,首先会创建一个连接规则(spec:= redis.Default().DB(0).Password(""),返回一个规则)自己创建 、然后创建一个新的syncClient、并连接到redis的服务器上使用,并指定ConnecttionSpec接口( client:=redis.NewSynchClientWithSpec(spec)、此时会返回一个错误信息、如果有错误则代表服务器连接失败)、接下来制定一个得到数据的规则( dbkey := "GAME:TEST:info")从client获取信息(value,err := client.Get(dbkey)此时返回一个值和错误信息、如果值为空则可以向客户端写入数据、client.Set,如果不为空则代表接收到数据)

网友评论

登录后评论
0/500
评论
wini_fred
+ 关注