Rumah > hujung hadapan web > tutorial js > Cara Membuat Cache Dalam Memori

Cara Membuat Cache Dalam Memori

Patricia Arquette
Lepaskan: 2024-12-27 02:37:09
asal
668 orang telah melayarinya

How to Create an In-Memory Cache

Dalam banyak projek, saya dapati bahawa walaupun cache boleh berguna — terutamanya pada bahagian pelanggan— ia sering diabaikan. Caching sebelah pelanggan adalah penting dalam meningkatkan pengalaman pengguna dengan mengurangkan kependaman dan memunggah permintaan pelayan berulang. Contohnya, dalam aplikasi dengan tatal tanpa had atau papan pemuka yang kerap dikemas kini, caching data yang diambil sebelum ini menghalang panggilan API yang tidak diperlukan, memastikan interaksi yang lebih lancar dan masa pemaparan yang lebih cepat.

Dalam salah satu projek saya baru-baru ini, melaksanakan cache mengurangkan volum panggilan API sebanyak lebih 40%, membawa kepada peningkatan prestasi yang ketara dan penjimatan kos. Ini menggariskan sebab caching sebelah pelanggan harus dianggap sebagai strategi pengoptimuman asas. Cache cenderung menjadi salah satu ciri terakhir yang dipertimbangkan, walaupun kesannya yang ketara terhadap prestasi dengan pelaksanaan yang agak mudah, sama ada disebabkan oleh kekangan masa pembangunan atau keutamaan lain.

Cache boleh dilaksanakan pada pelbagai peringkat dalam seni bina: daripada caching backend menggunakan Redis, CDN untuk kandungan statik, kepada cache dalam memori pada klien atau menggunakan localStorage atau IndexedDB untuk kegigihan. Sebaik-baiknya, strategi ini harus digabungkan untuk mengurangkan beban dan kos pangkalan data dan API, serta ketinggalan daripada permintaan pelayan pelanggan, terutamanya untuk data yang telah diambil sebelum ini.

Dalam artikel ini, kami akan meneroka cara mereka bentuk dan melaksanakan cache LRU (Paling Kurang Digunakan) dengan sokongan TTL (Time-to-Live) dalam JavaScript, mencipta pakej yang serupa dengan adev-lru saya. Pada akhirnya, anda akan mempunyai contoh yang berkesan yang mempamerkan prinsip teras dan kefungsian penyelesaian caching yang berkesan.


Apakah Cache LRU?

Cache LRU (Paling Kurang Digunakan) memastikan item yang paling baru diakses kekal dalam ingatan sambil mengusir item yang paling kurang diakses baru-baru ini apabila melebihi kapasitinya. Strategi ini berfungsi dengan mengekalkan susunan penggunaan: setiap aksesori mengemas kini kedudukan item dalam cache, dengan item yang paling kurang diakses dialih keluar terlebih dahulu.

Berbanding dengan strategi caching lain, LRU mengimbangi kesederhanaan dan kecekapan, menjadikannya sangat sesuai untuk senario di mana penggunaan terkini merupakan penunjuk yang boleh dipercayai bagi akses masa hadapan. Contohnya, aplikasi yang menyimpan cache respons API, lakaran kenit atau keutamaan pengguna yang kerap diakses boleh memanfaatkan LRU untuk mengurangkan operasi pengambilan berlebihan tanpa merumitkan proses pengusiran secara berlebihan.

Tidak seperti LFU (Kurang Kerap Digunakan), yang menjejaki kekerapan akses dan memerlukan simpan kira tambahan, LRU mengelakkan kerumitan ini sambil masih mencapai prestasi cemerlang dalam banyak kes penggunaan dunia sebenar. Begitu juga, FIFO (Masuk Pertama, Keluar Dahulu) dan MRU (Terkini Digunakan) menawarkan dasar pengusiran alternatif tetapi mungkin tidak sejajar dengan corak penggunaan yang aktiviti terkini adalah kritikal. Dengan menggabungkan LRU dengan sokongan TTL (Time-to-Live) dalam pelaksanaan saya, ia juga mengendalikan senario di mana data memerlukan tamat tempoh automatik, meningkatkan lagi kebolehgunaannya dalam persekitaran dinamik seperti papan pemuka langsung atau perkhidmatan penstriman. Ia amat berguna dalam aplikasi yang akses kepada data terbaharu adalah kritikal.

Perlaksanaan

