Golang中使用快取加速資料庫存取效率的實踐
隨著Web應用越來越複雜,對資料庫的存取也變得越來越頻繁。而存取資料庫通常是非常耗時的操作,特別是在資料量較大的情況下。為了提高存取資料庫的效率,可以採用諸如快取等策略來優化資料庫存取。
本文將介紹Golang中如何使用快取加速資料庫存取的實踐。我們將使用Golang作為開發語言,Redis作為快取伺服器,MySQL作為資料庫伺服器進行實驗。
1.建造環境
在開始之前,我們需要搭建好環境。首先安裝Golang以及MySQL和Redis伺服器,這裡不再贅述。
然後在Golang中安裝本地Redis和MySQL的Go驅動程式:
go get github.com/go-redis/redis/v8 go get github.com/go-sql-driver/mysql
2.編寫程式碼
接下來,我們編寫程式碼以實現快取加速資料庫存取。
首先是資料庫存取的程式碼。我們定義了一個叫做DB的全域變量,用於連接MySQL。然後,我們定義了一個函數getUserByID,用於從MySQL中查詢一個使用者的資訊:
package main import ( "database/sql" "fmt" "log" _ "github.com/go-sql-driver/mysql" ) var DB *sql.DB type User struct { ID int Username string Password string Age int } func init() { db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/test?charset=utf8") if err != nil { log.Fatal("Open mysql failed,err:", err) return } DB = db fmt.Println("Connect to mysql success") } func getUserByID(id int) (*User, error) { var user User query := "SELECT id, username, password, age FROM users WHERE id=?" err := DB.QueryRow(query, id).Scan(&user.ID, &user.Username, &user.Password, &user.Age) if err != nil { log.Println(err) return nil, err } return &user, nil }
然後,我們在這個getUserByID函數中加入了快取邏輯。具體而言,我們首先透過getUserByID函數嘗試從Redis快取中讀取請求的使用者資訊。如果Redis中沒有該使用者的資訊記錄,則從MySQL中讀取使用者資訊,並將其存入Redis以供下次存取。如果使用者資訊在Redis中有記錄,則直接從Redis傳回使用者資訊:
package main import ( "database/sql" "encoding/json" "fmt" "log" "strconv" "github.com/go-redis/redis/v8" _ "github.com/go-sql-driver/mysql" ) var DB *sql.DB var RedisClient *redis.Client type User struct { ID int Username string Password string Age int } func init() { db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/test?charset=utf8") if err != nil { log.Fatal("Open mysql failed,err:", err) return } DB = db fmt.Println("Connect to mysql success") RedisClient = redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", }) pong, err := RedisClient.Ping(RedisClient.Context()).Result() if err != nil { panic(err) return } fmt.Println("Connect to redis success: ", pong) } func getUserByID(id int) (*User, error) { var user User key := "user-" + strconv.Itoa(id) // 1.尝试从Redis中读取用户信息 val, err := RedisClient.Get(RedisClient.Context(), key).Result() if err == redis.Nil { fmt.Println("Cache miss") } else if err != nil { log.Println("Get from Redis fail:", err) } else { fmt.Println("Get from Redis:", val) if err := json.Unmarshal([]byte(val), &user); err != nil { // 将json字符串转换为结构体 log.Panicln("Unmarshal to user fail:", err) } return &user, nil } // 2.如果Redis中没有,从MySQL中查询 query := "SELECT id, username, password, age FROM users WHERE id=?" err = DB.QueryRow(query, id).Scan(&user.ID, &user.Username, &user.Password, &user.Age) if err != nil { log.Println(err) return nil, err } // 3.然后更新Redis缓存 val, err = json.Marshal(user) // 将结构体转换为json字符串 if err != nil { log.Panicln("Marshal user fail:", err) } err = RedisClient.Set(RedisClient.Context(), key, val, 0).Err() if err != nil { log.Panicln("Cache to Redis fail:", err) } return &user, nil }
3.測試
我們完成了快取邏輯的編寫。現在我們來測試一下這份程式碼,看看運行效果如何。
首先,我們測試程式第一次查詢使用者資訊需要從MySQL中讀取:
func main() { id := 1 user, err := getUserByID(id) if err != nil { log.Fatal(err) return } fmt.Printf("User info: id=%d, username=%s, password=%s, age=%d ", user.ID, user.Username, user.Password, user.Age) }
運行程序,輸出如下:
Cache miss User info: id=1, username=kirito, password=123456, age=18
可以看到程式從MySQL中取出了用戶訊息,並將其存入了Redis快取中。
第二次查詢同樣的使用者後,程式將從Redis讀取使用者資訊而不是存取MySQL資料庫:
func main() { id := 1 user, err := getUserByID(id) if err != nil { log.Fatal(err) return } fmt.Printf("User info: id=%d, username=%s, password=%s, age=%d ", user.ID, user.Username, user.Password, user.Age) }
運行程序,輸出如下:
Get from Redis: {"ID":1,"Username":"kirito","Password":"123456","Age":18} User info: id=1, username=kirito, password=123456, age=18
可以看到程式直接從Redis讀取了用戶信息,而沒有存取MySQL資料庫,這證明了快取的實用性。
總結
在本文中,我們介紹了Golang中使用Redis快取機制來優化資料庫存取效率的實踐。透過編寫getUserByID函數,我們在查詢使用者資訊時首先嘗試從Redis讀取資訊以加速查詢速度,如果Redis中沒有該使用者資訊則從MySQL讀取並將其存入Redis。將資料進行快取後,程式在多次存取相同資料時,可以直接從快取中讀取,而不需要每次都去存取資料庫。
要注意的是,快取的使用需要避免髒資料產生。對於資料的CRUD操作,快取也需要跟隨資料進行操作,以確保資料在快取和資料庫中的一致性。
總的來說,使用快取機制可以大幅提高程式的效能,並且在處理大量資料的時候特別有效。這種策略在高並發系統中也非常實用,建議開發者嘗試。
以上是Golang中使用快取加速資料庫存取效率的實踐。的詳細內容。更多資訊請關注PHP中文網其他相關文章!