Home  >  Article  >  Database  >  Introduction to the method of implementing secondary cache with MySQL and Redis (code example)

Introduction to the method of implementing secondary cache with MySQL and Redis (code example)

不言
不言forward
2019-02-01 09:35:283067browse

What this article brings to you is an introduction to the method of implementing secondary cache with MySQL and Redis (code examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Introduction to redis

  • Redis is completely open source and free, complies with the BSD protocol, and is a high-performance key-value database

  • Redis has the following three characteristics with other key-value caching products:

    • Redis supports data persistence and can save data in memory to disk and restart It can be loaded again for use

    • Redis not only supports simple key-value type data, but also provides storage of list, set, zset, hash and other data structures

    • Redis supports data backup, that is, data backup in master-slave mode

Advantages

  • Extremely high performance - Redis can read at a speed of 110,000 times/s and write at a speed of 81,000 times/s

  • Rich data types - Redis supports Strings, Lists in binary cases, Hashes, Sets and Ordered Sets data type operations

  • Atomic – All operations in Redis are atomic, meaning they will either be executed successfully or not executed at all if they fail. Individual operations are atomic. Multiple operations also support transactions, that is, atomicity, wrapped through MULTI and EXEC instructions

Download and install

  • Download and unzip

wget http://download.redis.io/releases/redis-5.0.3.tar.gz
tar xzf redis-5.0.3.tar.gz
  • Move the folder to /usr/local/

mv redis-5.0.3 /usr/local/
  • Enter folder and compile and test

cd /usr/local/redis-5.0.3
sudo make test
  • Compile and install

sudo make install
  • Start redis

redis-server

If the following screen appears, it means that the redis database has been started:
jpg

mysql and redis do secondary cache

  • For data with relatively large access volume, in order to obtain the data faster, we need to cache the data obtained from the database.

  • Using Redis caching process in the project

    Data caching should consider synchronization issues: if the data is cached, when querying the data, if the cache If there is data, the cached data will be returned directly without querying the database. When the database data changes, database inconsistency may occur. You can consider deleting the corresponding cached data every time you modify the database, so that when you re-query, the database will be queried and cached

  1. When querying, start with Query in the cache

  2. If there is no data in the cache, query from the database and save the data into the cache

  3. If the data is queried in the cache Return directly, no longer need to query the database

Step implementation
  • Create the redisPool.go file for initialization of the connection pool

package redigo_pool

import (
    "flag"
    "github.com/garyburd/redigo/redis"
    "time"
)
var (
    Pool *redis.Pool
    RedisServer   = flag.String("redisServer", ":6379", "")
    
)
func init() {
    Pool = &redis.Pool{
        MaxIdle:     3, //最大空闲链接数,表示即使没有redis链接事依然可以保持N个空闲链接,而不被清除
        MaxActive:   3, //最大激活连接数,表示同时最多有多少个链接
        IdleTimeout: 240 * time.Second,//最大空闲链接等待时间,超过此时间,空闲将被关闭
        Dial: func() (redis.Conn, error) {
            c, err := redis.Dial("tcp", *RedisServer)
            if err != nil {
                return nil, err
            }
            return c, err
        },
        TestOnBorrow: func(c redis.Conn, t time.Time) error {
            if time.Since(t) < time.Minute {
                return nil
            }
            _, err := c.Do("PING")
            return err
        },
    }
}
  • Create main.go file to implement second-level cache

package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "github.com/garyburd/redigo/redis"
    _ "github.com/go-sql-driver/mysql"
    "strconv"
    "web/redis/redigo_pool"
    _ "web/redis/redigo_pool"
)

type Person struct {
    Id int `db:"id"`
    Name string `db:"name"`
    Age int `db:"age"`
    Rmb int `db:"rmb"`
}

func main() {
    var cmd string
    for{
        fmt.Println("输入命令")
        fmt.Scan(&cmd)
        switch cmd {
        case "getall":
            getAll()
        default:
            fmt.Println("不能识别其他命令")
        }
        fmt.Println()
    }
}

func getAll()  {
    //从连接池当中获取链接
    conn := redigo_pool.Pool.Get()
    //先查看redis中是否有数据
    //conn,_ :=redis.Dial("tcp","localhost:6379")
    defer conn.Close()
    values, _ := redis.Values(conn.Do("lrange", "mlist",0,-1))

    if len(values) > 0 {
        //如果有数据
        fmt.Println("从redis获取数据")
        //从redis中直接获取
        for _,key := range values{
            pid :=string(key.([]byte))
            id ,_:= strconv.Atoi(pid)
            results,_ := redis.Bytes(conn.Do("GET",id))
            var p Person
            err := json.Unmarshal(results,&p)
            if err != nil {
                fmt.Println("json 反序列化出错")
            }else {
                fmt.Printf("name = %s\n",p.Name)
            }
        }
    }else {
        fmt.Println("从mysql中获取")

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

        var persons []Person

        rows,_ := db.Query("select id,name,age,rmb from person")
        for rows.Next()  {
            var id int
            var name string
            var age int
            var rmb int
            rows.Scan(&id,&name,&age,&rmb)
            per := Person{id,name,age,rmb}
            persons = append(persons,per)

        }
        //写入到redis中:将person以hash的方式写入到redis中
        for _,p := range persons{

            p_byte,_ := json.Marshal(p)
            _,err1 := conn.Do("SETNX",p.Id,p_byte)
            _,err2 := conn.Do("lpush","mlist",p.Id)
            // 设置过期时间
            conn.Do("EXPIRE",p.Id,60*5)
            if err1 != nil || err2 != nil {
                fmt.Println("写入失败")
            }else {
                fmt.Println("写入成功")
            }
        }
        conn.Do("EXPIRE","mlist",60*5)
    }
}

The above is the detailed content of Introduction to the method of implementing secondary cache with MySQL and Redis (code example). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:cnblogs.com. If there is any infringement, please contact admin@php.cn delete