Tergoda Oleh Cache Image

Tergoda Oleh Cache

Saat sedang asik tenggelam dalam dunia biner, terlihat sekilas neng cache melirik menggoda dan memanggil diri ini untuk sekedar menyapa.

Sudah beberapa kali godaan ini saya tepis dan saya hanya membalas dengan senyuman.

Tapi malam ini berbeda.

Terlihat ada pesona magis tersendiri dalam tatapannya yang membuat diri ini datang menghampiri dan datang menyapanya.

Niat awal sih cuma mau sekedar say hi saja.

Tapi ternyata si eneng ini asik dan membuat diri ini terjebak dalam suatu komunikasi yang susah diungkapkan dengan kata.

Django Cache Framework

Intronya kok lebay yah, mau dihapus tapi sayang juga karena kata - kata itu muncul tiba -tiba. Mungkin efek dari asupan kopi yang overload ke otak.

Atau mungkin bisikan dari eneng ghaib yang geulis?

Whatever lah.

Intinya malam ini saya tertarik sama berbagai file __pycache__ yang berseliweran diantara file - file lainnya.

Kenal cache sudah lama sih, sejak jaman ngotak ngatik Wordpress.

Berdasarkan feeling, saya merasa kalau implementasi cache di Django pasti tidak semudah implementasi cache di Wordpress.

Kalau lagi malas, implementasi cache di Wordpress tinggal cari plugin, install, dan selesai.

Tapi kalau lagi iseng, tinggal lihat dan pelajari source code berbagai plugin, pahami konsepnya, terus modifikasi and add my own logic untuk membuat system yang lebih personal.

Tapi di Django beda.

Makanya selama ini saya berusaha cuek, karena kalau sudah masuk saya pasti bakal terlalu fokus di cache.

Dan akhirnya saya pun terjerat dan terjebak.

Entah sudah berapa jam saya bergelut sama Django cache, but let's take a break and look at the rundown of some findings.

The Cache

Sudah sejak jaman otak atik Wordpress saya tau kalau cache bisa mempercepat loading dari website. Yang jadi kendala adalah cara implementasinya.

Untuk seorang programmer tulen mungkin hal tersebut bukan masalah, tapi untuk saya yang hanya programmer jadi-jadian tentunya hal itu menjadi kendala tersendiri. 😱

Apa itu cache?

Cache adalah bentuk copy sementara dari halaman suatu website, sehingga website dinamis bisa berperilaku seperti layaknya sebuah web statis.

Runutan web dinamis dalam memproses request umumnya melibatkan code processing, komunikasi database, proses cek ricek, template rendering, baru memberikan response.

Nah kalau web statis, prosesnya cuma mencari ada atau tidak filenya terus langsung memberikan response.

Hasil dari response inilah yang merupakan tampilan halaman web yang biasa kita lihat di browser maupun aplikasi.

Jadi cache inilah yang menolong web dinamis dalam mempersingkat beberapa proses.

Kenapa sifatnya cuma sementara?

Karena kalau dibuat permanen terus ada update atau modifikasi konten, maka hasil update atau modifikasi tersebut tidak akan muncul di web.

Isi yang ada di cache adalah isi konten sewaktu cache dibuat, jadi kalau ada perubahan maka isi dari cache juga perlu diubah.

Jadi kita harus memberi tahu ke cache kalau ada perubahan dengan cara berkomunikasi dalam bentuk code.

"Cuy, konten x yang itu sudah expired. Ada yang baru nih, update-an dari si Fergusso"

Atau dari sisi cache,

"Sob, ada yang minta konten x nih. Punya ane sudah expired, ada yang baru kagak? Kalau gak ada, render aja yang ada kali aja ente lupa!"

Kira - kira seperti itu chit chat antara web framework sama cache backend. Belum lagi komunikasi antara cache dengan web server atau database, kalau dijabarkan mungkin jadi novel.

Ada banyak bentuk dan sistem cache, kalau saya mengkategorikannya dalam 3 grup biar gampang diingat, yaitu server cache, client cache, dan external cache.

Saat ini saya mau main di area server cache dulu, itupun mungkin tidak terlalu jauh.

Karena kalau main di semua area dan mendalam, saya mungkin bakal menghabiskan waktu berbulan - bulan cuma untuk ngurusin sistem cache web ini. 😂

Tapi mungkin next bakal sedikit nge-tweak cache dari file statik, biar ngebantu visitor sedikit berhemat kuota kalau mampir lagi ke web ini.

