当前位置:网站首页>Connexion d'initialisation pour go redis
Connexion d'initialisation pour go redis
2022-07-06 09:09:00 【- Pompéi】
Table des matières
- go-redisInitialisation de la connexion
go-redisInitialisation de la connexion
Installation
Si vous utilisezRedis 6,Veuillez installer go-redis/ v8:
go get github.com/go-redis/redis/v8
Si vous utilisezRedis 7,Veuillez installer go-redis/ v9(Actuellement en phase d'essai):
go get github.com/go-redis/redis/v9
Connectez - vous à Redis Serveur
Pour se connecter à Redis Serveur:
import "github.com/go-redis/redis/v8"
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
Une autre méthode populaire est d'utiliser des chaînes de connexion :
opt, err := redis.ParseURL("redis://<user>:<pass>@localhost:6379/<db>")
if err != nil {
panic(err)
}
rdb := redis.NewClient(opt)
Utiliser TLS
Pour activer TLS/SSL, Vous devez fournir un tls.Config
. Si vous utilisez un certificat privé ,Oui. Spécifie d'ouvrir dans une nouvelle fenêtre Ils sonttls.Config
.
rdb := redis.NewClient(&redis.Options{
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
//Certificates: []tls.Certificate{cert}
},
})
Si vous obtenezx509: cannot validate certificate for xxx.xxx.xxx.xxx because it doesn't contain any IP SANs
, Essayez de définir ServerName
Options:
rdb := redis.NewClient(&redis.Options{
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
ServerName: "your.domain.com",
},
})
Adoption SSH
Adoption SSH Connexion au canal:
sshConfig := &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{
ssh.Password("password")},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: 15 * time.Second,
}
sshClient, err := ssh.Dial("tcp", "remoteIP:22", sshConfig)
if err != nil {
panic(err)
}
rdb := redis.NewClient(&redis.Options{
Addr: net.JoinHostPort("127.0.0.1", "6379"),
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
return sshClient.Dial(network, addr)
},
// Disable timeouts, because SSH does not support deadlines.
ReadTimeout: -1,
WriteTimeout: -1,
})
dial tcp: i/o timeout
Quand go-redis Impossible de se connecter à Redis Quand le serveur, Vous recevrez dial tcp: i/o timeout
Messages d'erreur,Par exemple, Lorsque le serveur est éteint ou que le port est protégé par un pare - feu .Pour vérifier Redis Si le serveur écoute le port , S'il vous plaît, en cours go-redis Exécution sur l'hôte du client telnet Les ordres:
telnet localhost 6379
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
Si vous utilisez Docker、Istio Ou toute autre grille de services /sidecar, Assurez - vous que l'application démarre lorsque le conteneur est entièrement disponible ,Par exemple,Via la configuration Le bilan de santé s'ouvre dans une nouvelle fenêtre Utiliser Docker EtholdApplicationUntilProxyStarts
Istio.
Context
Chaque Redis Les commandes prennent toutes un contexte , Vous pouvez l'utiliser pour définir Temps mort Ou diffuser des informations ,Par exempleContexte de suivi.
ctx := context.Background()
Exécuter les commandes
Exécuter les commandes:
val, err := rdb.Get(ctx, "key").Result()
fmt.Println(val)
Ou, Vous pouvez enregistrer la commande et accéder aux valeurs et aux erreurs plus tard, respectivement :
get := rdb.Get(ctx, "key")
fmt.Println(get.Val(), get.Err())
Exécuter une commande non prise en charge
Pour exécuter n'importe quel /Commandes personnalisées:
val, err := rdb.Do(ctx, "get", "key").Result()
if err != nil {
if err == redis.Nil {
fmt.Println("key does not exists")
return
}
panic(err)
}
fmt.Println(val.(string))
Do
Retour à unCmdOuvrir dans une nouvelle fenêtre Il y a un tas d'assistants qui peuvent s'occuper de interface{}
Valeur:
// Text is a shortcut for get.Val().(string) with proper error handling.
val, err := rdb.Do(ctx, "get", "key").Text()
fmt.Println(val, err)
Liste complète des assistants :
s, err := cmd.Text()
flag, err := cmd.Bool()
num, err := cmd.Int()
num, err := cmd.Int64()
num, err := cmd.Uint64()
num, err := cmd.Float32()
num, err := cmd.Float64()
ss, err := cmd.StringSlice()
ns, err := cmd.Int64Slice()
ns, err := cmd.Uint64Slice()
fs, err := cmd.Float32Slice()
fs, err := cmd.Float64Slice()
bs, err := cmd.BoolSlice()
redis.Nil
go-redis Exporterredis.Nil
Erreur et Redis Renvoie le serveur quand il répond (nil)
.Vous pouvez utiliser redis-cli Vérifiez Redis Réponse retournée.
Dans l'exemple suivant,Nous utilisonsredis.Nil
Pour distinguer une réponse à chaîne vide de nil Réponse(key N'existe pas):
val, err := rdb.Get(ctx, "key").Result()
switch {
case err == redis.Nil:
fmt.Println("key does not exist")
case err != nil:
fmt.Println("Get failed", err)
case val == "":
fmt.Println("value is empty")
}
GET
Par exemple, Ce n'est pas le seul retour nil Ordre de réponse ,BLPOP
- Oui.ZSCORE
Peut revenir àredis.Nil
.
Conn
Conn Représente un seul Redis Connexion, Au lieu du pool de connexion . À moins qu'un seul élément consécutif ne soit particulièrement nécessaire Redis Connexion, Sinon, l'exécution des commandes à partir du client est préférable .
cn := rdb.Conn(ctx)
defer cn.Close()
if err := cn.ClientSetName(ctx, "myclient").Err(); err != nil {
panic(err)
}
name, err := cn.ClientGetName(ctx).Result()
if err != nil {
panic(err)
}
fmt.Println("client name", name)
redisCluster
go-redis Apportez - le vous - même.Redis Cluster Le client s'ouvre dans une nouvelle fenêtre . En bas,redis.ClusterClient
Pourredis.Client
Communication avec chaque noeud du cluster .Tout le monde.redis.Client
Maintenir un pool de connexions séparé .
Pour se connecter à Redis Cluster:
import "github.com/go-redis/redis/v8"
rdb := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{
":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
// To route commands by latency or randomly, enable one of the following.
//RouteByLatency: true,
//RouteRandomly: true,
})
Tranches itératives :
err := rdb.ForEachShard(ctx, func(ctx context.Context, shard *redis.Client) error {
return shard.Ping(ctx).Err()
})
if err != nil {
panic(err)
}
Pour itérer sur le noeud Maître ,Veuillez utiliserForEachMaster
. Pour traverser le noeud esclave ,Veuillez utiliserForEachSlave
.
Pour modifier les options pour certains éclats :
rdb := redis.NewClusterClient(&redis.ClusterOptions{
NewClient: func(opt *redis.Options) *redis.NewClient {
user, pass := userPassForAddr(opt.Addr)
opt.Username = user
opt.Password = pass
return redis.NewClient(opt)
},
})
redisSentinelle
Redis Client serveur
Connectez - vous à Redis SentinelGestion Redis Le serveur s'ouvre dans une nouvelle fenêtre :
import "github.com/go-redis/redis/v8"
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "master-name",
SentinelAddrs: []string{
":9126", ":9127", ":9128"},
})
De v8 C'est parti., Vous pouvez utiliser l'expérience NewFailoverClusterClient
Routage des commandes en lecture seule vers le noeud esclave :
import "github.com/go-redis/redis/v8"
rdb := redis.NewFailoverClusterClient(&redis.FailoverOptions{
MasterName: "master-name",
SentinelAddrs: []string{
":9126", ":9127", ":9128"},
// To route commands by latency or randomly, enable one of the following.
//RouteByLatency: true,
//RouteRandomly: true,
})
Redis Le client Sentinel
Pour se connecter à Redis Sentinel En soi:
import "github.com/go-redis/redis/v8"
sentinel := redis.NewSentinelClient(&redis.Options{
Addr: ":9126",
})
addr, err := sentinel.GetMasterAddrByName(ctx, "master-name").Result()
redisAnneau
Introduction
Ring C'est un Redis Client, Il utilise un hachage cohérent sur plusieurs Redis Serveur(Fractionnement) Distribuer les clés entre .Plusieurs goroutine L'utilisation simultanée est sûre .
Ring Surveiller l'état de chaque tranche et retirer la tranche morte de l'anneau . Quand une pièce est en ligne , Il sera ajouté à la boucle . Cela permet une disponibilité maximale et une tolérance aux pannes de partition , Mais il n'y a pas de cohérence entre les différents segments ou même entre les clients . Chaque client utilise le fragment disponible pour le client , Et ne pas coordonner avec d'autres clients lorsque l'état du patch change .
Quand vous avez besoin de plus d'un Redis Lorsque le serveur est mis en cache et peut tolérer la perte de données lorsque l'un des serveurs s'écrase ,Il faut utiliser Ring.Sinon, vous devez utiliserRedis ClusterOuRedis Server.
Démarrage rapide
Créer un contenant 3 En morceaux Ring Cluster:
import "github.com/go-redis/redis/v8"
rdb := redis.NewRing(&redis.RingOptions{
Addrs: map[string]string{
"shard1": ":7000",
"shard2": ":7001",
"shard3": ":7002",
},
})
Le client peut alors utiliser comme d'habitude :
if err := rdb.Set(ctx, "foo", "bar", 0).Err(); err != nil {
panic(err)
}
Tranches itératives :
err := rdb.ForEachShard(ctx, func(ctx context.Context, shard *redis.Client) error {
return shard.Ping(ctx).Err()
})
if err != nil {
panic(err)
}
Chaque option de fractionnement
Pour modifier les options de connexion slice :
rdb := redis.NewRing(&redis.RingOptions{
NewClient: func(opt *redis.Options) *redis.NewClient {
user, pass := userPassForAddr(opt.Addr)
opt.Username = user
opt.Password = pass
return redis.NewClient(opt)
},
})
Distribution des clés
Par défaut,Ring UtiliserRendezvousOuvrir dans une nouvelle fenêtre Hacher les clés sur plusieurs partitions . Mais vous pouvez modifier l'implémentation de hachage cohérente par défaut :
import "github.com/golang/groupcache/consistenthash"
ring := redis.NewRing(&redis.RingOptions{
NewConsistentHash: func() {
return consistenthash.New(100, crc32.ChecksumIEEE)
},
})
Redis Client universel
UniversalClient
C'est un client abstrait , Sur la base des options offertes ,Représentant a ClusterClient
、 aFailoverClient
Ou single-node Client
. Ceci est utile pour tester localement des applications spécifiques à un Cluster ou pour avoir différents clients dans différents environnements .
NewUniversalClient
Retour à un nouveau Multi - client . Le type de client retourné dépend des conditions suivantes :
- Si cette option est spécifiée ,Renvoie
MasterName
Appui sentinelle .FailoverClient
- Si la quantité
Addrs
Pour 2 Ou plus,ClusterClient
Renvoie a. - Sinon,Retour à un seul noeud
Client
.
// rdb is *redis.Client.
rdb := NewUniversalClient(&redis.UniversalOptions{
Addrs: []string{
":6379"},
})
// rdb is *redis.ClusterClient.
rdb := NewUniversalClient(&redis.UniversalOptions{
Addrs: []string{
":6379", ":6380"},
})
// rdb is *redis.FailoverClient.
rdb := NewUniversalClient(&redis.UniversalOptions{
Addrs: []string{
":6379"},
MasterName: "mymaster",
})
Golang Redis Tuyauterie、WATCH Et services
Utilisation de tuyaux pour accélérer Redis
Redis Le pipeline permet d'utiliser un seul client -Serveur- Le client exécute plusieurs commandes pour améliorer les performances . Vous pouvez placer les commandes dans le pipeline , Ensuite, utilisez une seule écriture comme une seule commande + Lire l'opération exécuter la commande en file d'attente , Au lieu de les exécuter un par un 100 Commandes.
Pour utiliser une seule écriture + L'opération read exécute plusieurs commandes :
pipe := rdb.Pipeline()
incr := pipe.Incr(ctx, "pipeline_counter")
pipe.Expire(ctx, "pipeline_counter", time.Hour)
cmds, err := pipe.Exec(ctx)
if err != nil {
panic(err)
}
// The value is available only after Exec is called.
fmt.Println(incr.Val())
Ou, Vous pouvez utiliser Pipelined
which Appelez:Exec
var incr *redis.IntCmd
cmds, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
incr = pipe.Incr(ctx, "pipelined_counter")
pipe.Expire(ctx, "pipelined_counter", time.Hour)
return nil
})
if err != nil {
panic(err)
}
// The value is available only after the pipeline is executed.
fmt.Println(incr.Val())
Le pipeline renvoie également les commandes exécutées , Vous pouvez donc les parcourir pour récupérer les résultats :
cmds, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
for i := 0; i < 100; i++ {
pipe.Get(ctx, fmt.Sprintf("key%d", i))
}
return nil
})
if err != nil {
panic(err)
}
for _, cmd := range cmds {
fmt.Println(cmd.(*redis.StringCmd).Val())
}
Transactions EtWatch
Utiliser Redis La transaction s'ouvre dans une nouvelle fenêtre , Vous pouvez observer le changement de clé et exécuter le pipeline seulement si la clé observée n'a pas été modifiée par un autre client . Cette méthode de résolution des conflits est également connue sous le nom de Verrouillage optimiste
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
TxPipelined
Vous pouvez utiliserand Emballage avec MULTI Et EXEC Le tuyau de commande TxPipeline
, Mais ce n'est pas très utile en soi :
cmds, err := rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
for i := 0; i < 100; i++ {
pipe.Get(ctx, fmt.Sprintf("key%d", i))
}
return nil
})
if err != nil {
panic(err)
}
// MULTI
// GET key0
// GET key1
// ...
// GET key99
// EXEC
Au contraire.,Vous devriez utiliserWatch Gérer les pipelines de transaction Ouvrir dans une nouvelle fenêtre,Par exemple, Nous pouvons le faire correctement INCROuvrir dans une nouvelle fenêtreUtiliserGET
,SET
EtWATCH
Ordre de Veuillez noter comment nous utilisonsredis.TxFailedErr
Pour vérifier si la transaction a échoué .
// Redis transactions use optimistic locking.
const maxRetries = 1000
// Increment transactionally increments the key using GET and SET commands.
func increment(key string) error {
// Transactional function.
txf := func(tx *redis.Tx) error {
// Get the current value or zero.
n, err := tx.Get(ctx, key).Int()
if err != nil && err != redis.Nil {
return err
}
// Actual operation (local in optimistic lock).
n++
// Operation is commited only if the watched keys remain unchanged.
_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Set(ctx, key, n, 0)
return nil
})
return err
}
// Retry if the key has been changed.
for i := 0; i < maxRetries; i++ {
err := rdb.Watch(ctx, txf, key)
if err == nil {
// Success.
return nil
}
if err == redis.TxFailedErr {
// Optimistic lock lost. Retry.
continue
}
// Return any other error.
return err
}
return errors.New("increment reached maximum number of retries")
}
Redis Publier un abonnement
go-redis Autoriser la publication de messages et l'abonnement aux canaux . En cas d'erreur réseau , Il se reconnecte aussi automatiquement à Redis Server.
Pour publier un message :
err := rdb.Publish(ctx, "mychannel1", "payload").Err()
if err != nil {
panic(err)
}
Abonnez - vous au canal:
// There is no error because go-redis automatically reconnects on error.
pubsub := rdb.Subscribe(ctx, "mychannel1")
// Close the subscription when we are done.
defer pubsub.Close()
Pour recevoir un message:
for {
msg, err := pubsub.ReceiveMessage(ctx)
if err != nil {
panic(err)
}
fmt.Println(msg.Channel, msg.Payload)
}
Mais la façon la plus simple est de fermer avec l'abonnement Go Channel:
ch := pubsub.Channel()
for msg := range ch {
fmt.Println(msg.Channel, msg.Payload)
}
边栏推荐
- 注意力机制的一种卷积替代方式
- LeetCode:34. Find the first and last positions of elements in a sorted array
- LeetCode:836. 矩形重叠
- Leetcode: Sword Finger offer 42. Somme maximale des sous - tableaux consécutifs
- I-BERT
- How to intercept the string correctly (for example, intercepting the stock in operation by applying the error information)
- Tdengine biweekly selection of community issues | phase III
- Selenium+Pytest自动化测试框架实战
- Intel distiller Toolkit - Quantitative implementation 3
- Simclr: comparative learning in NLP
猜你喜欢
[sword finger offer] serialized binary tree
Export IEEE document format using latex
Pytest parameterization some tips you don't know / pytest you don't know
Esp8266-rtos IOT development
Mongodb installation and basic operation
数学建模2004B题(输电问题)
LeetCode:236. 二叉树的最近公共祖先
UML diagram memory skills
LeetCode:498. 对角线遍历
Intel distiller Toolkit - Quantitative implementation 3
随机推荐
项目连接数据库遇到的问题及解决
BMINF的后训练量化实现
Improved deep embedded clustering with local structure preservation (Idec)
Notes 01
I-BERT
LeetCode:124. 二叉树中的最大路径和
[MySQL] multi table query
LeetCode:498. 对角线遍历
[OC foundation framework] - [set array]
AcWing 2456. 记事本
Compétences en mémoire des graphiques UML
A convolution substitution of attention mechanism
Guangzhou will promote the construction of a child friendly city, and will explore the establishment of a safe area 200 meters around the school
Leetcode: Sword finger offer 42 Maximum sum of continuous subarrays
Advance Computer Network Review(1)——FatTree
Advanced Computer Network Review(3)——BBR
Leetcode: Sword finger offer 48 The longest substring without repeated characters
LeetCode:214. Shortest palindrome string
CUDA实现focal_loss
Using C language to complete a simple calculator (function pointer array and callback function)