Halaman ini memberikan panduan tentang cara menggunakan Memorystore for Redis secara optimal. Halaman ini juga menunjukkan potensi masalah yang harus dihindari.
Untuk daftar skenario pemecahan masalah, lihat Pemecahan masalah.
Mengekspor RDB
Saat mengekspor cadangan RDB, gunakan panduan berikut:
- Mengekspor selama periode kecepatan penulisan rendah.
- Jika mengekspor selama periode kecepatan penulisan tinggi, turunkan sementara konfigurasi
maxmemorymenjadi 50% kapasitas instance untuk memberikan overhead yang cukup agar operasi berhasil.
Operasi yang memerlukan banyak resource
Untuk instance Redis Tingkat Standar, operasi berikut menggunakan memori tambahan selama durasi operasi:
Upgrade versi, penskalaan, dan failover manual menggunakan memori tambahan (untuk instance Tingkat Standar) karena replikasi. Operasi ini mengikuti proses replikasi yang dijelaskan dalam Perilaku upgrade instance Tingkat Standar.
Operasi impor dan ekspor memerlukan memori tambahan karena proses Redis yang di-fork dan pengelolaan data copy-on-write yang terkait dengan operasi ini.
Untuk memitigasi kekurangan operasi yang menggunakan banyak resource, Anda harus:
- Kurangi konfigurasi maxmemory menjadi 80% dari kapasitas instance selama durasi operasi. Tindakan ini memberikan overhead yang cukup untuk operasi yang berhasil.
- Pantau metrik rasio penggunaan memori sistem, dan pastikan metrik ini di bawah 80% sebelum menjalankan salah satu operasi ini.
- Jalankan operasi ini selama periode traffic instance rendah (seperti semalaman, atau selama akhir pekan, dll.).
- Terapkan logika coba lagi dengan backoff eksponensial sebelum menjalankan operasi ini.
Operasi dan skenario yang memerlukan percobaan ulang koneksi
Operasi dan skenario berikut akan menghentikan koneksi jaringan antara jaringan Anda dan instance Redis:
- Upgrade versi
- Menskalakan ke atas/ke bawah
- Mengimpor
- Failover manual
- Pemeliharaan sistem
- Rotasi Certificate Authority untuk instance Redis yang mengaktifkan enkripsi saat transit
- Pengalihan darurat
Operasi ini mengubah instance Anda, sehingga memerlukan jeda koneksi sementara. Anda harus menerapkan logika percobaan ulang dengan backoff eksponensial sebelum menjalankan operasi ini agar aplikasi Anda otomatis terhubung kembali dan terus berfungsi secara normal.
Pemeliharaan rutin
Instance Memorystore for Redis menjalani pemeliharaan secara berkala. Untuk mengetahui detail selengkapnya, lihat kebijakan pemeliharaan Memorystore for Redis.
Terapkan praktik terbaik berikut agar Anda siap untuk pemeliharaan rutin:
- Tetapkan masa pemeliharaan untuk waktu terjadinya update pemeliharaan.
- Jadwalkan masa pemeliharaan untuk saat traffic instance rendah dan overhead memori yang memadai. Untuk mengetahui informasi selengkapnya, lihat Dampak update pemeliharaan.
- Aktifkan notifikasi masa pemeliharaan untuk memberi tahu Anda tentang pemeliharaan mendatang.
- Memiliki logika coba lagi dengan backoff eksponensial di tempat.
- Untuk instance Tingkat Standar, Anda dapat menyimulasikan peristiwa pemeliharaan menggunakan failover manual untuk melihat pengaruh failover yang disebabkan oleh pemeliharaan terhadap aplikasi Anda.
- Untuk instance Tingkat Dasar, Anda dapat menyimulasikan dampak update pemeliharaan dengan menskalakan instance ke ukuran yang lebih besar untuk sementara. Setelah mengamati dampaknya, Anda dapat menskalakan kembali ke ukuran semula.
Pengelolaan memori
Pengelolaan memori dapat menjadi tantangan karena fragmentasi memori yang terkenal terjadi pada Redis open source. Sebaiknya turunkan konfigurasi maxmemory
untuk instance Anda guna memberikan ruang tambahan jika terjadi tekanan memori yang tinggi.
Cara terbaik untuk memantau tekanan memori pada instance Memorystore adalah dengan menggunakan metrik Rasio Penggunaan Memori Sistem. Untuk panduan mendetail tentang cara mengelola memori untuk Memorystore for Redis, lihat Praktik terbaik pengelolaan memori.
Mengelola koneksi yang tidak ada aktivitas
Seiring waktu, Anda mungkin melihat jumlah koneksi ke instance Memorystore Anda meningkat jika koneksi tidak dihentikan dengan benar. Hal ini dapat
berdampak negatif pada performa, terutama jika Anda menggunakan enkripsi saat transit, yang menerapkan batas koneksi maksimum
berdasarkan tingkat kapasitas Anda. Untuk mengurangi hal ini, sebaiknya gunakan
timeout parameter konfigurasi Redis
yang memungkinkan Anda menetapkan jumlah detik sebelum koneksi klien yang tidak aktif
dihentikan secara otomatis.
Nama resource Transparansi Akses
Data sensitif tidak boleh disimpan dalam nama resource Memorystore for Redis. Yang dimaksud dengan nama resource adalah nama instance Memorystore for Redis, dan metadata instance, seperti tag. Data yang disimpan dalam nama resource tidak dijamin dilindungi oleh Google Cloud Transparansi Akses, dan dapat bertentangan dengan persyaratan kepatuhan Transparansi Akses organisasi Anda.
Konektor Akses VPC Serverless diperlukan untuk beberapa lingkungan serverless
Beberapa lingkungan serverless memerlukan Konektor Akses VPC Serverless untuk terhubung ke Memorystore for Redis. Siapkan konektor Akses VPC Serverless untuk project Anda jika Anda ingin terhubung menggunakan salah satu lingkungan ini.
Jaringan
Sebaiknya gunakan akses layanan pribadi mode koneksi. Memorystore for Redis menggunakan dua mode koneksi: akses layanan pribadi dan peering langsung. Mode koneksi akses layanan pribadi menyederhanakan pengelolaan rentang IP dan memungkinkan Anda menggunakan VPC Bersama jika ingin.
Setelah Anda membuat instance, mode koneksi tidak dapat diubah.
Untuk mengetahui detail selengkapnya, lihat Networking.
Pemantauan dan pemberitahuan
Sebaiknya gunakan pemantauan dan pemberitahuan karena keduanya memberikan sinyal utama tentang penggunaan memori instance Redis Anda. Metrik ini juga memberi Anda insight tentang seberapa efisien instance Redis Anda merespons permintaan cache yang masuk.
Anda harus menyiapkan pemberitahuan default berikut:
- Menetapkan pemberitahuan Cloud Monitoring untuk penggunaan memori
- Menetapkan pemberitahuan Cloud Monitoring untuk Rasio Penggunaan Memori Sistem
Praktik terbaik penggunaan CPU
Penggunaan perintah redis yang mahal secara tidak tepat menyebabkan latensi tinggi, tidak responsif, atau masalah konektivitas. Instance Tingkat Standar menyediakan ketersediaan tinggi selama disaster recovery dan mengandalkan replikasi asinkron antara node utama dan replika. Jika salah satu node memiliki pemrosesan perintah yang mahal dan memblokir thread utama Redis, replikasi dapat terpengaruh. Jika masalah berlanjut dan terjadi pemadaman layanan di suatu lokasi, data terbaru yang ditulis di lokasi pemadaman layanan mungkin tidak tersedia di lokasi lain.
Sebaiknya gunakan Cloud Monitoring
untuk menyetel pemberitahuan untuk metrik Detik CPU Thread Utama
(redis.googleapis.com/stats/cpu_utilization_main_thread) guna memastikan
pemanfaatan CPU tidak melebihi 0,8 detik untuk node utama atau 0,5 detik
untuk setiap node replika, saat replika ditetapkan sebagai replika baca.
Jika instance Redis Anda melampaui nilai yang direkomendasikan, sebaiknya skalakan instance ke tingkatan kapasitas yang lebih tinggi atau ikuti petunjuk pemecahan masalah untuk menghindari operasi yang intensif CPU.
Jika instance Anda mengalami pemakaian CPU yang tinggi atau sumber daya instance habis (misalnya, karena memiliki terlalu banyak koneksi), instance mungkin berperilaku tidak semestinya dan metrik eksternal mungkin tidak ada.
Perintah yang memerlukan banyak resource
Sebaiknya hindari penggunaan perintah Redis yang membutuhkan banyak resource. Penggunaan perintah ini dapat menyebabkan masalah performa berikut:
- Latensi tinggi dan waktu tunggu klien
- Tekanan memori yang disebabkan oleh perintah yang meningkatkan penggunaan memori
- Kehilangan data selama replikasi dan sinkronisasi node karena thread utama Redis diblokir
- Health check yang tidak memadai, kemampuan pengamatan, dan replikasi
Tabel berikut mencantumkan contoh perintah Redis yang intensif resource dan memberikan alternatif yang hemat resource.
| Kategori | Perintah yang memerlukan banyak resource | Alternatif yang hemat resource |
|---|---|---|
| Jalankan untuk seluruh ruang kunci | KEYS |
SCAN |
| Menjalankan untuk keyset dengan panjang variabel | LRANGE |
Batasi ukuran rentang yang Anda gunakan untuk kueri. |
ZRANGE |
Batasi ukuran rentang yang Anda gunakan untuk kueri. | |
HGETALL |
HSCAN |
|
SMEMBERS |
SSCAN |
|
| Memblokir eksekusi skrip | EVAL |
Pastikan skrip Anda tidak berjalan tanpa batas waktu. |
EVALSHA |
Pastikan skrip Anda tidak berjalan tanpa batas waktu. | |
| Menghapus file dan link | DEL |
UNLINK |
| Memublikasikan dan berlangganan | PUBLISH |
SPUBLISH |
SUBSCRIBE |
SSUBSCRIBE |
Praktik terbaik klien Redis
Bagian ini memberikan panduan tentang penggunaan klien Redis secara optimal.
Mendeteksi dan menangani koneksi yang tidak responsif
Sebaiknya konfigurasikan aplikasi klien Anda untuk mendeteksi koneksi yang tidak responsif ke Memorystore for Redis. Saat koneksi yang tidak responsif terdeteksi, klien harus meresetnya. Untuk membangun aplikasi yang tangguh, kami merekomendasikan konfigurasi klien berikut:
- Konfigurasi parameter keep-alive TCP: tetapkan parameter
TCP keepalive time,TCP keepalive interval, danTCP keepalive probessehingga klien mendeteksi dan menghentikan koneksi yang tidak responsif secara proaktif, bahkan saat koneksi tidak ada aktivitas. Misalnya, jika Anda menyetel parameterTCP keepalive timeke 30 detik,TCP keepalive intervalke 10 detik, danTCP keepalive probeske 3, maka klien akan mereset koneksi tidak aktif yang tidak responsif dalam waktu satu menit. - Konfigurasi waktu tunggu pengguna TCP: tetapkan waktu tunggu ini di klien Anda untuk mereset koneksi yang memiliki permintaan yang belum selesai dan berhenti merespons. Misalnya, jika Anda menetapkan waktu tunggu ke 15 detik, klien akan mereset koneksi yang tidak responsif yang memiliki permintaan yang belum selesai setelah 15 detik.
Praktik terbaik khusus klien
Jika Anda menskalakan aplikasi, Anda mungkin mengalami error READONLY pada perintah tulis. Memorystore for Redis menggunakan deployment non-Sentinel dengan
endpoint statis, dan klien tidak menerima informasi peran dinamis di awal.
Jika Anda menggunakan satu koneksi klien untuk endpoint utama dan replika, klien Anda mungkin secara tidak sengaja mengirim perintah tulis ke replika hanya baca. Replika menampilkan error READONLY karena tidak dapat
memproses perintah tulis.
Untuk mencegah kesalahan perutean penulisan, jangan gunakan satu koneksi untuk operasi baca dan tulis. Sebagai gantinya, pisahkan operasi Anda dengan membuat instance klien terpisah berikut:
- Klien utama: hanya terhubung ke endpoint utama
- Klien replika: hanya terhubung ke endpoint replika
Tab berikut menunjukkan cara mengonfigurasi template terpisah di Go, Java, Node.js, dan Python.
Go
package main import ( "context" "fmt" "github.com/redis/go-redis/v9" ) func main() { ctx := context.Background() // Initialize the primary client connecting only to the primary endpoint primaryClient := redis.NewClient(&redis.Options{ Addr: "PRIMARY_HOST:6379", Password: "YOUR_PASSWORD", DB: 0, }) defer primaryClient.Close() // Initialize the replica client connecting only to the replica endpoint replicaClient := redis.NewClient(&redis.Options{ Addr: "REPLICA_HOST:6379", Password: "YOUR_PASSWORD", DB: 0, }) defer replicaClient.Close() // Use the primary client for all mutating commands err := primaryClient.Set(ctx, "example_key", "example_value", 0).Err() if err != nil { fmt.Printf("Failed to write to primary: %v\n", err) } // Use the replica client for all read-only commands val, err := replicaClient.Get(ctx, "example_key").Result() if err != nil { fmt.Printf("Failed to read from replica: %v\n", err) } else { fmt.Printf("Successfully read value: %s\n", val) } }
Java
@Bean public RedisConnectionFactory primaryConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("PRIMARY_HOST", 6379); config.setPassword(RedisPassword.of("YOUR_PASSWORD")); return new LettuceConnectionFactory(config); } @Bean public RedisConnectionFactory replicaConnectionFactory() { RedisStaticMasterReplicaConfiguration config = new RedisStaticMasterReplicaConfiguration("PRIMARY_HOST", 6379); config.addNode("REPLICA_HOST", 6379); config.setPassword(RedisPassword.of("YOUR_PASSWORD")); LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .readFrom(ReadFrom.REPLICA_PREFERRED) .build(); return new LettuceConnectionFactory(config, clientConfig); } @Bean public RedisTemplate<String, Object> primaryRedisTemplate( @Qualifier("primaryConnectionFactory") RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); return template; } @Bean public RedisTemplate<String, Object> replicaRedisTemplate( @Qualifier("replicaConnectionFactory") RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); return template; }
Node.js
import { createClient } from 'redis'; async function main() { // Initialize the primary client connecting only to the primary endpoint const primaryClient = createClient({ url: 'redis://PRIMARY_HOST:6379', password: 'YOUR_PASSWORD' }); // Initialize the replica client connecting only to the replica endpoint const replicaClient = createClient({ url: 'redis://REPLICA_HOST:6379', password: 'YOUR_PASSWORD' }); primaryClient.on('error', (err) => console.error('Primary Client Error', err)); replicaClient.on('error', (err) => console.error('Replica Client Error', err)); await primaryClient.connect(); await replicaClient.connect(); // Use the primary client for all mutating commands try { await primaryClient.set('example_key', 'example_value'); console.log('Successfully wrote to primary'); } catch (err) { console.error('Failed to write to primary:', err); } // Use the replica client for all read-only commands try { const val = await replicaClient.get('example_key'); console.log(`Successfully read value: ${val}`); } catch (err) { console.error('Failed to read from replica:', err); } await primaryClient.disconnect(); await replicaClient.disconnect(); } main();
Python
import redis def main(): # Initialize the primary client connecting only to the primary endpoint primary_client = redis.Redis( host='PRIMARY_HOST', port=6379, password='YOUR_PASSWORD', decode_responses=True ) # Initialize the replica client connecting only to the replica endpoint replica_client = redis.Redis( host='REPLICA_HOST', port=6379, password='YOUR_PASSWORD', decode_responses=True ) # Use the primary client for all mutating commands try: primary_client.set('example_key', 'example_value') print('Successfully wrote to primary') except redis.RedisError as e: print(f'Failed to write to primary: {e}') # Use the replica client for all read-only commands try: val = replica_client.get('example_key') print(f'Successfully read value: {val}') except redis.RedisError as e: print(f'Failed to read from replica: {e}') if __name__ == '__main__': main()