当前位置:网站首页>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:836. 矩形重叠
- Tdengine biweekly selection of community issues | phase III
- LeetCode:673. 最长递增子序列的个数
- [OC]-<UI入门>--常用控件-提示对话框 And 等待提示器(圈)
- How to effectively conduct automated testing?
- Booking of tourism products in Gansu quadrupled: "green horse" became popular, and one room of B & B around Gansu museum was hard to find
- 【每日一题】搬运工 (DFS / DP)
- Selenium+pytest automated test framework practice
- Simclr: comparative learning in NLP
- KDD 2022论文合集(持续更新中)
猜你喜欢
LeetCode:498. 对角线遍历
Intel Distiller工具包-量化实现2
LeetCode:221. 最大正方形
Selenium+Pytest自动化测试框架实战(下)
[sword finger offer] serialized binary tree
Pytest parameterization some tips you don't know / pytest you don't know
[MySQL] limit implements paging
Post training quantification of bminf
数字人主播618手语带货,便捷2780万名听障人士
LeetCode41——First Missing Positive——hashing in place & swap
随机推荐
Advanced Computer Network Review(3)——BBR
IJCAI2022论文合集(持续更新中)
Intel distiller Toolkit - Quantitative implementation 3
Selenium+pytest automated test framework practice
LeetCode:26. Remove duplicates from an ordered array
什么是MySQL?MySql的学习之路是怎样的
Pytest之收集用例规则与运行指定用例
【图的三大存储方式】只会用邻接矩阵就out了
BN折叠及其量化
Pytorch view tensor memory size
LeetCode:214. Shortest palindrome string
In depth analysis and encapsulation call of requests
Alibaba cloud server mining virus solution (practiced)
To effectively improve the quality of software products, find a third-party software evaluation organization
What are the common processes of software stress testing? Professional software test reports issued by companies to share
Li Kou daily question 1 (2)
Export IEEE document format using latex
一篇文章带你了解-selenium工作原理详解
Intel Distiller工具包-量化实现2
Philosophical enlightenment from single point to distributed