Golang управляет базой данных Redis

Go
Golang управляет базой данных Redis

предыдущий постGolang управляет базой данных MySqlПредставлено, как работать с базой данных MySql на языке Go, а также,Redis также часто используется при разработке проектов, поэтому в этой статье также представлен язык Go.go-redisОсновное использование библиотеки — использование языка Go для работы с базой данных Redis.

Введение в Redis

Redis — это база данных в памяти с открытым исходным кодом.Redis предоставляет множество различных типов структур данных, и проблемы во многих бизнес-сценариях могут быть естественным образом сопоставлены с этими структурами данных. Кроме того, благодаря таким функциям, как репликация, сохранение и сегментирование на стороне клиента, мы можем легко масштабировать Redis до системы, которая может содержать сотни гигабайт данных и обрабатывать миллионы запросов в секунду.

Структуры данных, поддерживаемые Redis

Redis поддерживает такие вещи, как строки, хэши, списки, наборы, отсортированные наборы с запросами диапазона, растровые изображения, гиперлоглоги, запросы радиуса и потоки, геопространственные индексы и другие структуры данных (геопространственные индексы), чаще всего используются первые пять структур данных.

Сценарии приложений Redis

  • Система кэширования для снижения нагрузки на основную базу данных (MySQL).

  • Сценарии подсчета, такие как подписчики и подписчики в Weibo и Douyin.

  • Популярные рейтинги, сцены, которые нужно отсортировать, особенно подходят для ZSET.

  • Функцию очереди можно реализовать с помощью LIST.

Подготовьте среду Redis

Здесь мы напрямую используем Docker для запуска среды Redis, удобной для изучения и использования.

Пример докера, запускающего сервер Redis с версией 5.0.7 с именем redis507:

docker run --name redis507 -p 6379:6379 -d redis:5.0.7

**Примечание.** Укажите здесь версию, имя контейнера и номер порта в соответствии с вашими потребностями.

Запустите redis-cli для подключения к указанному выше серверу redis:

docker run -it --network host --rm redis:5.0.7 redis-cli

библиотека go-redis

Установить

В отличие от другой часто используемой клиентской библиотеки redis языка Go: redigo, мы используем здесьGitHub.com/go-Redis/hot…Подключение к базе данных Redis и работа сgo-redisПоддерживает подключение к Sentinel и Redis в кластерном режиме.

Скачайте и установите с помощью следующих команд:

go get -u github.com/go-redis/redis

нормальное соединение

package main​ import "github.com/go-redis/redis"​// 声明一个全局的rdb变量var rdb *redis.Client​// 初始化连接func initClient() (err error) {  rdb = redis.NewClient(&redis.Options{    Addr:     "localhost:6379",    Password: "", // no password set    DB:       0,  // use default DB  })​  _, err = rdb.Ping().Result()  if err != nil {    return err  }  return nil}​func main() {  err := initClient()  if err != nil {    panic(err)  }}

Относится к новой версии V8

Последняя версияgo-redisСоответствующие команды библиотеки должны быть переданыcontext.ContextПараметры, например:

package main​import (  "context"  "fmt"  "github.com/go-redis/redis"  "time"​  "github.com/go-redis/redis/v8" // 注意导入的是新版本)​var (  rdb *redis.Client)​// 初始化连接func initClient() (err error) {  rdb = redis.NewClient(&redis.Options{    Addr:     "localhost:16379",    Password: "",  // no password set    DB:       0,   // use default DB    PoolSize: 100, // 连接池大小  })​  ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)  defer cancel()​  _, err = rdb.Ping(ctx).Result()  return err}​func V8Example() {  ctx := context.Background()  if err := initClient(); err != nil {    return  }​  err := rdb.Set(ctx, "key", "value", 0).Err()  if err != nil {    panic(err)  }​  val, err := rdb.Get(ctx, "key").Result()  if err != nil {    panic(err)  }  fmt.Println("key", val)​  val2, err := rdb.Get(ctx, "key2").Result()  if err == redis.Nil {    fmt.Println("key2 does not exist")  } else if err != nil {    panic(err)  } else {    fmt.Println("key2", val2)  }  // Output: key value  // key2 does not exist}

Подключить режим Redis Sentinel

func initClient()(err error){  rdb := redis.NewFailoverClient(&redis.FailoverOptions{    MasterName:    "master",    SentinelAddrs: []string{"x.x.x.x:26379", "xx.xx.xx.xx:26379", "xxx.xxx.xxx.xxx:26379"},  })  _, err = rdb.Ping().Result()  if err != nil {    return err  }  return nil}

Подключиться к кластеру Redis

func initClient()(err error){  rdb := redis.NewClusterClient(&redis.ClusterOptions{    Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},  })  _, err = rdb.Ping().Result()  if err != nil {    return err  }  return nil}

основное использование

установить/получить пример