Kelas LRUCache dibina untuk menjadi cekap, menyokong konfigurasi fleksibel dan mengendalikan pengusiran automatik. Di bawah adalah beberapa kaedah utama:

Mencipta Cache

public static getInstance<T>(capacity: number = 10): LRUCache<T> {
    if (LRUCache.instance == null) {
        LRUCache.instance = new LRUCache<T>(capacity);
    }
    return LRUCache.instance;
}
Salin selepas log masuk
Salin selepas log masuk

Kaedah ini memastikan hanya terdapat satu contoh cache dalam aplikasi, pilihan reka bentuk yang memudahkan pengurusan sumber. Dengan melaksanakan cache sebagai singleton, kami mengelakkan penggunaan memori yang berlebihan dan memastikan data yang konsisten merentas aplikasi. Ini amat berharga dalam senario di mana berbilang komponen atau modul memerlukan akses kepada data cache yang sama, kerana ia menghalang konflik dan memastikan penyegerakan tanpa memerlukan logik penyelarasan tambahan. Jika tiada kapasiti dinyatakan, ia lalai kepada 10.

Menambah Item pada Cache

public put(key: string, value: T, ttl: number = 60_000): LRUCache<T> {
    const now = Date.now();
    let node = this.hash.get(key);
    if (node != null) {
        this.evict(node);
    }
    node = this.prepend(key, value, now + ttl);
    this.hash.set(key, node);
    if (this.hash.size > this.capacity) {
        const tailNode = this.pop();
        if (tailNode != null) {
            this.hash.delete(tailNode.key);
        }
    }
    return this;
}
Salin selepas log masuk
Salin selepas log masuk

Kaedah ini menambah atau mengemas kini item dalam cache. Apabila kunci sudah wujud, item yang sepadan akan diusir dan ditambahkan semula di hadapan cache. Untuk melakukan ini, cache menggunakan Senarai Berganda Berkaitan untuk menyimpan data sebagai nod dan mengekalkan keupayaan untuk memadam data dari penghujung senarai — Ekor— dan mengalihkannya ke permulaan senarai — Kepala —, untuk menjamin pemalar O (1) membaca setiap data nod, Jadual Hash digunakan untuk menyimpan penunjuk pada setiap nod senarai. Proses ini selaras dengan prinsip LRU dengan memastikan item yang diakses baru-baru ini sentiasa diutamakan, menandakannya sebagai "terbaru digunakan." Dengan berbuat demikian, cache mengekalkan susunan penggunaan yang tepat, yang penting untuk membuat keputusan pengusiran apabila kapasiti melebihi. Tingkah laku ini memastikan sumber diurus secara optimum, meminimumkan masa mendapatkan semula data yang kerap diakses. Jika kunci sudah wujud, item itu dialihkan ke hadapan untuk menandakannya sebagai digunakan baru-baru ini.

Mendapatkan semula Item daripada Cache

public get(key: string): T | undefined {
    const node = this.hash.get(key);
    const now = Date.now();
    if (node == null || node.ttl < now) {
        return undefined;
    }
    this.evict(node);
    this.prepend(node.key, node.value, node.ttl);
    return node.value;
}
Salin selepas log masuk

Kaedah ini mendapatkan semula item yang disimpan. Jika item telah tamat tempoh, ia dialih keluar daripada cache.

Metrik Prestasi

Untuk menilai kecekapan cache, saya melaksanakan metrik prestasi seperti kadar pukulan, kesilapan dan pengusiran:

public static getInstance<T>(capacity: number = 10): LRUCache<T> {
    if (LRUCache.instance == null) {
        LRUCache.instance = new LRUCache<T>(capacity);
    }
    return LRUCache.instance;
}
Salin selepas log masuk
Salin selepas log masuk

Membersihkan Cache

public put(key: string, value: T, ttl: number = 60_000): LRUCache<T> {
    const now = Date.now();
    let node = this.hash.get(key);
    if (node != null) {
        this.evict(node);
    }
    node = this.prepend(key, value, now + ttl);
    this.hash.set(key, node);
    if (this.hash.size > this.capacity) {
        const tailNode = this.pop();
        if (tailNode != null) {
            this.hash.delete(tailNode.key);
        }
    }
    return this;
}
Salin selepas log masuk
Salin selepas log masuk

Kaedah ini mengosongkan semua item dan menetapkan semula keadaan cache.

