MySQL與Redis實現二級緩存

来源:https://www.cnblogs.com/develop-SZT/archive/2019/02/01/10344594.html
-Advertisement-
Play Games

redis簡介 Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key value資料庫 Redis 與其他 key value 緩存產品有以下三個特點: Redis支持數據的持久化,可以將記憶體中的數據保存在磁碟中,重啟的時候可以再次載入進行使用 Redis不僅僅支持簡單的key val ...


redis簡介

  • Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key-value資料庫
  • Redis 與其他 key - value 緩存產品有以下三個特點:
    • Redis支持數據的持久化,可以將記憶體中的數據保存在磁碟中,重啟的時候可以再次載入進行使用
    • Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲
    • Redis支持數據的備份,即master-slave模式的數據備份

優勢

  • 性能極高 - Redis能讀的速度是110000次/s,寫的速度是81000次/s
  • 豐富的數據類型 – Redis支持二進位案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作
  • 原子 – 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
        },
    }
}
  • 創建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)
    }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • #備份資料庫:導出全部資料庫:--all-databases, -A導出幾個資料庫。參數後面所有名字參量都被看作資料庫名:--databases, -B導出存儲過程以及自定義函數:--routines, -R導出事件:--events, -E不緩衝查詢,直接導出到標準輸出。預設為打開狀態,使用--s ...
  • 死鎖雜談 當資料庫死鎖時,SqlServer會釋放一個優先順序較低的鎖,讓另一個事務運行;所以,即時去捕捉資料庫死鎖,是挺不容易的。 如果,資料庫死鎖比較長時間,那麼死鎖是可以被捕捉的。 可以用SqlServer活動監視器來查看,哪些進程鎖了資料庫。 首先打開SqlServer活動監視器,然後可以看到 ...
  • 一 環境準備 圖形界面:略 安裝包: linux.x64_11gR2_database_1of2.zip linux.x64_11gR2_database_2of2.zip 二 安裝ASM-Oracle準備 2.1 用戶名/組建立 2.2 相關目錄創建 附:oracle預設不支持CentOS系統安裝 ...
  • 什麼是redis Redis是一種面向“key-value”類型數據的分散式NoSQL資料庫系統,具有高性能、持久存儲、適應高併發應用場景等優勢。它雖然起步較晚,但發展卻十分迅速。 redis為何需要持久化 由於Redis的數據都存放在記憶體中,如果沒有配置持久化,redis重啟後數據就全丟失了,於是 ...
  • MySQL 事務介紹 標簽(空格分隔): Mysql 事務 [TOC] MySQL事務 ACID 1. 原子性(Atomcity) 一個事務的最小單元,要麼全部成功要麼全部失敗,執行的過程中是不能被打斷或者執行其他操作的。 2. 一致性(Consistent) 事務開始前和結束後,資料庫的完整性約束 ...
  • 話不多說先來看看表結構: 顯而易見 Pid 存放的 Person 的 id ;下麵重點(奇葩需求!!!!) 我需要向表一(Person)里插入幾條數據(...)這時候不會對錶二做任何操作。 需求:查詢表一(Person)條件是表二(Person_Visison)里有沒有表一(Person)的 id ...
  • 一 環境準備 安裝包:linux.x64_11gR2_database_1of2.zip linux.x64_11gR2_database_2of2.zip 二 安裝Oracle準備 2.1 用戶名/組建立 2.2 相關目錄創建 提示:oracle預設不支持CentOS系統安裝,需要如下修改 2.3 ...
  • 近期的一個項目要求用mysql資料庫,正好系統重裝了,複習下mysql的安裝,哪成想是踩了無數坑啊! 要安裝首先自然是火速進官網下個安裝包(下載地址https://dev.mysql.com/downloads/file/?id=483327),沒註意mysql都8了,上次安裝的好像是5.幾的。下載 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...