Golang でキャッシュを使用して大量のリクエストを処理するための実践的なテクニック
インターネットの発展に伴い、大量のリクエストは現代の Web アプリケーションにとって避けられない問題となっています。これらのリクエストには効率的に応答する必要があります。そうしないと、ユーザー エクスペリエンスが重大な影響を受けます。 Golang では、キャッシュを使用してリクエストの応答速度を向上させ、大量のリクエストの課題にうまく対処できます。
この記事では、キャッシュのデータ構造、キャッシュの生成方法、キャッシュの更新と削除、キャッシュ容量と同時実行セキュリティなど、Golang でキャッシュを使用して大量のリクエストを処理するための実践的なスキルを紹介します。
キャッシュ データ構造
Golang のキャッシュ データ構造は、通常、map を使用して実装されます。 Golang のマップは検索効率が非常に高く、動的な要素の追加や削除にも対応できるためです。
たとえば、ユーザー情報を格納するマップを定義できます:
type User struct { Name string Age int } var usersCache = make(map[int]*User)
このうち、usersCache はユーザー情報をキャッシュするために使用されるマップで、キー値はユーザー ID、値はユーザー構造体のポインタ。
キャッシュの生成方法
キャッシュの生成方法は、静的生成と動的生成の 2 つに分類できます。
静的生成とは、アプリケーション起動時にキャッシュを生成することを指し、キャッシュデータが頻繁に変更されない場合に適した方法です。プログラムの初期化中にデータベースまたは他のデータ ソースからデータを読み取り、キャッシュすることができます。
たとえば、プログラムの開始時にデータベースからユーザー情報を読み取り、キャッシュすることができます。
func init() { // 从数据库中读取用户信息 rows, err := db.Query("SELECT * FROM users") if err != nil { log.Fatal(err) } defer rows.Close() // 将用户信息缓存起来 for rows.Next() { var user User if err := rows.Scan(&user.ID, &user.Name, &user.Age); err != nil { log.Fatal(err) } usersCache[user.ID] = &user } }
動的生成とは、キャッシュにデータがない場合に、データが次のように生成されることを意味します。キャッシュはソースから動的に生成されます。
たとえば、GetUser 関数を定義して、ユーザー情報を取得し、データ ソースからデータを読み取り、必要に応じてキャッシュを生成できます。
func GetUser(id int) (*User, error) { // 先从缓存中查找用户信息 user, ok := usersCache[id] if ok { return user, nil } // 如果缓存中不存在,则从数据库中读取用户信息 var user User err := db.QueryRow("SELECT * FROM users WHERE id=?", id).Scan(&user.ID, &user.Name, &user.Age) if err != nil { return nil, err } // 将用户信息缓存起来 usersCache[id] = &user return &user, nil }
キャッシュの更新と削除
Whenデータ ソース内のデータが変更されると、それに応じてキャッシュ内のデータも更新および削除する必要があります。
たとえば、ユーザー情報が変更された場合、キャッシュ内のユーザー情報を更新する必要があります:
func UpdateUser(id int, name string, age int) error { // 更新数据库中的用户信息 _, err := db.Exec("UPDATE users SET name=?, age=? WHERE id=?", name, age, id) if err != nil { return err } // 更新缓存中的用户信息 user, ok := usersCache[id] if ok { user.Name = name user.Age = age } return nil }
ユーザーがログアウトするとき、キャッシュからユーザー情報を削除する必要があります:
func DeleteUser(id int) error { // 从数据库中删除用户信息 _, err := db.Exec("DELETE FROM users WHERE id=?", id) if err != nil { return err } // 从缓存中删除用户信息 delete(usersCache, id) return nil }
キャッシュ容量と同時実行セキュリティ
キャッシュ容量は非常に重要な問題です。キャッシュが十分に大きくないと、キャッシュされたデータが頻繁にリサイクルおよび再適用され、システムのパフォーマンスに影響を与える可能性があります。 。キャッシュが大きすぎると、メモリ オーバーフローやシステム クラッシュなどの問題が発生する可能性があります。したがって、キャッシュを設計する際にはキャッシュ容量を十分に考慮する必要があります。
さらに、複数のゴルーチンが同時にキャッシュにアクセスする可能性があるため、キャッシュの同時実行性のセキュリティにも注意が必要です。同期パッケージによって提供される Mutex または RWMutex を使用して、キャッシュの同時実行の安全性を確保できます。
たとえば、RWMutex を使用して、GetUser 関数の同時実行性の安全性を確保できます。
type UsersCache struct { cache map[int]*User mu sync.RWMutex } var usersCache = UsersCache{cache: make(map[int]*User)} func GetUser(id int) (*User, error) { usersCache.mu.RLock() user, ok := usersCache.cache[id] usersCache.mu.RUnlock() if ok { return user, nil } usersCache.mu.Lock() defer usersCache.mu.Unlock() // 二次检查 user, ok = usersCache.cache[id] if !ok { // 如果缓存中不存在,则从数据库中读取用户信息 var user User err := db.QueryRow("SELECT * FROM users WHERE id=?", id).Scan(&user.ID, &user.Name, &user.Age) if err != nil { return nil, err } // 将用户信息缓存起来 usersCache.cache[id] = &user return &user, nil } return user, nil }
上の例では、RWMutex を使用してキャッシュの同時実行性の安全性を確保し、二重ロックを使用します。テクノロジー キャッシュの重複作成を避けるため。
概要
この記事では、キャッシュ データ構造、キャッシュ生成方法、キャッシュ更新と削除、キャッシュ容量と同時実行性、安全性など、キャッシュを使用して Golang で大量のリクエストを処理するための実践的なスキルを紹介します。側面。キャッシュを柔軟に適用することで、大量のリクエストの課題にうまく対処し、システムのパフォーマンスと安定性を向上させることができます。
以上がGolang でキャッシュを使用して大量のリクエストを処理するための実践的なテクニック。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。