Snorkel On The Cache Framework

Sebenarnya untuk web yang baru dan masih kecil ini, optimasi seperti cache belum terlalu diperlukan.

Apalagi visitor kayaknya masih seekor atau dua ekor, yaitu saya pakai lappie, saya pakai hape, dan mungkin bini.

Jadi optimasi belum perlu - perlu amat.

Kecuali kalau visitor sudah ratusan atau ribuan per jam, walau web tergolong masih baru dan kecil, tetap perlu optimasi.

Tapi seperti cerita saya di atas, jadi saya terpaksa deh nengokin cache.

Sempet sih tergoda untuk diving in to the cache realm, cuma takut keasikan dan malah sibuk ngurusin cache.

Makanya saya mencoba untuk selalu self reminder, snorkel aja dulu diving-nya lain kali aja.

Karena snorkel di Django Cache Framework saja sudah cukup makan waktu. Kalau diving, bisa - bisa gawean, istri, dan anak terbengkalai!! 😖

Berdasarkan wawasan awal dan hasil riset dari stackoverflow, reddit, serta berbagai web, saya akhirnya memilih Redis Cache.

Pertimbangannya karena Redis sistemnya in-memory caching, yang mana tentunya lebih kencang dibanding yang bukan in-memory.

Sempat terpikir pakai Memcached, karena kayaknya lebih simple.

Tapi Redis 'katanya' lebih unggul dalam hal scalability. Ya siapa tau web ini bakal expand atau jadi besar, jadi biar gak repot kenalan lagi maka jadilah Redis yang terpilih.

Amunisi

Untuk menggunakan redis cache, maka kita perlu menginstall redis sebagai backend engine dan redis-py sebagai binding.

sudo pacman -S redis

pip install redis

Kemudian untuk parser, saya menambah hiredis-py sebagai module tambahan untuk mempercepat proses parsing.

Sebenarnya parser default sudah cukup, karena saat ini saya cuma mau menerapkan cache yang simple.

Tapi siapa tau bisa membantu walau cuma 0.00xx miliseconds. 😅

pip install hiredis

Kemudian sesuai panduan dari kitab Django, kita perlu menginformasikan sistem cache yang akan digunakan.

Kemudian kita perlu menginformasikan ke Django tentang sistem cache yang akan digunakan dengan cara menulis informasi tersebut di dalam settings.

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',
    }
}

Konfigurasi di atas hanya contoh simple, tentunya untuk keperluan spesifik berbagai konfigurasi perlu di tweaking lebih lanjut.

But I think it's enough, for now. 🤪

Implementasi Cache

Secara umum ada tiga cara untuk mengimplementasikan cache, dan Django tergolong fleksibel karena menyediakan berbagai alternatif pilihan untuk menyesuaikan kebutuhan kita.

Full Cache
Merupakan cache yang diterapkan pada seluruh isi dan komponen web secara menyeluruh.
Cara ini yang paling gampang dan simple. Tapi menurut saya cara ini efektif hanya untuk web dinamis yang bersifat 'statis'.
Untuk mengimplementasikannya, di Django menggunakan cara per-site cache.
Page Cache
Merupakan cache yang diterapkan secara menyeluruh hanya pada halaman - halaman web (webpage) tertentu.
Metode ini tergolong efektif untuk web dinamis yang menginginkan perilaku semi-statis, karena cukup fleksibel dan mudah dalam penerapannya.
Untuk mengimplementasikannya di Django bisa menggunakan cara per-view cache di views.py atau di urls.py.
Sectional Cache
Merupakan cache yang diterapkan secara spesifik pada komponen dan elemen tertentu di web.
Cara ini sangat fleksibel, dimana kita bisa menerapkan cache's timeout secara spesifik dan bervariasi pada tiap komponen.
Timeout untuk menu navigasi bisa diatur lebih lama dari timeout konten misalnya, karena menu navigasi jarang berubah, di update, atau di modifikasi dibandingkan konten.
Untuk mengimplementasikannya di Django bisa menggunakan cara template fragment cache atau low level cache API.

Dari pilihan tersebut, saya pun memilih page cache karena ada beberapa halaman web yang tidak ingin saya cache, seperti halaman draft, statistik, page info, dan lain sebagainya.

Karena itu saya tidak menerapkan full cache.

Web ini sebenarnya lebih efektif kalau pakai sectional cache, apalagi nanti kalau konten dan visitor sudah banyak.