Dalam pelaksanaan saya, saya juga telah menambah kaedah lain seperti getOption yang bukannya mengembalikan T | undefined ia mengembalikan contoh Pilihan monad untuk mereka yang lebih suka pendekatan yang lebih berfungsi. Saya juga menambahkan monad Penulis untuk menjejaki setiap operasi pada cache untuk tujuan pengelogan.

Anda boleh melihat semua kaedah lain yang terlibat dalam algoritma ini, diulas dengan sangat baik, pada repositori ini: https://github.com/Armando284/adev-lru


Membandingkan Algoritma Cache

Cache LRU bukan satu-satunya pilihan. Memilih algoritma caching yang betul sangat bergantung pada keperluan khusus aplikasi dan corak akses. Di bawah ialah perbandingan LRU dengan strategi caching lain yang biasa digunakan dan panduan tentang masa untuk menggunakan setiap satu:

  • LFU (Kurang Kerap Digunakan): Algoritma ini mengusir item yang paling kerap diakses. Ia sesuai untuk senario di mana kekerapan penggunaan dari semasa ke semasa merupakan peramal yang lebih baik untuk akses masa hadapan berbanding kekinian. Walau bagaimanapun, ia biasanya memerlukan simpan kira tambahan untuk menjejak kiraan akses, menjadikannya lebih kompleks dan mahal dari segi pengiraan daripada LRU. Gunakan LFU untuk aplikasi seperti enjin pengesyoran atau saluran paip pembelajaran mesin yang corak penggunaan sejarah adalah kritikal.
  • FIFO (Masuk Pertama, Keluar Dahulu): Pendekatan ini mengalih keluar item tertua, tanpa mengira kekerapan item itu diakses. Walaupun ia mudah untuk dilaksanakan, FIFO mungkin tidak sesuai untuk kebanyakan kes penggunaan kerana ia tidak mempertimbangkan corak penggunaan. Ia boleh berfungsi untuk aplikasi dengan aliran kerja tetap dan boleh diramal, seperti menyimpan konfigurasi statik atau aset pramuat.
  • MRU (Terkini Digunakan): MRU mengusir item yang paling baru diakses, bertentangan dengan LRU. Strategi ini paling sesuai untuk situasi di mana data lama lebih berkemungkinan untuk digunakan semula, seperti sistem rollback atau jenis operasi buat asal tertentu.

Bila Menggunakan LRU

LRU menyeimbangkan antara kesederhanaan dan keberkesanan, menjadikannya sesuai untuk aplikasi yang aktiviti terkini berkait rapat dengan penggunaan masa hadapan. Contohnya:

  • Caching Web dan API: LRU sangat sesuai untuk mengurangkan panggilan API yang berlebihan, terutamanya dalam senario seperti paparan penomboran, penatalan tidak terhingga atau tinjauan data langsung yang kerap.
  • Aplikasi Multimedia: Cache baru-baru ini memainkan atau melihat item seperti video atau imej.
  • Pengurusan Negeri UI: Simpan keadaan komponen yang diakses baru-baru ini untuk meningkatkan prestasi pemaparan.

Sebaliknya, jika corak akses menunjukkan bahawa kekerapan atau susunan sisipan adalah lebih berkaitan, algoritma seperti LFU atau FIFO mungkin merupakan pilihan yang lebih baik. Menilai pertukaran ini memastikan bahawa strategi caching sejajar dengan matlamat aplikasi anda dan kekangan sumber.

  • LFU (Kurang Kerap Digunakan): Mengalih keluar item yang paling kurang diakses berdasarkan kekerapan.
  • FIFO (Masuk Pertama, Keluar Dahulu): Mengusir item tertua, tanpa mengira penggunaan terkini.
  • MRU (Terkini Digunakan): Mengalih keluar item yang paling baru ditambah, bertentangan dengan LRU.

Kesimpulan

Melaksanakan cache dalam memori boleh meningkatkan prestasi aplikasi dengan ketara, mengurangkan masa tindak balas dan meningkatkan pengalaman pengguna.

Jika anda ingin melihat Cache LRU penuh dalam tindakan anda boleh menggunakan pakej npm saya https://www.npmjs.com/package/adev-lru Saya juga ingin mendapatkan maklum balas anda untuk terus memperbaikinya.

Cuba pakej dan kongsi pendapat anda atau sumbangkan jika anda rasa ingin membantu lebih lagi?!

Atas ialah kandungan terperinci Cara Membuat Cache Dalam Memori. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan