Motivasi
sebelum saya bahas tentang mempercepat proses load data di java menggunakan cache, saya akan bahas dahulu tentang apa saja manfaat yang akan didapat setelah mambaca artike ini. secara sederhana anda akan mengetahui :
- cara mempercepat proses load menggunakan cache.
- bagaimana cara kerja cache sehingga dapat mempercepat proses laod data.
- cara menerapkan cache pada sistem anda.
- framework yang dapat digunakan sebagai cache.
sekarang jika anda sekiranya tidak tertarik dengan manfaat artikel ini, anda bisa tidak melanjutkan membacanya, namun jika tertarik anda dapat meneruskan untuk membaca artikel ini.
Apa itu Cache?
sebelum tahu bagaimana cara mempercepat proses load data menggunakan cache, tentulah anda harus mengetahui dulu tentang apa itu cache.
Cache adalah kumpulan dari duplikasi data yang disimpan di suatu media. dimana data orisinil dari duplikasi tersebut membutuhkan biaya yang mahal untuk diakses, seperti waktu yang lama, ataupun proses yang memakan resource processor banyak.
sekarang yang jadi pertanyaan, data yang bagaimana yang bagus untuk dibuat cache-nya, dan dimanakan kita harus menyimpan cache tersebut?
sudah tidak bisa dipungkiri lagi jika setiap sistem pasti membutuhkan media penyimpanan, dan kebanyakan media penyimpanan tersebut adalah disk. misal seperti database, ataupun file biasa. ataupun biasanya sistem menyimpan data dalam memori. biasanya data yang disimpan dalam memori itu bukanlah data yang bersifat permanen, biasanya jika datanya bersifat permanen, maka diharuskan disimpan dalam disk.
anggap saja saat ini kita sedang menggunakan sistem yang berbasis database. artinya kita menggunakan database sebagai media penyimpan datanya. dan hal ini berarti data tersebut disimpan dalam disk. (kecuali menggunakan database berbasis memori seperti HSQLDB, anggap saja kita sekarang menggunakan database yang datanya disimpan dalam disk).
perlu diketahui juga kalo proses disk io yang dilakukan oleh database, baik itu ketika menyimpan data ataupun meload data bukanlah proses yang gampang. proses tersebut meruapkan proses yang mahal. kenapa bisa dibilang proses yang mahal? karena ada proses yang lebih murah dari proses tersebut
yup! proses yang lebih murah tersebut adalah memori io, yang artinya pengaksesan data dari disk itu lebih mahal dari pada pengaksesan data dari memori. mengakses data dari file akan membutuhkan waktu yang lama dimandingkan mengakses data dati memori. dan mengakses data dari disk membutuhkan resource processor lebih besar dari pada mengakses data dari memori. (makanya harga memori lebih mahal dari harga hardisk
)
gak percaya kalo memori lebih cepat dari disk? coba tanya ke orang teknik komputer
sekarang yang menjadi pertanyaannya adalah, bagaimana cara kita meyimpan cache dalam memori?
Arsitektur Menggunakan Cache
sebelum menggunakan cache, biasanya kita membuat sistem berbasis database seperti dibawah ini :

dimana biasanya aplikasi langsung terkoneksi ke database, sehingga proses insert, update, delete, dan select akan langsung dilakukan ke database. namun seperti yang dibahas sebelumnya, karena proses disk io dalam database itu prosesnya cukup mahal, maka adabaiknya kita menggunakan cache untuk menggulangi masalah tersebut. dimana kita akan menggunakan memori sebagai media penyimpanan cache tersebut. sehingga arsitekturnya akan seperti ini :

