Maison  >  Article  >  base de données  >  Quelles sont les méthodes utilisées par le client Go Redis ?

Quelles sont les méthodes utilisées par le client Go Redis ?

WBOY
WBOYavant
2023-06-03 09:01:381035parcourir

    Introduction

    La couche inférieure de go-redis et redigo est implémentée en appelant la méthode universelle Do, mais

    redigo :

    • Puisque l'entrée est de type universel, vous devez vous souvenir des paramètres et renvoyer valeurs de chaque commande, il est très peu convivial à utiliser

    • Le type de paramètre est un type universel, donc le type de paramètre ne peut pas être vérifié pendant la phase de compilation

    • Chaque commande nécessite du temps pour enregistrer l'utilisation. méthode, nombre de paramètres, etc., et le coût d'utilisation est élevé ;

    go-redis :

    • détaille les fonctions de chaque commande redis. Il suffit de mémoriser la commande et de vérifier directement l'application d'interface. pour un usage spécifique. Le coût d'utilisation est faible

    • Deuxièmement, il unifie le type de données en fonction du type de redis sous-jacent, ce qui peut aider à vérifier le type de paramètre lors de la compilation

    • Et sa réponse est renvoyée uniformément en utilisant l'interface de résultat, garantissant l'exactitude du type de paramètre renvoyé et le rendant plus convivial ;

    Comparaison des performances

    BenchmarkRedis/redigo_client_Benchmark-12     31406	     36919 ns/op
    BenchmarkRedis/go-redis_client_Benchmark-12   29977	     38152 ns/op
    BenchmarkRedis/redigo_client_Benchmark-12     27928	     39923 ns/op
    BenchmarkRedis/go-redis_client_Benchmark-12   27127	     46451 ns/op

    Comme le montre la figure ci-dessus, bien que go-redis soit environ 10 % plus lent que redigo dans à chaque opération, redigo doit afficher la connexion application/fermeture, donc la différence de performances globale entre les deux est en fait. La petite

    bibliothèque Redigo

    redigo est le client Go de la base de données Redis. Le fonctionnement de Redis est fondamentalement le même que les commandes. Les commandes Redigo sont essentiellement implémentées via la méthode Do.

    Do(ctx context.Context, cmd string, args ...interface{}) (interface{}, error)

    Bien que l'appel des paramètres universels de la fonction Do puisse réaliser toutes les fonctions, mais il est très peu convivial à utiliser. Le type de paramètre est un type universel, donc le type de paramètre ne peut pas être vérifié pendant l'exécution. étape de compilation.Deuxièmement, chaque commande nécessite du temps pour enregistrer la méthode d'utilisation, le nombre de paramètres, etc., ce qui est coûteux à utiliser

    Démonstration

    Démontrer l'établissement de base du pool de connexions, le ping, les opérations de chaîne, les opérations de hachage, les opérations de liste, expirer et autres opérations

    package main
    import (
       "fmt"
       "github.com/gomodule/redigo/redis"
    )
    func main() {
       // 新建一个连接池
       var pool *redis.Pool
       pool = &redis.Pool{
          MaxIdle:     10,  //最初的连接数量
          MaxActive:   0,   //连接池最大连接数量,(0表示自动定义),按需分配
          IdleTimeout: 300, //连接关闭时间 300秒 (300秒不使用自动关闭)
          Dial: func() (redis.Conn, error) { //要连接的redis数据库
             return redis.Dial("tcp", "localhost:6379")
          },
       }
       conn := pool.Get() //从连接池,取一个链接
       defer conn.Close()
       // 0. ping正常返回pong, 异常res is nil, err not nil
       res, err := conn.Do("ping")
       fmt.Printf("ping res=%v\n", res)
       if err != nil {
          fmt.Printf("ping err=%v\n", err.Error())
       }
       // string操作
       // set
       res, err = conn.Do("set", "name", "测试001")
       fmt.Printf("set res=%v\n", res)
       if err != nil {
          fmt.Printf("set err=%v\n", err.Error())
       }
       // get
       res, err = redis.String(conn.Do("get", "name"))
       fmt.Printf("get res=%v\n", res)
       if err != nil {
          fmt.Printf("get err=%v\n", err.Error())
       }
       // MSet   MGet
       res, err = conn.Do("MSet", "name", "测试001", "age", 18)
       fmt.Printf("MSet res=%v\n", res)
       if err != nil {
          fmt.Printf("MSet err=%v\n", err.Error())
       }
       r, err := redis.Strings(conn.Do("MGet", "name", "age"))
       fmt.Printf("MGet res=%v\n", r)
       if err != nil {
          fmt.Printf("MGet err=%v\n", err.Error())
       }
       // expire
       res, err = conn.Do("expire", "name", 5)
       fmt.Printf("expire res=%v\n", r)
       if err != nil {
          fmt.Printf("expire err=%v\n", err.Error())
       }
       // list操作
       // lpush lpop
       res, err = conn.Do("lpush", "hobby", "篮球", "足球", "乒乓球")
       fmt.Printf("lpush res=%v\n", r)
       if err != nil {
          fmt.Printf("lpush err=%v\n", err.Error())
       }
       // lpop
       rs, er := conn.Do("lpop", "hobby")
       fmt.Printf("lpop res=%v\n", rs)
       if er != nil {
          fmt.Printf("lpop err=%v\n", er.Error())
       }
       // hash 操作
       // hset
       res, err = conn.Do("HSet", "userinfo", "name", "lqz")
       fmt.Printf("HSet res=%v\n", r)
       if err != nil {
          fmt.Printf("HSet err=%v\n", err.Error())
       }
       // hget
       r4, er4 := conn.Do("HGet", "userinfo", "name")
       fmt.Printf("HGet res=%v\n", r4)
       if er4 != nil {
          fmt.Printf("HGet err=%v\n", er4.Error())
       }
    }

    Introduction et utilisation des composants go-redis

    go-redis fournit trois modes client correspondant au serveur, au cluster et à la sentinelle, et le mode autonome, les trois modes sont communs dans le pool de connexions, et fournit également un mécanisme Hook flexible, dont la couche inférieure est en fait la méthode universelle Do appelée

    Quelles sont les méthodes utilisées par le client Go Redis ?

    Mais go-redis affine chacun. Il suffit de se souvenir de la fonction de chaque commande redis. Pour une utilisation spécifique, nous pouvons directement. Vérifiez l'application de l'interface.Le coût d'utilisation est faible;Deuxièmement, il unifie le type de données en fonction du type de redis sous-jacent, ce qui peut aider à vérifier le type de paramètre, et sa réponse est renvoyée uniformément à l'aide de l'interface de résultat. assurer l'exactitude du type de paramètre renvoyé et le rendre plus convivial

    Démonstration

    Démontre l'établissement de base du pool de connexions, le ping, les opérations de chaîne, les opérations de hachage et les opérations de liste, l'expiration et d'autres opérations

    func main() {
       var rdb = redis2.NewClient(
          &redis2.Options{
             Addr:     "localhost:6379",
             Password: "", DB: 1,
             MinIdleConns: 1,
             PoolSize:     1000,
          })
       ctx := context.Background()
       res, err = rdb.Ping(ctx).Result()
       fmt.Printf("ping res=%v\n", res)
       if err != nil {
          fmt.Printf("ping err=%v\n", err.Error())
       }
       // string操作
       // set
       res, err = rdb.Set(ctx, "name", "测试001", 0).Result()
       fmt.Printf("set res=%v\n", res)
       if err != nil {
          fmt.Printf("set err=%v\n", err.Error())
       }
       // get
       res, err = rdb.Get(ctx, "name").Result()
       fmt.Printf("get res=%v\n", res)
       if err != nil {
          fmt.Printf("get err=%v\n", err.Error())
       }
       // MSet   MGet
       res, err = rdb.MSet(ctx, "name", "测试001", "age", "18").Result()
       fmt.Printf("MSet res=%v\n", res)
       if err != nil {
          fmt.Printf("MSet err=%v\n", err.Error())
       }
       var ret []interface{}
       ret, err = rdb.MGet(ctx, "name", "age").Result()
       fmt.Printf("MGet res=%v\n", ret)
       if err != nil {
          fmt.Printf("MGet err=%v\n", err.Error())
       }
       // expire
       res, err = rdb.Expire(ctx, "name", time.Second).Result()
       fmt.Printf("expire res=%v\n", res)
       if err != nil {
          fmt.Printf("expire err=%v\n", err.Error())
       }
       // list操作
       // lpush lpop
       res, err = rdb.LPush(ctx, "hobby", "篮球", "足球", "乒乓球").Result()
       fmt.Printf("lpush res=%v\n", res)
       if err != nil {
          fmt.Printf("lpush err=%v\n", err.Error())
       }
       // lpop
       rs, err = rdb.LPop(ctx, "hobby").Result()
       fmt.Printf("lpop res=%v\n", rs)
       if er != nil {
          fmt.Printf("lpop err=%v\n", er.Error())
       }
       // hash 操作
       // hset
       res, err = rdb.HSet(ctx, "userinfo", "name", "lqz").Result()
       fmt.Printf("HSet res=%v\n", r)
       if err != nil {
          fmt.Printf("HSet err=%v\n", err.Error())
       }
       // hget
       r4, er4 = rdb.HGet(ctx, "userinfo", "name").Result()
       fmt.Printf("HGet res=%v\n", r4)
       if er4 != nil {
          fmt.Printf("HGet err=%v\n", er4.Error())
       }
    }

    Test de performances

    package main
    import (
       "context"
       redis2 "github.com/go-redis/redis/v8"
       "github.com/gomodule/redigo/redis"
       "testing"
       "time"
    )
    func BenchmarkRedis(b *testing.B) {
       // 新建一个连接池
       var pool *redis.Pool
       pool = &redis.Pool{
          MaxIdle:     10,   //最初的连接数量
          MaxActive:   1000, //连接池最大连接数量,(0表示自动定义),按需分配
          IdleTimeout: 300,  //连接关闭时间 300秒 (300秒不使用自动关闭)
          Dial: func() (redis.Conn, error) { //要连接的redis数据库
             return redis.Dial("tcp", "localhost:6379")
          },
       }
       var rdb = redis2.NewClient(
          &redis2.Options{
             Addr:         "localhost:6379",
             Password:     "",
             MinIdleConns: 10,
             PoolSize:     1000,
          })
       b.Run("redigo client Benchmark", func(b *testing.B) {
    		for j := 0; j < b.N; j++ {
    			conn := pool.Get() //从连接池,取一个链接
    			conn.Do("set", time.Now().String(), 10000, time.Second)
    			conn.Do("get", time.Now().String())
    			conn.Close()
    		}
    	})
    	ctx := context.Background()
    	b.Run("go-redis client Benchmark", func(b *testing.B) {
    		for j := 0; j < b.N; j++ {
    			rdb.Set(ctx,  time.Now().String(), 1000, time.Second)
    			rdb.Get(ctx,  time.Now().String())
    		}
    	})
    }

    Sortie du résultat

    goos : darwin
    goarch : amd64
    cpu : processeur Intel(R) Core(TM) i7-9750H à 2,60 GHz
    BenchmarkRedis
    BenchmarkRedis/redigo_client_Benchmark
    BenchmarkRedis /redigo_client_Benchmark-12         26 386       39 110 ns/op
    BenchmarkRedis /go-redis_client_Benchmark
    BenchmarkRedis/go-redis_client_Benchmark-12                 28186  37794 ns/op

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer