Instans Tair (Redis OSS-compatible) dapat mengalami gangguan sementara akibat fluktuasi jaringan, gangguan layanan, atau beban server. Konfigurasikan mekanisme retry otomatis di library klien Anda untuk menangani gangguan tersebut secara graceful.
Penyebab gangguan temporary
| Cause | Effect |
|---|---|
| Master-replica switchover | Tair memantau kesehatan node dan memicu switchover ketika node master gagal. Klien mungkin mengalami koneksi transient dalam hitungan detik dan masuk ke status read-only dalam waktu 30 detik. Status read-only mencegah kehilangan data dan dual writes. Untuk informasi selengkapnya, lihat High availability. |
| Slow queries | Operasi dengan kompleksitas waktu O(N) memblokir permintaan lain, menyebabkan kegagalan temporary pada operasi klien yang konkuren. |
| Network issues | Fluktuasi jaringan dan pengiriman ulang data antara klien dan server menyebabkan kegagalan permintaan yang intermiten. |
Praktik terbaik retry
Retry hanya operasi idempotent
Timeout dapat terjadi pada tahap mana pun dalam eksekusi perintah:
Perintah belum sampai ke server.
Perintah telah sampai ke server, tetapi eksekusinya timeout.
Perintah telah dieksekusi di server, tetapi responsnya timeout.
Karena operasi yang diretry mungkin dieksekusi lebih dari sekali, lakukan retry hanya untuk operasi idempotent.
Idempotent — SET a b: Menjalankan perintah ini beberapa kali selalu menghasilkan hasil yang sama.
Non-idempotent — LPUSH mylist a: Menjalankan perintah ini beberapa kali akan menambahkan elemen a duplikat ke mylist.
Konfigurasikan jumlah retry dan interval yang sesuai
Tentukan jumlah retry dan interval berdasarkan workload Anda:
Terlalu sedikit retry atau interval terlalu lama: Aplikasi mungkin gagal menyelesaikan operasi selama gangguan transient singkat.
Terlalu banyak retry atau interval terlalu pendek: Aplikasi mengonsumsi sumber daya berlebihan dan berpotensi membebani server.
| Strategy | Description |
|---|---|
| Immediate retry | Retry tanpa penundaan. Hanya cocok untuk gangguan yang diperkirakan terselesaikan dalam milidetik. |
| Fixed-interval retry | Tunggu durasi tetap antar retry. Dapat menyebabkan lonjakan permintaan saat banyak klien melakukan retry secara bersamaan. |
| Exponential backoff | Gandakan waktu tunggu setelah setiap percobaan. Menyebar retry sepanjang waktu dan mengurangi beban server. |
| Randomized backoff | Tambahkan jitter acak ke interval backoff. Mencegah banyak klien melakukan retry pada saat yang sama setelah event kegagalan bersama. |
Hindari retry nesting
Retry nesting—di mana operasi retry memicu loop retry lain—dapat menyebabkan retry berulang atau tak terbatas. Implementasikan logika retry hanya pada satu lapisan dalam stack aplikasi Anda.
Catat kegagalan retry
Buat log retry pada level WARN. Catat hanya ketika retry terakhir gagal, bukan pada setiap percobaan individual, untuk menghindari kebisingan log.
Jedis
Gunakan Jedis 4.0.0 atau versi yang lebih baru. Contoh berikut menggunakan Jedis 5.0.0.
Tambahkan dependensi ke file pom.xml Anda:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.0.0</version>
</dependency>Instans Standard atau Cluster dalam mode proxy (JedisPool)
Untuk instans standard atau instans cluster dalam mode proxy, gunakan PooledConnectionProvider dengan UnifiedJedis.
Contoh ini melakukan retry perintah SET hingga 5 kali dalam waktu 10 detik, dengan waktu tunggu yang meningkat secara eksponensial. Jika semua retry gagal, sebuah exception akan dilemparkan.
PooledConnectionProvider provider = new PooledConnectionProvider(HostAndPort.from("127.0.0.1:6379"));
int maxAttempts = 5; // Jumlah maksimum retry
Duration maxTotalRetriesDuration = Duration.ofSeconds(10); // Durasi total maksimum untuk retry
UnifiedJedis jedis = new UnifiedJedis(provider, maxAttempts, maxTotalRetriesDuration);
try {
System.out.println("set key: " + jedis.set("key", "value"));
} catch (Exception e) {
// Operasi gagal setelah mencapai maxAttempts atau melebihi maxTotalRetriesDuration.
e.printStackTrace();
}| Parameter | Value in example | Description |
|---|---|---|
maxAttempts | 5 | Jumlah maksimum percobaan retry. |
maxTotalRetriesDuration | 10 seconds | Durasi total maksimum untuk seluruh percobaan retry. Retry dihentikan jika durasi ini terlampaui, meskipun maxAttempts belum tercapai. |
Instans Cluster dalam mode koneksi langsung (JedisCluster)
Untuk instans cluster dalam mode koneksi langsung, gunakan JedisCluster. Parameter maxAttempts menentukan jumlah percobaan retry. Nilai default-nya adalah 5. Jika operasi gagal setelah mencapai jumlah maksimum percobaan, sebuah exception akan dilemparkan.
HostAndPort hostAndPort = HostAndPort.from("127.0.0.1:30001");
int connectionTimeout = 5000;
int soTimeout = 2000;
int maxAttempts = 5;
ConnectionPoolConfig config = new ConnectionPoolConfig();
JedisCluster jedisCluster = new JedisCluster(hostAndPort, connectionTimeout, soTimeout, maxAttempts, config);
try {
System.out.println("set key: " + jedisCluster.set("key", "value"));
} catch (Exception e) {
// Operasi gagal setelah maxAttempts retry.
e.printStackTrace();
}| Parameter | Value in example | Default | Description |
|---|---|---|---|
connectionTimeout | 5000 | -- | Timeout koneksi dalam milidetik. |
soTimeout | 2000 | -- | Timeout socket dalam milidetik. |
maxAttempts | 5 | 5 | Jumlah maksimum percobaan retry saat terjadi kegagalan. |
Redisson
Redisson menyediakan dua parameter untuk mengontrol perilaku retry:
| Parameter | Default | Description |
|---|---|---|
retryAttempts | 3 | Jumlah percobaan retry. |
retryInterval | 1500 ms | Interval antar retry, dalam milidetik. |
Config config = new Config();
config.useSingleServer()
.setTimeout(1000)
.setRetryAttempts(3)
.setRetryInterval(1500) // ms
.setAddress("redis://127.0.0.1:6379");
RedissonClient connect = Redisson.create(config);StackExchange.Redis
StackExchange.Redis hanya mendukung retry koneksi, bukan retry pada level perintah. Gunakan parameter connectRetry untuk menentukan jumlah percobaan koneksi ulang.
var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");| Parameter | Value in example | Description |
|---|---|---|
connectRetry | 3 | Jumlah percobaan retry untuk koneksi awal. |
Untuk logika retry pada level perintah, gunakan library resilience seperti Polly untuk membungkus perintah individual dengan kebijakan retry.
Lettuce
Lettuce tidak menyediakan parameter untuk retry perintah individual setelah timeout. Sebagai gantinya, ia mendukung dua mode keandalan eksekusi:
| Mode | Behavior |
|---|---|
| At-most-once | Setiap perintah dieksekusi paling banyak sekali. Jika klien terputus dan tersambung kembali, perintah yang tertunda mungkin hilang. |
| At-least-once (default) | Setiap perintah dieksekusi paling sedikit sekali. Klien melakukan retry perintah untuk memastikan eksekusi berhasil. Jika terjadi master-replica switchover saat klien sedang melakukan retry, perintah retry dapat menumpuk. Setelah switchover selesai, pemanfaatan CPU instans mungkin melonjak. |
Pengaturan autoReconnect menentukan mode eksekusi:
clientOptions.isAutoReconnect() ? Reliability.AT_LEAST_ONCE : Reliability.AT_MOST_ONCE;Untuk informasi selengkapnya, lihat Client-Options dan Command execution reliability.