func redisExample() {  err := rdb.Set("score", 100, 0).Err()  if err != nil {    fmt.Printf("set score failed, err:%v\n", err)    return  }​  val, err := rdb.Get("score").Result()  if err != nil {    fmt.Printf("get score failed, err:%v\n", err)    return  }  fmt.Println("score", val)​  val2, err := rdb.Get("name").Result()  if err == redis.Nil {    fmt.Println("name does not exist")  } else if err != nil {    fmt.Printf("get name failed, err:%v\n", err)    return  } else {    fmt.Println("name", val2)  }}

пример zset

func redisExample2() {  zsetKey := "language_rank"  languages := []redis.Z{    redis.Z{Score: 90.0, Member: "Golang"},    redis.Z{Score: 98.0, Member: "Java"},    redis.Z{Score: 95.0, Member: "Python"},    redis.Z{Score: 97.0, Member: "JavaScript"},    redis.Z{Score: 99.0, Member: "C/C++"},  }  // ZADD  num, err := rdb.ZAdd(zsetKey, languages...).Result()  if err != nil {    fmt.Printf("zadd failed, err:%v\n", err)    return  }  fmt.Printf("zadd %d succ.\n", num)​  // 把Golang的分数加10  newScore, err := rdb.ZIncrBy(zsetKey, 10.0, "Golang").Result()  if err != nil {    fmt.Printf("zincrby failed, err:%v\n", err)    return  }  fmt.Printf("Golang's score is %f now.\n", newScore)​  // 取分数最高的3个  ret, err := rdb.ZRevRangeWithScores(zsetKey, 0, 2).Result()  if err != nil {    fmt.Printf("zrevrange failed, err:%v\n", err)    return  }  for _, z := range ret {    fmt.Println(z.Member, z.Score)  }​  // 取95~100分的  op := redis.ZRangeBy{    Min: "95",    Max: "100",  }  ret, err = rdb.ZRangeByScoreWithScores(zsetKey, op).Result()  if err != nil {    fmt.Printf("zrangebyscore failed, err:%v\n", err)    return  }  for _, z := range ret {    fmt.Println(z.Member, z.Score)  }}

Результат выглядит следующим образом:

$ ./06redis_demo zadd 0 succ.Golang's score is 100.000000 now.Golang 100C/C++ 99Java 98JavaScript 97Java 98C/C++ 99Golang 100

Получить ключ от префикса

vals, err := rdb.Keys(ctx, "prefix*").Result()

Выполнить пользовательскую команду

res, err := rdb.Do(ctx, "set", "key", "value").Result()

Удалить ключ по подстановочному знаку

Когда количество ключей, соответствующих подстановочным знакам, невелико, вы можете использоватьKeys()Получить все ключи в использованииDelкоманда удалить. Если количество ключей очень велико, мы можем использовать их вместеScanКоманда иDelКоманда завершает удаление.

func exampleTongPeiFu() {  ctx := context.Background()  iter := rdb.Scan(ctx, 0, "prefix*", 0).Iterator()  for iter.Next(ctx) {    err := rdb.Del(ctx, iter.Val()).Err()    if err != nil {      panic(err)    }  }  if err := iter.Err(); err != nil {    panic(err)  }}

Pipeline

PipelineВ основном оптимизация сети. По сути, это означает, что клиент буферизует кучу команд и отправляет их на сервер сразу. Выполнение этих команд в транзакции не гарантируется. Преимущество этого заключается в экономии сетевого времени приема-передачи (RTT) для каждой команды.

PipelineОсновной пример выглядит следующим образом:

pipe := rdb.Pipeline()​incr := pipe.Incr("pipeline_counter")pipe.Expire("pipeline_counter", time.Hour)​_, err := pipe.Exec()fmt.Println(incr.Val(), err)

Приведенный выше код эквивалентен одновременной отправке следующих двух команд на сервер Redis для выполнения без использованияPipelineПо сравнению с одним RTT можно уменьшить.

INCR pipeline_counterEXPIRE pipeline_counts 3600

также можно использоватьPipelined:

var incr *redis.IntCmd_, err := rdb.Pipelined(func(pipe redis.Pipeliner) error {  incr = pipe.Incr("pipelined_counter")  pipe.Expire("pipelined_counter", time.Hour)  return nil})fmt.Println(incr.Val(), err)

В некоторых сценариях, когда у нас есть несколько команд для выполнения, мы можем рассмотреть возможность использования конвейера для оптимизации.

Полный пример кода заархивирован на GitHub

Полный пример кода базы данных Redis операции Golang

Вышеприведенное является введением в работу с Redis на языке Go. Спасибо за чтение. Если у вас есть какие-либо вопросы или комментарии, прокомментируйте и поделитесь ими ниже.

Источник статьи"Перейти клавишный воин"Общественный номер, приветствуем внимание, чтобы обменяться вместе!"

Предыдущая статья:

Операционная база данных Golang MySql