בדף הזה מוצגות דוגמאות קוד למופעי Memorystore for Valkey שמוגדרים בהם גם מצב אשכול מופעל וגם מצב אשכול מושבת.
דוגמאות קוד למצב אשכולות מופעל
Memorystore for Valkey תואם לכל דוגמאות הקוד של הלקוח ב-Memorystore for Redis Cluster:
- Memorystore for Redis Cluster דוגמאות קוד של ספריות לקוח
- Memorystore for Redis Cluster דוגמאות לקוד חיבור של ספריות לקוח
מידע על Valkey GLIDE
Valkey General Language Independent Driver for the Enterprise (GLIDE) היא ספריית לקוח בקוד פתוח, והיא תומכת בכל הפקודות של Valkey.
אתם יכולים להשתמש ב-Valkey GLIDE כדי לקשר את האפליקציות שלכם למופעים של Memorystore for Valkey. Valkey GLIDE נועד לספק אמינות, ביצועים אופטימליים וזמינות גבוהה.
כדי להבטיח עקביות בפיתוח ובפעולות של אפליקציות, Valkey GLIDE מיושם באמצעות מסגרת של מנהל התקן ליבה, שנכתבה ב-Rust, עם תוספים ספציפיים לשפה. העיצוב הזה מבטיח עקביות בתכונות בשפות שונות ומפחית את המורכבות.
Valkey GLIDE תומך ב-Valkey בגרסאות 7.2, 8.0 ו-9.0. היא זמינה בשפות הבאות:
ספריות לקוח אחרות של Valkey OSS
בנוסף ל-Valkey GLIDE, Memorystore for Valkey תואם לספריות הלקוח הבאות של Valkey OSS:
מערכות ושירותים
אתם יכולים להשתמש ב-Spring Boot, ב-PostgreSQL וב-Memorystore for Valkey כדי ליצור את המערכות והשירותים הבאים:
- מערכת לניהול סשנים: ניהול סשנים הוא חלק חשוב באפליקציות אינטרנט מודרניות. הוא מבטיח שהאינטראקציות של המשתמשים יישארו עקביות ומאובטחות בכמה בקשות. באמצעות שכבת מטמון, האפליקציה יכולה לנהל את סשנים של המשתמשים בצורה יעילה, תוך הפחתת העומס על מסד הנתונים והבטחת יכולת ההתאמה לגודל.
- מערכת לידרבורד ניתנת להרחבה: לידרבורדים הם דרך שימושית להצגת נתוני דירוג באפליקציות. באמצעות שכבת מטמון, אפשר לספק דירוגים בזמן אמת בלידרבורד תוך צמצום העומס על מסד הנתונים.
- שירות מתקדם של שמירת נתונים במטמון: אפליקציות מודרניות צריכות לספק חוויית משתמש מהירה ורספונסיבית בהיקף גדול. בעזרת שירות ה-caching הזה, תוכלו לצמצם את זמן האחזור ואת העומס על מסד הנתונים.
דוגמאות קוד להשבתת מצב האשכול
ההגדרה 'מצב אשכולות מושבת' ב-Memorystore for Valkey תואמת לכל ספריות הלקוח של Redis ו-Valkey OSS שמפורטות בדוגמאות קוד להפעלה של מצב אשכולות.
כשמשתמשים במופע Cluster Mode Disabled ב-Memorystore for Valkey, צריך לבצע את הפעולות הבאות:
- במקום אובייקט הלקוח
RedisClusterאוValkeyClusterשהספרייה מספקת, צריך להשתמש באובייקט הלקוח של Redis או Valkey. - יוצרים לקוח כתיבה באמצעות כתובת ה-IP של נקודת הקצה הראשית.
יוצרים לקוח קריאה באמצעות כתובת ה-IP של נקודת הקצה של הקורא.
redis-py
מומלץ להשתמש ב-redis-py, בגרסה 5.1 ומעלה.
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
מומלץ להשתמש ב-go-redis, בגרסאות 9.11.0 ואילך.
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, בגרסה 4.4.0 ואילך.
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());
}
}
}
Node.js
מומלץ להשתמש ב-Node.js, גרסאות 24.4.1 ואילך.
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)
דוגמת קוד לאימות IAM ולהצפנה בתנועה
בקטע הזה מופיעה דוגמה לאימות ולחיבור למופע של Memorystore for Valkey באמצעות אימות IAM והצפנה במעבר עם ספריות לקוח שונות.
redis-py
מומלץ להשתמש ב-redis-py, גרסה 5.1 ואילך.
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, גרסאות 1.24.5 ואילך.
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)
}