MySQLとRedisで2次キャッシュを実装する方法の紹介(コード例)

不言
リリース: 2019-02-01 09:35:28
転載
3065 人が閲覧しました

この記事の内容は、MySQL と Redis を使用した二次キャッシュの実装方法 (コード例) の紹介です。必要な方は参考にしていただければ幸いです。

redis の概要

  • Redis は完全にオープンソースで無料で、BSD プロトコルに準拠しており、高性能のキーと値のデータベースです

  • Redis には、他のキー/値キャッシュ製品と比べて、次の 3 つの特徴があります。

    • Redis はデータの永続性をサポートし、メモリ内のデータをディスクに保存して再起動できます。再度ロードして使用することができます

    • Redis は、単純なキー値型のデータをサポートするだけでなく、リスト、セット、zset、ハッシュ、およびその他のデータ構造のストレージも提供します

    • #Redis はデータ バックアップ、つまりマスター/スレーブ モードでのデータ バックアップをサポートします

    ##利点

#非常に高いパフォーマンス - Redis は 110,000 回/秒の速度で読み取り、81,000 回/秒の速度で書き込みが可能
  • #豊富なデータ型 - Redis は文字列、バイナリケースのリストをサポートします、ハッシュ、セット、および順序付きセットのデータ型操作
  • アトミック – Redis のすべての操作はアトミックです。つまり、操作は正常に実行されるか、失敗した場合にはまったく実行されません。個々の操作はアトミックです。複数の操作は、MULTI 命令と EXEC 命令によってラップされたトランザクション、つまりアトミック性もサポートします
  • ダウンロードとインストール

ダウンロードと解凍
  • wget http://download.redis.io/releases/redis-5.0.3.tar.gz
    tar xzf redis-5.0.3.tar.gz
    ログイン後にコピー

フォルダーを /usr/local/
  • mv redis-5.0.3 /usr/local/
    ログイン後にコピー

フォルダーに移動し、コンパイルしてテストします
  • #
    cd /usr/local/redis-5.0.3
    sudo make test
    ログイン後にコピー

    #コンパイルとインストール
    sudo make install
    ログイン後にコピー
  • #redis の開始

redis-server
ログイン後にコピー
    次の画面が表示された場合は、redis データベースが開始されたことを意味します:
  • jpg

    mysql と redis は二次キャッシュを実行します


アクセス量が比較的多いデータの場合、より高速にデータを取得するために、データベースから取得したデータをキャッシュする必要があります。

    プロジェクトで Redis キャッシュ プロセスを使用する
  • データ キャッシュでは、同期の問題を考慮する必要があります。データがキャッシュされている場合、データをクエリするとき、キャッシュが存在する場合データがある場合、データベースにクエリを実行せずにキャッシュされたデータが直接返されます。データベースのデータが変更されると、データベースの不整合が発生する可能性があります。データベースを変更するたびに、対応するキャッシュされたデータを削除することを検討してください。これにより、再クエリ時にデータベースがクエリされてキャッシュされるようになります。
  • クエリを実行するとき、キャッシュ内のクエリから開始します

  • #キャッシュにデータがない場合は、データベースからクエリを実行し、データをキャッシュに保存します
    1. データがキャッシュ内でクエリされた場合は直接返され、データベースをクエリする必要はなくなりました
    2. #ステップの実装
    3. 接続プールの初期化のための redisPool.go ファイル
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
        },
    }
}
ログイン後にコピー
  • 2 次レベル キャッシュを実装するための main.go ファイルの作成

    ##
    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)
        }
    }
    ログイン後にコピー

以上がMySQLとRedisで2次キャッシュを実装する方法の紹介(コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!