Exemplos de código da biblioteca de cliente

Exemplos de código para o modo de cluster ativado

O Memorystore para Valkey é compatível com todos os exemplos de código de cliente do Memorystore para Redis Cluster:

O Memorystore para Valkey também é compatível com os clientes do Valkey do OSS, como:

Exemplos de código para o modo de cluster desativado

O Memorystore para Valkey com o modo de cluster desativado é compatível com todas as bibliotecas de cliente do Redis e do Valkey OSS mencionadas na seção Exemplos de código para instâncias com o modo de cluster ativado.

Há duas diferenças principais que você precisa implementar ao usar uma instância com o modo cluster desativado.

  • Use o objeto de cliente Redis ou Valkey em vez do objeto de cliente RedisCluster ou ValkeyCluster fornecido pela biblioteca.
  • Crie um cliente de gravação usando o endereço IP do endpoint principal e um cliente de leitura usando o endereço IP do endpoint de leitura.

redis-py

import redis
primaryEndpoint = PRIMARY_ENDPOINT_IP
readerEndpoint = READER_ENDPOINT_IP

primary_client = redis.Redis(host=primaryEndpoint, port=6379, db=0, decode_responses=True)
reader_client = redis.Redis(host=readerEndpoint, port=6379, db=0, decode_responses=True)

primary_client.set("key","value")
print(reader_client.get("key"))

go-redis

package main

import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)

func main() {
primary_endpoint := PRIMARY_ENDPOINT_IP
reader_endpoint := READER_ENDPOINT_IP

primary_client := redis.NewClient(&redis.Options{
  Addr:     primary_endpoint,
  Password: "", // no password set
  DB:       0,  // use default DB
})

reader_client := redis.NewClient(&redis.Options{
  Addr:     reader_endpoint,
  Password: "", // no password set
  DB:       0,  // use default DB
})

ctx := context.Background()

err := primary_client.Set(ctx, "foo", "bar", 0).Err()
if err != nil {
  panic(err)
}

val, err := reader_client.Get(ctx, "foo").Result()
if err != nil {
  panic(err)
}
fmt.Println("foo", val)
}

Jedis


package org.example;

import java.io.*;
import java.time.LocalDateTime;
import java.lang.Thread;
import java.util.HashMap;
import java.util.Map;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class Main
{
public static void main( String[] args )
{
  primaryEndpoint = PRIMARY_ENDPOINT_IP

  JedisPool pool = new JedisPool(primaryEndpoint, 6379);

  try (Jedis jedis = pool.getResource()) {
    jedis.set("foo", "bar");
    System.out.println(jedis.get("foo")); // prints bar

    Map hash = new HashMap<>();;
    hash.put("name", "John");
    hash.put("surname", "Smith");
    hash.put("company", "Redis");
    hash.put("age", "29");
    jedis.hset("user-session:123", hash);
    System.out.println(jedis.hgetAll("user-session:123"));
    // Prints: {name=John, surname=Smith, company=Redis, age=29}
  } catch (Exception e) {
    System.out.println("Error setting or getting  key: " + e.getMessage());
  }
}
}

nodejs

import { createClient } from 'redis';
import * as fs from 'fs';

const primaryEndpoint = PRIMARY_ENDPOINT_IP

const primary_endpoint_url ='redis://primaryEndpoint:6379'

const client = createClient({
url: primary_endpoint_url
});

await client.connect();
await client.set(key, value);
const retval = await client.get(key);
console.log(retval)

Exemplo de código para autenticação do IAM e criptografia em trânsito

Esta seção mostra um exemplo de como autenticar e se conectar com a autenticação do IAM e a criptografia em trânsito com várias bibliotecas de cliente.

redis-py

from google.cloud import iam_credentials_v1
from redis.backoff import ConstantBackoff
from redis.retry import Retry
from redis.exceptions import (
ConnectionError,
AuthenticationWrongNumberOfArgsError,
AuthenticationError
)
from redis.utils import (str_if_bytes)

import redis

service_account="projects/-/serviceAccounts/<TO-DO-1: your service account that used to authenticate to Valkey>""

host=<TO-DO-2: your Redis Cluster discovery endpoint ip>
ssl_ca_certs=<TO-DO-3, your trusted server ca file name>

def generate_access_token():
  # Create a client
  client = iam_credentials_v1.IAMCredentialsClient()

  # Initialize request argument(s)
  request = iam_credentials_v1.GenerateAccessTokenRequest(
      name=service_account,
      scope=['https://www.googleapis.com/auth/cloud-platform'],
  )

  # Make the request
  response = client.generate_access_token(request=request)
  print(str(response.access_token))

  # Handle the response
  return str(response.access_token)

class ValkeyTokenProvider(redis.CredentialProvider):

    # Generated IAM tokens are valid for 15 minutes
    def get_credentials(self):
        token= generate_access_token()
        return "default",token

