MySQL과 Redis를 이용한 2차 캐시 구현 방법 소개(코드 예시)

不言
풀어 주다: 2019-02-01 09:35:28
앞으로
3036명이 탐색했습니다.

이 기사에서는 MySQL 및 Redis를 사용하여 보조 캐시를 구현하는 방법(코드 예제)을 소개합니다. 필요한 친구가 참고할 수 있기를 바랍니다.

redis 소개

  • Redis는 완전 오픈 소스이며 무료이며 BSD 프로토콜을 준수하며 고성능 키-값 데이터베이스입니다.

  • Redis는 다른 키-값 캐시 제품과 함께 다음 세 가지 특징을 가지고 있습니다. :

    • Redis는 메모리에 있는 데이터를 디스크에 저장했다가 다시 로드하여 다시 시작할 수 있습니다.

    • Redis는 간단한 키-값 형식의 데이터를 지원할 뿐만 아니라 목록도 제공합니다. , set , zset, hash 및 기타 데이터 구조 저장

    • Redis는 데이터 백업, 즉 마스터-슬레이브 모드의 데이터 백업을 지원합니다

Advantages

  • 매우 높은 성능 - Redis는 빠른 속도로 읽을 수 있습니다. 110,000회/초, 쓰기 속도는 81,000회/초

  • 풍부한 데이터 유형 - Redis는 바이너리 케이스 문자열, 목록, 해시, 세트 및 Ordered Set 데이터 유형 작업을 지원합니다.

  • Atomic - Redis의 모든 작업은 원자적 성적(Atomic Sexual)은 성공적으로 실행되거나 실패하고 전혀 실행되지 않음을 의미합니다. 개별 작업은 원자적입니다. 다중 작업은 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
로그인 후 복사
  • Start redis

redis-server
로그인 후 복사

다음 화면이 나오면 redis 데이터베이스가 시작되었다는 뜻입니다 :
jpg

보조 캐싱을 위한 mysql 및 redis

  • 상대적으로 접근량이 많은 데이터의 경우 데이터를 더 빠르게 얻기 위해서는 데이터베이스에서 얻은 데이터를 캐싱해야 합니다.

  • 프로젝트에서 Redis 캐싱 프로세스 사용

    데이터 캐싱은 동기화 문제를 고려해야 합니다. 데이터가 캐시되어 있으면 데이터를 쿼리할 때 캐시에 데이터가 있으면 캐시된 데이터가 직접 반환되고 데이터베이스는 데이터가 변경되면 데이터베이스 불일치가 발생할 수 있습니다. 데이터베이스를 수정할 때마다 해당 캐시된 데이터를 삭제하여 다시 쿼리할 때 데이터베이스를 쿼리하고 캐시할 수 있습니다. 쿼리할 때 캐시에 데이터가 없으면 먼저 캐시에서 쿼리합니다. 데이터베이스에서 쿼리하고 데이터를 캐시에 저장합니다

    1. 데이터가 캐시에서 쿼리되어 직접 반환되면 데이터베이스를 쿼리할 필요가 없습니다
    2. 구현 단계

    3. redisPool 생성 연결 풀링을 위한 .go 파일 초기화

    4. 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:cnblogs.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!