Karena komponen seperti menu navigasi dan footer tentunya bisa di cache lebih lama dibanding cache dari isi konten.

Dan cache isi konten juga bisa di cache lebih lama dibanding komponen yang lebih dinamis seperti related posts misalnya.

Tapi saya perlu invest waktu lagi kalau mau menerapkan sectional / fragment cache.

Karena tadi sempat sedikit otak atik, dan banyak sistem komunikasi database yang perlu disesuaikan.

Performance

Tes saya lakukan di lappie, so banyak faktor yang mempengaruhi hal di atas. Utamanya server yang bersifat lokal, dan resource lappie yang tentu jauh lebih bagus dibanding resource VPS saya yang bokekers.

Kalau sempat dan tidak malas, mungkin lain waktu saya bakal iseng coba di server biar terlihat seperti apa.

Karena kalau di server perlu setup development environment euy, biar flow koneksi, latency, web server, dan lain sebagainya bisa ikut terlibat.

Agak ribet cuy.

Karena cuma untuk gambaran pribadi, jadi saya sedikit iseng saja melakukan rough benchmark yang jelas kurang validasinya. 🤪

Saya cuma ingin dapat pandangan seberapa sih peningkatan performanya.

Gambar benchmark tanpa cache
Hasil Tanpa Cache

Sebelum menerapkan cache, terlihat ada 6 query ke database. Proses CPU juga lumayan, total cuma 314,5 miliseconds.

Walaupun lappie sudah tua, dulu beli sekitar bulan Mei tahun 2014, tapi masih gercep juga. Mungkin karena the power of Arch!!

Setelah menerapkan page cache, hasilnya seperti terlihat di bawah, yaitu salah satu hasil yang sempat di screenshot.

Gambar benchmark page cache
Hasil Page Cache

Terlihat kalau query ke database jadi 0, template tidak di render, dan beban CPU jadi berkurang sehingga CPU memproses cuma dalam 150an miliseconds.

Itu baru 6 query, coba bayangkan kalau ada puluhan query ke database, cache sangat membantu sekali!!

So kalau dibandingkan, dengan parameter 10 specimen, maka kurang lebih hasilnya seperti pada tabel berikut ini.

Page Cache vs Non Cache
REP NON CACHE PAGE CACHE
1 1282 1143
2 1258 1083
3 1262 973
4 1352 1121
5 1268 1203
6 1309 1087
7 1291 1166
8 1345 1075
9 1069 986
10 1309 1146
AVERAGE 1274,5 1098,3

Dari hasil di atas, terlihat ada peningkatan ± 16% kalau menggunakan page cache di lappie. Lumayan lah.

Saya sempat coba iseng pakai low level cache, tapi sepertinya ada yang salah sama konfigurasi yang saya lakukan.

Gambar coba low level cache
Iseng Coba Low Level Cache

Karena query ke database tidak berkurang, tetap ada 6 query. Dan karena ada tambahan cache proses, CPU jadinya memproses lebih lambat dibandingkan kalau tidak memakai cache.

Salah satu penyebabnya yaitu karena query database tidak ter-cache.

Untuk mengatasi satu penyebab itu, maka perlu dilakukan tracing dari template dan views, hingga ke cabang - cabangnya.

So untuk notes lain kali sajalah, karena tracing perlu waktu dan effort lebih.

Sekalian mungkin nanti di combine antara low level cache dengan template fragment.

Karena sudah jam 03.07 dini hari dan sudah ada ayam yang iseng berkokok padahal belum waktunya, jadi hasil sementara saya bungkus saja dulu.

Wrapping Up

Akhirnya selesai juga ngotak atik cache sambil ngetik tulisan ini. Walau belum maksimal, tapi saya rasa sudah cukup untuk kondisi saat ini.

Daripada di tegur sama The Big Boss karena kagak laporan subuh dan malah laporan dhuha.

Semoga tulisan ini bisa menjadi bacaan ringan walaupun mungkin anda bukan penggemar dunia biner.

Tulisan ini merupakan catatan dan log pribadi yang dikemas dengan keluh kesah saat melakukannya.

So jadikan tulisan ini sebagai pelengkap wawasan saja, jangan dijadikan referensi mutlak di karya ilmiah, jurnal, TA ataupun skripsi yah.

Kalau untuk referensi yang bersifat ilmiah atau akademik, tracing saja mulai dari berbagai link di atas, terus bisa dilanjutkan dengan berkubang di search engine.