lho kenapa tetap menggunakan database?
tentu saja, karena sifat memori yang akan menghapus data ketika sumber daya mati, maka kita tidak bisa menggunakan memori sebagai media penyimpanan utama. jadi tetap walaupun kita menyimpan cache di memori, tetapi tetap data original harus ada dalam database, sehingga saat sistem mati, data tetap ada.
Implementasi Dalam Java
sekarang pertanyaannya, “bagaimana cara mengimplementasikan cache di java?“
seperti biasa, biasanya orang java selalu menggunakan konsep yang namanya Data Access Object saat membuat sistem berbasiskan database. anggap saja misal kita memiliki entitas Manusia, maka biasanya dibuatlah data access object untuk entitas tersebut :
package echo.khannedy.cacheload.mapper;
import echo.khannedy.cacheload.entity.Manusia;
public interface ManusiaMapper {
void saveManusia(Manusia manusia);
void updateManusia(Manusia manusia);
void deleteManusia(Long id);
Manusia getManusia(Long id);
}
jika anda belum mengerti tentang konsep dao, anda bisa membacanya disini :
dan biasanya kita membuat implementasi dao tersebut seperti ini :
package echo.khannedy.cacheload.implement;
import echo.khannedy.cacheload.entity.Manusia;
import echo.khannedy.cacheload.mapper.ManusiaMapper;
public class ManusiaMapperImpl implements ManusiaMapper {
@Override
public void deleteManusia(Long id) {
// mulai transaksi
database.beginTransaction();
// hapus data yang ada di database
database.deleteById(Manusia.class, id);
// commit transaksi
database.commit();
}
@Override
public Manusia getManusia(Long id) {
// mulai transaksi
database.beginTransaction();
// load data yang ada dalam database
Manusia manusia = database.getById(Manusia.class, id);
// commit transaksi
database.commit();
return manusia;
}
@Override
public void saveManusia(Manusia manusia) {
// mulai transaksi
database.beginTransaction();
// simpan data ke database
database.save(Manusia.class, manusia);
// commit transaksi
database.commit();
}
@Override
public void updateManusia(Manusia manusia) {
// mulai transaksi
database.beginTransaction();
// ubah data di database
database.update(Manusia.class, manusia);
// commit transaksi
database.commit();
}
}
nah sekarang bagaimana membuat cache? seperti pada penjelasannya bahwa cache itu adalah kumpulan duplikasi data, artinya cache ini berisikan data. sehingga dengan demikian kita bisa menggunakan collection untuk dijadikan cache tersebut. namun yang menjadi permasalaan adalah, bagai mana kita tahu jika ada data yang kita mau dalam cache?
untuk mengatasi masalah tersebut, kita harus menggunakan identitas untuk tiap object dalam cache. sehingga collection yang mensupport pengidentitasan menggunakan id adalah java.util.Map, dimana jika kita menggunakan java.util.List, maka kita hanya bisa menyimpan object tanpa memberi identitas.
dan karena pada kasus ini kita menggunakan entitas Manusia, jadi kita buat juta cache untuk entitas Manusia dengan nama ManusiaCache :
package echo.khannedy.cacheload.cache;
import java.util.HashMap;
import java.util.Map;
import echo.khannedy.cacheload.entity.Manusia;
public class ManusiaCache {
// buat collection dari map
private Map<Long, Manusia> map = new HashMap<Long, Manusia>();
/**
* metode ini bisa digunakan untuk menambah data ke cache ataupun mengubah
* data di cache
*
* @param manusia
*/
public void put(Manusia manusia) {
// simpan data ke map
map.put(manusia.getId(), manusia);
}
/**
* metode ini digunakan untuk menghapus data di cache
*
* @param id
*/
public void delete(Long id) {
map.remove(id);
}
/**
* metode ini digunakan untuk mendapatkan data di cache
*
* @param id
* @return manusia atau null jika tidak terdapat data manusia dengan id
* tersebut
*/
public Manusia get(Long id) {
return map.get(id);
}
}
dengan demikian kita ubah juga data access object Manusia menjadi seperti dibawah ini :
package echo.khannedy.cacheload.implement;
import echo.khannedy.cacheload.cache.ManusiaCache;
import echo.khannedy.cacheload.entity.Manusia;
import echo.khannedy.cacheload.mapper.ManusiaMapper;
public class ManusiaMapperImpl implements ManusiaMapper {
private ManusiaCache cache = new ManusiaCache();
@Override
public void deleteManusia(Long id) {
// mulai transaksi
database.beginTransaction();
// hapus data yang ada di database
database.deleteById(Manusia.class, id);
// hapus data di cache
cache.delete(id);
// commit transaksi
database.commit();
}
@Override
public Manusia getManusia(Long id) {
// load data di cache
Manusia manusia = cache.get(id);
// cek apakah data tidak ada dalam cache
if(manusia == null){
// jika data tidak ada dalam cache, maka load dari database
// mulai transaksi
database.beginTransaction();
// load data di database
manusia = database.getById(Manusia.class, id);
// simpan data ke cache
cache.put(manusia);
// commit transaksi
database.commit();
}
return manusia;
}
@Override
public void saveManusia(Manusia manusia) {
// mulai transaksi
database.beginTransaction();
// simpan data ke database
database.save(Manusia.class, manusia);
// simpan data ke cache
cache.put(manusia);
// commit transaksi
database.commit();
}
@Override
public void updateManusia(Manusia manusia) {
// mulai transaksi
database.beginTransaction();
// ubah data di database
database.update(Manusia.class, manusia);
// ubah data di cache
database.put(manusia);
// commit transaksi
database.commit();
}
}
dengan demikian saat terjadi proses load data maka proses ini yang akan dilakukan :
- load data dari cache
- cek apakah data di cache ada
- jika data ada maka proses selesai
- jika data tidak ada dalam cache maka load data yang ada didatabase
- setelah data yang ada didatabase diload, simpan data tersebut di cache
- selesai
dengan demikian saat sistem melakukan load data yang ada dicache dan ditemukan, maka sistem sama sekali tidak menyentuh database untuk meload data. dan hal ini tentu akan menjadikan proses load data lebih cepat.
namun jika data tidak ada dalam cache, maka data akan diload dari database, dan setelah itu data tersebut akan disimpan dalam cache. dengan ini proses selanjutnya maka load akan dilakukan ke cache tanpa harus ke database lagi
pada artikel ini, kita telah membuat cache secara manual, artinya kita membuat cache sendiri. namun jika anda ingin menggunakan cache yang lebih powerfull anda dapat menggunakan framework-framework cache yang telah ada seperti :
terima kasih telah membaca artikel ini, semoga ilmu anda dan saya semakin bertambah
Posted in Java Programming, NetBeans Tagged: cache, cache io, cache memori, cara mempercepat proses database di java, dao, data access object, Database, database crud, database java, delete, disk, disk io, insert, Java, memory io, mempercepat java, mempercepat proses database di java, mempercepat proses load di java menggunakan cache, optimisasi java, pemrograman java, proses java database, tutorial java database, tutoruial java, update
