JedisPool adalah connection pool untuk client Jedis. Konfigurasi parameter pool yang tepat dapat meningkatkan kinerja Redis dan pemanfaatan sumber daya. Topik ini mencakup penggunaan JedisPool, deskripsi parameter, serta rekomendasi optimasi.
Penggunaan
Contoh ini menggunakan Jedis 2.9.0. Dependensi Maven:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
Jedis menggunakan Apache Commons-pool2 untuk manajemen pool. Kelas parameter utama adalah GenericObjectPoolConfig:
GenericObjectPoolConfig jedisPoolConfig = new GenericObjectPoolConfig();
jedisPoolConfig.setMaxTotal(...);
jedisPoolConfig.setMaxIdle(...);
jedisPoolConfig.setMinIdle(...);
jedisPoolConfig.setMaxWaitMillis(...);
...
Inisialisasi JedisPool:
// redisHost adalah alamat IP instans. redisPort adalah port instans. redisPassword adalah password instans. timeout berlaku sebagai connection timeout sekaligus read/write timeout.
JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisHost, redisPort, timeout, redisPassword);
// Jalankan perintah sebagai berikut.
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
// Perintah spesifik.
jedis.executeCommand()
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
// Dalam mode JedisPool, objek Jedis dikembalikan ke kolam sumber daya.
if (jedis != null)
jedis.close();
}
Parameter
JedisPool mengelola koneksi Jedis dalam pool terbatas yang aman untuk thread. Konfigurasi GenericObjectPoolConfig yang tepat meningkatkan kinerja Redis dan mengurangi overhead sumber daya. Tabel berikut menjelaskan parameter utama beserta pengaturan yang direkomendasikan.
Tabel 1. Parameter terkait pengaturan dan penggunaan sumber daya
|
Parameter |
Deskripsi |
Nilai default |
Rekomendasi |
|
maxTotal |
Jumlah maksimum koneksi dalam pool. |
8 |
|
|
maxIdle |
Jumlah maksimum koneksi idle dalam pool. |
8 |
|
|
minIdle |
Jumlah minimum koneksi idle yang dipertahankan dalam pool. |
0 |
|
|
blockWhenExhausted |
Apakah pemanggil diblokir saat pool habis. maxWaitMillis hanya berlaku jika nilai ini true. |
true |
Gunakan nilai default. |
|
maxWaitMillis |
Waktu tunggu maksimum (ms) saat pool habis. |
-1 (tidak pernah timeout) |
Jangan gunakan nilai default. |
|
testOnBorrow |
Apakah koneksi divalidasi (ping) saat dipinjam dari pool. Koneksi yang tidak valid akan dihapus. |
false |
Untuk traffic tinggi, atur ke false untuk mengurangi overhead ping. |
|
testOnReturn |
Apakah koneksi divalidasi (ping) saat dikembalikan ke pool. Koneksi yang tidak valid akan dihapus. |
false |
Untuk traffic tinggi, atur ke false untuk mengurangi overhead ping. |
|
jmxEnabled |
Apakah Pemantauan JMX diaktifkan. |
true |
Aktifkan fitur ini. Pastikan juga diaktifkan untuk aplikasi Anda. |
Empat parameter berikut mengontrol deteksi koneksi idle.
Tabel 2. Parameter terkait deteksi sumber daya idle
|
Nama |
Deskripsi |
Nilai default |
Rekomendasi |
|
testWhileIdle |
Apakah koneksi idle divalidasi (ping) selama proses eviction. Koneksi yang tidak valid akan dihapus. |
false |
true |
|
timeBetweenEvictionRunsMillis |
Interval (ms) antara proses eviction koneksi idle. |
-1 (tidak ada deteksi) |
Atur nilai ini untuk mengaktifkan deteksi. Anda dapat memilih periode atau menggunakan default JedisPoolConfig di bawah. |
|
minEvictableIdleTimeMillis |
Waktu idle minimum (ms) sebelum koneksi memenuhi syarat untuk dihapus. |
1.800.000 (30 menit) |
Nilai default (30 menit) biasanya sudah cukup. Anda juga dapat menggunakan default JedisPoolConfig di bawah. |
|
numTestsPerEvictionRun |
Jumlah koneksi yang diuji per proses eviction. |
3 |
Sesuaikan berdasarkan ukuran pool Anda. Atur ke -1 untuk memeriksa semua koneksi per proses eviction. |
JedisPoolConfig memperluas GenericObjectPoolConfig dengan nilai default deteksi idle berikut:
public class JedisPoolConfig extends GenericObjectPoolConfig {
public JedisPoolConfig() {
setTestWhileIdle(true);
setMinEvictableIdleTimeMillis(60000);
setTimeBetweenEvictionRunsMillis(30000);
setNumTestsPerEvictionRun(-1);
}
}
Semua nilai default didefinisikan dalam kelas org.apache.commons.pool2.impl.BaseObjectPoolConfig.
Pengaturan yang direkomendasikan untuk parameter utama
maxTotal (jumlah koneksi maksimum)
Pertimbangkan faktor-faktor berikut saat mengatur maxTotal:
-
Konkurensi Redis yang diharapkan.
-
Waktu eksekusi perintah di sisi client.
-
Sumber daya Redis yang tersedia. Jumlah node (instans ECS aplikasi) dikalikan dengan
maxTotaltidak boleh melebihi jumlah koneksi maksimum yang diizinkan untuk instans tersebut. Periksa batas ini di halaman detail instans. -
Overhead sumber daya akibat koneksi idle dan scaling pool yang sering.
Contoh: jika waktu perintah rata-rata (pinjam + eksekusi + jaringan) adalah 1 ms, satu koneksi menangani ~1.000 QPS. Untuk target 50.000 QPS pada satu instans (total QPS / jumlah shard), nilai teoretis maxTotal adalah 50.000 / 1.000 = 50.
Tambahkan buffer di atas nilai teoretis tersebut. Namun, ukuran maxTotal yang terlalu besar membuang sumber daya client dan server serta tidak membantu ketika perintah besar menyebabkan blocking.
maxIdle dan minIdle
maxIdle merepresentasikan jumlah koneksi puncak aktual yang dibutuhkan oleh workload Anda, sedangkan maxTotal menyediakan buffer. Hindari mengatur maxIdle terlalu rendah—hal ini memaksa pool untuk sering membuat koneksi new Jedis. minIdle mengontrol deteksi sumber daya idle.
Kinerja terbaik tercapai ketika maxTotal sama dengan maxIdle, karena menghindari overhead scaling pool. Atur keduanya sama jika workload Anda mengalami lonjakan lalu lintas. Jika konkurensi rendah atau maxIdle terlalu tinggi, koneksi idle akan terbuang sia-sia.
Perkirakan ukuran pool per node berdasarkan total QPS dan jumlah instans client.
Gunakan pemantauan untuk mendapatkan nilai yang wajar
Di lingkungan produksi, gunakan JMX atau alat pemantauan lain untuk menentukan nilai optimal berdasarkan pola penggunaan aktual.
FAQ
Sumber daya tidak mencukupi
Kasus-kasus berikut mencegah pengambilan sumber daya dari pool.
-
Timeout:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool … Caused by: java.util.NoSuchElementException: Timeout waiting for idle object at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449) -
Parameter blockWhenExhausted diatur ke false, sehingga pemanggil tidak menunggu sumber daya dilepaskan:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool … Caused by: java.util.NoSuchElementException: Pool exhausted at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)
Eksepsi ini tidak selalu disebabkan oleh ukuran pool yang tidak mencukupi. Eksepsi ini juga dapat terjadi akibat masalah jaringan, konfigurasi parameter pool yang salah, pemantauan JMX, tidak adanya pemanggilan jedis.close(), query lambat, atau masalah DNS. Lihat Pengaturan yang direkomendasikan untuk parameter utama.
Pemanasan JedisPool
JedisPool tidak membuat koneksi secara aktif saat inisialisasi. Permintaan pertama memicu pembuatan koneksi new Jedis, yang menambah latensi. Dengan timeout kecil, hal ini dapat menyebabkan timeout saat startup. Untuk menghindarinya, pra-ambil koneksi berdasarkan minIdle setelah pembuatan pool:
List<Jedis> minIdleJedisList = new ArrayList<Jedis>(jedisPoolConfig.getMinIdle());
for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) {
Jedis jedis = null;
try {
jedis = pool.getResource();
minIdleJedisList.add(jedis);
jedis.ping();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
}
}
for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) {
Jedis jedis = null;
try {
jedis = minIdleJedisList.get(i);
jedis.close();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
}
}
Untuk error lainnya, lihat Common errors.