Go和MySQL,Redis最二级缓存

go语言简介
首先go语言作为一门新语言,2007年开始研发,2009年11月开源,2012年初发布Go1稳定版本,截止目前还是在1.0时代,那么,这么一个“新生代语言”相比于活跃在各大公司之前的前辈,如:C,Java,python等具有哪些优势呢?
go语言的最大的优势在于高并发,go程,协程,一台pc机,即可完成百万级别的并发
go语言有自动垃圾回收机制,而且是一门底层语言
redis简介
redis是一种高速高性能的内存数据库,存储的是键值对数据
由于极高的存储和访问速度,redis常被用来作为数据缓存服务器
另外redis是支持数据持久化的(即redis会自动将数据写入磁盘)——这是redis大杀四方的重要原因
redis支持多个slave端同时向master端进行写入,这经常被用在分布式爬虫等场景中
2010年以后redis开始大面积流行,关系型数据库(核心数据)+redis(缓存)是常规的、常见的数据解决方案
mysql简介
Mysql是最流行的关系型数据库管理系统;
所谓的关系型数据库,是指建立在关系模型基础上的数据库,即数据表之间不是相互独立的,而是彼此关联的;
数据表中的每行代表一条数据,每列代表一个属性(也叫字段);
最著名的三大关系型数据库包括:Oracle(甲骨文),SQLServer(微软),MySQL(甲骨文);
MySQL是开源、免费的,且功能强大(64位机最大支持8T存储);
支持C/C++、Python、Java、PHP、Ruby、Perl等多种语言;
正文
下面就直奔主题
众所周知,在工作中,redis和mysql都是常用的数据库,redis常用来缓存,mysql作为关系型数据库常用来存储核心数据,那么如何实现交互呢
package main

import (
    "fmt"
    
    //此处注意“_”表示引用mysql函数中init的方法而无需使用函数
    _ "github.com/go-sql-driver/mysql"
    
    "github.com/garyburd/redigo/redis"
    "github.com/jmoiron/sqlx"
)

type Person struct {
    //对应id表字段
    Id int `db:"id"`
    //对应name表字段
    Name string `db:"name"`
    //对应age表字段
    Age int `db:"age"`
    //对应rmb表字段
    Rmb float64 `db:"rmb"`
}

func main() {
    var cmd string

    for {
        fmt.Println("请输入命令:")
        fmt.Scan(&cmd)
        //fmt.Println("你输入的是:",cmd)

        switch cmd {
        case "getall":
            GetAll()
        default:
            fmt.Println("不能识别的命令")
        }

        fmt.Println()
    }

}

func GetAll() {
    //先看看redis里有没有数据
    conn, _ := redis.Dial("tcp", "localhost:6379")
    defer conn.Close()
    reply, err := conn.Do("lrange", "mlist", 0, -1)
    pkeys, _ := redis.Strings(reply, err)
    fmt.Println(pkeys)

    if len(pkeys) > 0 {
        //如果有
        fmt.Println("从redis获得数据")

        // 从redis里直接读取
        for _, key := range pkeys {
            retStrs, _ := redis.Strings(conn.Do("hgetall", key))
            //fmt.Println(retStrs)
            fmt.Printf("{%s %s %s}\n", retStrs[1], retStrs[3], retStrs[5])
        }

    } else {
        //如果没有
        fmt.Println("从mysql获得数据")

        //查询数据库
        db, _ := sqlx.Open("mysql", "root:123456@tcp(localhost:3306)/mydb")
        defer db.Close()

        var persons []Person
        db.Select(&persons, "select id,name,age,rmb from person")
        fmt.Println(persons)

        //写入redis并且设置过期时间
        for _, p := range persons {
            //将p以hash形式写入redis
            _, e1 := conn.Do("hmset", p.Id, "name", p.Name, "age", p.Age, "rmb", p.Rmb)

            //将这个hash的key加入mlist
            _, e2 := conn.Do("rpush", "mlist", p.Id)

            //设置过期时间
            _, e3 := conn.Do("expire", p.Id, 60)
            _, e4 := conn.Do("expire", "mlist", 60)

            if e1 != nil || e2 != nil || e3 != nil || e4 != nil {
                fmt.Println(p.Name, "写入失败", e1, e2, e3, e4)
            } else {
                fmt.Println(p.Name, "写入成功")
            }
        }
    }
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
这样一个简单的二级缓存就完成了,打印结果为,在终端输入getall命令后查redis里有无数据,有则遍历打印,无则查询mysql中,打印之,并把数据写入redis作为缓存,时间我设置为60s,具体需要可以修改。

阅读更多

没有更多推荐了,返回首页