GO------小白之redis

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: redis 是一个开源的、使用c编写的支持网络交互的、科技与内存也可持久化的key-value数据库go getgithub.com/garyburd/redigo利用redis.

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,如果不为空则代表接收到数据)

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
8天前
|
NoSQL Go API
go语言操作Redis
go语言操作Redis
|
2月前
|
消息中间件 存储 NoSQL
redis实战——go-redis的使用与redis基础数据类型的使用场景(一)
本文档介绍了如何使用 Go 语言中的 `go-redis` 库操作 Redis 数据库
redis实战——go-redis的使用与redis基础数据类型的使用场景(一)
|
27天前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
|
2月前
|
NoSQL Go Redis
用 Go + Redis 实现分布式锁
用 Go + Redis 实现分布式锁
|
2月前
|
监控 NoSQL Go
Go语言中高效使用Redis的Pipeline
Redis 是构建高性能应用时常用的内存数据库,通过其 Pipeline 和 Watch 机制可批量执行命令并确保数据安全性。Pipeline 类似于超市购物一次性结账,减少网络交互时间,提升效率。Go 语言示例展示了如何使用 Pipeline 和 Pipelined 方法简化代码,并通过 TxPipeline 保证操作原子性。Watch 机制则通过监控键变化实现乐观锁,防止并发问题导致的数据不一致。这些机制简化了开发流程,提高了应用程序的性能和可靠性。
51 0
|
2月前
|
NoSQL Go Redis
Go语言中如何扫描Redis中大量的key
在Redis中,遍历大量键时直接使用`KEYS`命令会导致性能瓶颈,因为它会一次性返回所有匹配的键,可能阻塞Redis并影响服务稳定性。为解决此问题,Redis提供了`SCAN`命令来分批迭代键,避免一次性加载过多数据。本文通过两个Go语言示例演示如何使用`SCAN`命令:第一个示例展示了基本的手动迭代方式;第二个示例则利用`Iterator`简化迭代过程。这两种方法均有效地避免了`KEYS`命令的性能问题,并提高了遍历Redis键的效率。
40 0
|
4月前
|
NoSQL Go Redis
如何使用 Go 和 `go-redis/redis` 库连接到 Redis 并执行一些基本操作
如何使用 Go 和 `go-redis/redis` 库连接到 Redis 并执行一些基本操作
57 1
|
8天前
|
Go
Go 语言循环语句
在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。
17 1
|
7天前
|
Go 开发者
探索Go语言的并发之美
在Go语言的世界里,"并发"不仅仅是一个特性,它是一种哲学。本文将带你领略Go语言中goroutine和channel的魔力,揭示如何通过Go的并发机制来构建高效、可靠的系统。我们将通过一个简单的示例,展示如何利用Go的并发特性来解决实际问题,让你的程序像Go一样,轻盈而强大。
下一篇
无影云桌面