Belajar Spring - Integrasi Redis dengan Spring Boot dan JedisPool
Redis, sebagai salah satu solusi in-memory database yang populer, telah menjadi andalan dalam membangun aplikasi dengan kebutuhan akses data cepat dan efisien. Dalam artikel ini, kita akan menjelajahi cara mengintegrasikan Redis dengan Spring Boot, mulai dari konfigurasi dasar, optimasi pooling menggunakan Jedis, hingga implementasi fitur Redis Streams untuk keperluan messaging dan event-driven architecture. Panduan ini ditujukan untuk membantu Anda memahami konsep Redis dengan pendekatan yang praktis dan langsung diimplementasikan.
Dependency
Tambahkan Dependency Redis di Spring: Di file pom.xml, tambahkan dependency Redis Spring Data.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>5.1.3</version> </dependency>
Properties
Konfigurasi Redis di Aplikasi: Tambahkan konfigurasi Redis di file application.properties atau application.yml
server.port=8080 spring.data.redis.host=localhost spring.data.redis.port=6379
Configuration
@Component @ConfigurationProperties(prefix = "spring.data.redis") @Getter @Setter public class RedisProperties { private String host; private int port; }
@Configuration @EnableRedisRepositories public class RedisConfig { @Autowired private RedisProperties redisProperties; @Bean public JedisPoolConfig jedisPoolConfig() { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(10); poolConfig.setMaxIdle(5); poolConfig.setMinIdle(1); return poolConfig; } @Bean public JedisConnectionFactory jedisConnectionFactory() { RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(); configuration.setHostName(redisProperties.getHost()); configuration.setPort(redisProperties.getPort()); JedisClientConfiguration clientConfig = JedisClientConfiguration.builder() .usePooling() .poolConfig(jedisPoolConfig()) .build(); return new JedisConnectionFactory(configuration, clientConfig); } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(jedisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setEnableTransactionSupport(true); template.afterPropertiesSet(); return template; } }
Penjelasan
Anotasi dan Konfigurasi
- @Configuration: Menandakan bahwa class ini adalah konfigurasi Spring yang akan menyediakan bean untuk aplikasi.
- @EnableRedisRepositories: Mengaktifkan repositori Redis di Spring, memungkinkan pengelolaan data Redis menggunakan repositori mirip JPA.
JedisPoolConfig
JedisPoolConfig adalah konfigurasi untuk Jedis Connection Pool, yang digunakan untuk memanage koneksi Redis. Connection pool berguna untuk meningkatkan kinerja dengan meminimalkan waktu yang diperlukan untuk membuka dan menutup koneksi Redis setiap kali digunakan.
- setMaxTotal(10): Maksimum total koneksi yang diperbolehkan dalam pool.
- setMaxIdle(5): Maksimum jumlah koneksi idle yang dapat dipertahankan dalam pool.
- setMinIdle(1): Minimum jumlah koneksi idle yang dipertahankan.
Kelebihan
- Dengan pooling, efisiensi koneksi meningkat karena mengurangi overhead pembukaan dan penutupan koneksi Redis secara terus-menerus.
Kekurangan
- Pada aplikasi berskala besar dengan traffic tinggi, konfigurasi pooling ini mungkin perlu dioptimalkan lebih lanjut untuk menghindari connection exhaustion (kehabisan koneksi).
JedisConnectionFactory
JedisConnectionFactory bertanggung jawab untuk menyediakan koneksi ke Redis menggunakan Jedis sebagai klien Redis.
- RedisStandaloneConfiguration: Konfigurasi Redis dalam mode standalone, di mana Redis berjalan sebagai instance tunggal (bukan cluster atau sentinel).
- JedisClientConfiguration digunakan untuk mengatur konfigurasi tambahan, seperti menggunakan connection pooling. poolConfig(jedisPoolConfig()) menghubungkan konfigurasi pooling yang sudah dibuat di bean sebelumnya.
RedisTemplate
RedisTemplate adalah kelas template yang menyediakan API tingkat tinggi untuk bekerja dengan Redis. Ini adalah template yang memudahkan operasi seperti menyimpan, mengambil, dan memodifikasi data di Redis.
- setConnectionFactory(jedisConnectionFactory()): Mengatur koneksi Redis dari JedisConnectionFactory.
- KeySerializer dan HashKeySerializer menggunakan StringRedisSerializer, yang mengubah kunci menjadi string (umumnya UTF-8) agar lebih mudah terbaca.
- ValueSerializer dan HashValueSerializer menggunakan GenericJackson2JsonRedisSerializer, yang mengonversi nilai menjadi JSON dengan bantuan Jackson. Ini memungkinkan data kompleks diubah menjadi JSON dan disimpan dalam Redis, serta diambil kembali dalam bentuk asli.
- setEnableTransactionSupport(true): Mengaktifkan dukungan transaksi pada RedisTemplate. Ini memungkinkan Anda melakukan operasi Redis di dalam transaksi atomic
Kelebihan
- Efisiensi Koneksi: Penggunaan connection pool (JedisPoolConfig) memungkinkan aplikasi menangani banyak koneksi Redis dengan efisien.
- Kemudahan Serialization: Menggunakan JSON untuk serialisasi memudahkan penyimpanan dan pengambilan data kompleks di Redis.
- Dukungan Transaksi: Mengaktifkan dukungan transaksi memberi kemampuan untuk melakukan operasi Redis dalam satu unit transaksi.
- Scalability: Karena Redis digunakan dalam mode standalone, konfigurasi ini cocok untuk aplikasi yang sedang berkembang dan memungkinkan scaling dengan mode cluster jika dibutuhkan di masa depan.
Kekurangan
- Stand-alone Redis: Redis dikonfigurasi dalam mode standalone. Untuk lingkungan produksi dengan skala besar, mungkin Anda ingin mempertimbangkan mode Redis Cluster atau Redis Sentinel untuk ketersediaan yang lebih tinggi dan skalabilitas.
- Complexity with JSON Serialization: Menggunakan JSON sebagai serializer mungkin menambah sedikit overhead dalam hal konversi data, meskipun biasanya tidak signifikan kecuali untuk dataset besar.
DTO
Pertama, kita buat class Produk yang akan kita simpan di Redis. Gunakan anotasi @Data dari Lombok agar kita tidak perlu menuliskan getter dan setter secara manual.
@Data @NoArgsConstructor @AllArgsConstructor @Builder @RedisHash("Produk") public class Produk implements Serializable { private String id; private String kode; private String nama; }
Repository
Buat repository untuk mengelola produk menggunakan RedisTemplate.
public interface ProdukRepository { void save(Produk produk); Produk findById(String id); List<Produk> findAll(); void delete(String id); }
@Repository public class ProdukRepositoryImpl implements ProdukRepository { public static final String HASH_KEY = "Produk"; @Autowired private RedisTemplate redisTemplate; @Override public void save(Produk produk) { redisTemplate.opsForHash().put(HASH_KEY, produk.getId(), produk); } @Override public Produk findById(String id) { return (Produk) redisTemplate.opsForHash().get(HASH_KEY, id); } @Override public List<Produk> findAll() { return (List<Produk>) redisTemplate.opsForHash().values(HASH_KEY); } @Override public void delete(String id) { redisTemplate.opsForHash().delete(HASH_KEY, id); } }
Rest API
Buat controller untuk memfasilitasi permintaan HTTP seperti POST, GET, PUT, dan DELETE.
@RestController @RequestMapping("/api/produk") public class ProdukAPI { @Autowired private ProdukRepository produkRepository; @GetMapping("/list") public ResponseEntity<List<Produk>> findAll() { List<Produk> produkList = produkRepository.findAll(); if(produkList.isEmpty()) { return ResponseEntity.noContent().build(); } return ResponseEntity.ok(produkList); } @GetMapping("/search") public ResponseEntity<Produk> findById(@RequestParam(value = "id") String id) { Produk produk = produkRepository.findById(id); if(produk == null) { return ResponseEntity.noContent().build(); } return ResponseEntity.ok(produk); } @PostMapping("/create") public ResponseEntity<Produk> save(@RequestBody Produk produk) { produk.setId(UUID.randomUUID().toString()); produkRepository.save(produk); return ResponseEntity.ok(produk); } @DeleteMapping("/delete") public ResponseEntity<Produk> delete(@RequestParam(value = "id") String id) { Produk produk = produkRepository.findById(id); if(produk == null) { return ResponseEntity.noContent().build(); } produkRepository.delete(id); return ResponseEntity.ok(produk); } }
Dengan memanfaatkan integrasi Redis di Spring Boot, Anda dapat meningkatkan kinerja aplikasi dengan memanfaatkan caching yang efisien, transaksi Redis, dan arsitektur pesan berbasis event melalui Redis Streams. Konfigurasi yang tepat, seperti menggunakan pooling pada JedisConnectionFactory, dapat memberikan optimasi lebih lanjut untuk aplikasi yang menangani ratusan atau bahkan ribuan permintaan per detik. Semoga tutorial ini membantu Anda dalam memahami dan mengimplementasikan Redis secara efektif dalam aplikasi Spring Boot Anda.
0 Response to "Belajar Spring - Integrasi Redis dengan Spring Boot dan JedisPool"
Posting Komentar