creds_provider = ValkeyTokenProvider()
client = redis.Redis(host=host, port=6379, credential_provider=creds_provider, ssl=True, ssl_ca_certs=caFilePath)
client.set('foo',"bar")
print(client.get('foo'))

Go

package main

import (
  "context"
  "crypto/tls"
  "crypto/x509"
  "flag"
  "fmt"
  "io/ioutil"
  "log"
  "sync"
  "time"

  credentials "google.golang.org/genproto/googleapis/iam/credentials/v1"

  "github.com/golang/protobuf/ptypes"
  "github.com/redis/go-redis/v9"
  "google.golang.org/api/option"
  gtransport "google.golang.org/api/transport/grpc"
)

var (
  svcAccount               = flag.String("a", "projects/-/serviceAccounts/example-service-account@example-project.iam.gserviceaccount.com", "service account email")
  lifetime                 = flag.Duration("d", time.Hour, "lifetime of token")
  refreshDuration          = flag.Duration("r", 5*time.Minute, "token refresh duration")
  checkTokenExpiryInterval = flag.Duration("e", 10*time.Second, "check token expiry interval")
  lastRefreshInstant       = time.Time{}
  errLastSeen              = error(nil)
  token                    = ""
  mu                       = sync.RWMutex{}
  err                      = error(nil)
)

func retrieveToken() (string, error) {
  ctx := context.Background()
  conn, err := gtransport.Dial(ctx,
    option.WithEndpoint("iamcredentials.googleapis.com:443"),
    option.WithScopes("https://www.googleapis.com/auth/cloud-platform"))

  if err != nil {
    log.Printf("Failed to dial API, error: %v", err)
    return token, err
  }
  client := credentials.NewIAMCredentialsClient(conn)
  req := credentials.GenerateAccessTokenRequest{
    Name:     *svcAccount,
    Scope:    []string{"https://www.googleapis.com/auth/cloud-platform"},
    Lifetime: ptypes.DurationProto(*lifetime),
  }
  rsp, err := client.GenerateAccessToken(ctx, &req)
  if err != nil {
    log.Printf("Failed to call GenerateAccessToken with request: %v, error: %v", req, err)
    return token, err
  }
  return rsp.AccessToken, nil
}

func refreshTokenLoop() {
  if *refreshDuration > *lifetime {
    log.Fatal("Refresh should not happen after token is already expired.")
  }
  for {
    mu.RLock()
    lastRefreshTime := lastRefreshInstant
    mu.RUnlock()
    if time.Now().After(lastRefreshTime.Add(*refreshDuration)) {
      var err error
      retrievedToken, err := retrieveToken()
      mu.Lock()
      token = retrievedToken
      if err != nil {
        errLastSeen = err
      } else {
        lastRefreshInstant = time.Now()
      }
      mu.Unlock()
    }
    time.Sleep(*checkTokenExpiryInterval)
  }
}

func retrieveTokenFunc() (string, string) {
  mu.RLock()
  defer mu.RUnlock()
  if time.Now().After(lastRefreshInstant.Add(*refreshDuration)) {
    log.Printf("Token is expired. last refresh instant: %v, refresh duration: %v, error that was last seen: %v", lastRefreshInstant, *refreshDuration, errLastSeen)
    return "", ""
  }
  username := "default"
  password := token
  return username, password
}

func main() {
  caFilePath := CA_FILE_PATH
  clusterDicEpAddr := PRIMARY_ENDPOINT_IP_ADDRESS_AND_PORT
  caCert, err := ioutil.ReadFile(caFilePath)
  if err != nil {
    log.Fatal(err)
  }
  caCertPool := x509.NewCertPool()
  caCertPool.AppendCertsFromPEM(caCert)
  token, err = retrieveToken()
  if err != nil {
    log.Fatal("Cannot retrieve IAM token to authenticate to the cluster, error: %v", err)
  }
  token, err = retrieveToken()
  fmt.Printf("token : %v", token)
  if err != nil {
    log.Fatal("Cannot retrieve IAM token to authenticate to the cluster, error: %v", err)
  }
  lastRefreshInstant = time.Now()
  go refreshTokenLoop()

  client := redis.NewClient(&redis.Options{
    Addr:                clusterDicEpAddr,
    CredentialsProvider: retrieveTokenFunc,
    TLSConfig: &tls.Config{
      RootCAs: caCertPool,
    },
  })

  ctx := context.Background()
  err = client.Set(ctx, "foo", "bar", 0).Err()
  if err != nil {
    log.Fatal(err)
  }
  val, err := client.Get(ctx, "foo").Result()
  if err != nil {
    log.Fatal(err)
  }
  fmt.Printf("\nGot the value for key: key, which is %s \n", val)
}