Rumah > Artikel > pangkalan data > Bagaimanakah redis menyelesaikan masalah ketidakkonsistenan cache?
Artikel ini membawakan anda cara Redis menyelesaikan masalah ketidakkonsistenan cache dan bagaimana ketidakkonsistenan data berlaku antara cache dan pangkalan data Mari kita lihat bersama-sama .
Pembelajaran yang disyorkan: Tutorial pembelajaran Redis
Pertama sekali, kita perlu memahami maksud "ketekalan data" secara khusus. Sebenarnya, "konsistensi" di sini merangkumi dua situasi:
Untuk caching baca-tulis, jika anda ingin menambah, memadam atau mengubah suai data, anda perlu melakukannya dalam cache Pada masa yang sama, anda mesti memutuskan sama ada untuk menulisnya kembali ke pangkalan data secara serentak mengenai strategi tulis balik yang diguna pakai.
Strategi tulis langsung segerak: Apabila menulis cache, pangkalan data juga ditulis serentak, dan data dalam cache dan pangkalan data adalah konsisten; pangkalan data tidak ditulis secara serentak sehingga data diambil daripada pangkalan data Apabila dihapuskan daripada cache, ia ditulis semula ke pangkalan data. Apabila menggunakan strategi ini, jika data belum ditulis kembali ke pangkalan data, cache akan gagal, dan pada masa ini, pangkalan data tidak akan mempunyai data terkini.
Oleh itu, untuk cache baca-tulis, jika anda ingin memastikan bahawa data dalam cache dan pangkalan data adalah konsisten, anda mesti menggunakan strategi tulis langsung segerak. Walau bagaimanapun, perlu diingatkan bahawa jika anda menggunakan strategi ini, anda perlu mengemas kini cache dan pangkalan data pada masa yang sama. Oleh itu, kita perlu menggunakan mekanisme transaksi dalam aplikasi perniagaan untuk memastikan kemas kini cache dan pangkalan data adalah atom, ia sama ada dikemas kini bersama-sama atau tidak dikemas kini, mesej ralat dikembalikan dan cuba semula dilakukan. Jika tidak, kita tidak boleh mencapai penulisan langsung segerak.
Sudah tentu, dalam beberapa senario, keperluan kami untuk konsistensi data mungkin tidak begitu tinggi Contohnya, jika kami menyimpan atribut bukan kritikal produk e-dagang atau masa penciptaan atau pengubahsuaian video pendek, maka. kami Strategi tulis balik tak segerak boleh digunakan.
Mari kita bincangkan tentang caching baca sahaja. Untuk cache baca sahaja, jika terdapat data baharu, ia akan ditulis terus ke pangkalan data apabila terdapat pemadaman data, data dalam cache baca sahaja perlu ditandakan sebagai tidak sah. Dengan cara ini, apabila aplikasi kemudiannya mengakses data yang ditambah, dipadam atau diubah suai ini, kehilangan cache akan berlaku kerana tiada data yang sepadan dalam cache. Pada masa ini, aplikasi membaca data daripada pangkalan data ke dalam cache, supaya apabila data itu diakses kemudian, ia boleh dibaca terus dari cache.
Seterusnya, ambil Tomcat menulis dan memadam data ke MySQL sebagai contoh untuk menerangkan kepada anda bagaimana operasi penambahan, pemadaman dan pengubahsuaian data dilakukan, seperti yang ditunjukkan dalam rajah berikut:
Seperti yang boleh dilihat dari rajah, aplikasi yang berjalan pada Tomcat, sama ada menambah (operasi Sisipkan), mengubah suai (Kemas kini operasi), atau memadam (operasi Padam) data X, akan terus menambah, mengubah suai dan memadam data dalam pangkalan data. Sudah tentu, jika aplikasi melakukan operasi pengubahsuaian atau pemadaman, data cache X juga akan dipadamkan.
Jadi, adakah akan wujud ketidakkonsistenan data dalam proses ini? Memandangkan situasi menambah data dan memadam data adalah berbeza, kami melihatnya secara berasingan.
Data baharuJika ia adalah data baharu, data akan ditulis terus ke pangkalan data tanpa sebarang operasi pada cache Pada masa ini, tiada data baharu dalam cache itu sendiri. dan pangkalan data adalah nilai terkini.
Aplikasi ingin mengemas kini nilai data X daripada 10 kepada 3. Ia mula-mula memadamkan nilai cache X dalam cache Redis, tetapi kemas kini kepada pangkalan data gagal. Jika terdapat permintaan serentak lain untuk mengakses
Anda mungkin bertanya, jika kami mengemas kini pangkalan data dahulu dan kemudian memadamkan nilai dalam cache, adakah masalah ini boleh diselesaikan? Mari analisa semula.
Jika aplikasi melengkapkan kemas kini pangkalan data terlebih dahulu, tetapi gagal apabila memadam cache, maka nilai dalam pangkalan data adalah nilai baru dan nilai dalam cache adalah nilai lama, yang pastinya tidak konsisten. Pada masa ini, jika terdapat permintaan serentak lain untuk mengakses data, mengikut proses capaian cache biasa, cache akan ditanya terlebih dahulu, tetapi pada masa ini, nilai lama akan dibaca.
Biar saya jelaskan dengan bantuan contoh.
Aplikasi ingin mengemas kini nilai data X dari 10 hingga 3. Ia mula-mula berjaya mengemas kini pangkalan data dan kemudian memadamkan cache X dalam cache Redis, tetapi ini operasi gagal, pada masa ini, nilai baharu X dalam pangkalan data ialah 3, dan nilai cache X dalam Redis ialah 10, yang pastinya tidak konsisten. Jika pelanggan lain menghantar permintaan untuk mengakses X pada masa ini, ia akan membuat pertanyaan terlebih dahulu dalam Redis Pelanggan akan menemui hit cache, tetapi nilai lama 10 akan dibaca.
Baiklah, di sini, kita dapat melihat bahawa dalam proses mengemas kini pangkalan data dan memadam nilai cache, tidak kira susunan pelaksanaan kedua-dua operasi ini, selagi satu operasi gagal, ia akan Menyebabkan klien membaca nilai lama. Saya melukis jadual di bawah untuk meringkaskan dua situasi yang baru disebut.
Kita tahu punca masalah, tetapi bagaimana untuk menyelesaikannya?
Pertama, izinkan saya memperkenalkan anda kepada kaedah: mekanisme cuba semula.
Secara khusus, anda boleh menyimpan sementara nilai cache yang akan dipadamkan atau nilai pangkalan data yang akan dikemas kini dalam baris gilir mesej (contohnya, menggunakan baris gilir mesej Kafka). Apabila aplikasi gagal berjaya memadamkan nilai cache atau mengemas kini nilai pangkalan data, ia boleh membaca semula nilai daripada baris gilir mesej dan memadam atau mengemas kininya semula.
Jika pemadaman atau kemas kini boleh berjaya, kami akan mengalih keluar nilai ini daripada baris gilir mesej untuk mengelakkan operasi berulang Pada masa ini, kami juga boleh memastikan bahawa pangkalan data dan data cache adalah konsisten. Jika tidak, kita perlu mencuba lagi. Jika percubaan semula melebihi beberapa kali dan masih gagal, kami perlu menghantar mesej ralat ke lapisan perniagaan.
Gambar di bawah menunjukkan semasa mengemas kini pangkalan data dahulu dan kemudian memadamkan nilai cache Jika pemadaman cache gagal dan pemadaman berjaya selepas mencuba semula, anda boleh lihat.
Apa yang baru saya bincangkan ialah situasi di mana salah satu operasi gagal semasa proses mengemas kini pangkalan data dan memadamkan nilai cache, walaupun kedua-dua operasi ini dilaksanakan buat kali pertama Tiada satu pun daripadanya gagal Apabila terdapat sejumlah besar permintaan serentak, aplikasi mungkin masih membaca data yang tidak konsisten.
Begitu juga, kami membahagikannya kepada dua situasi mengikut pesanan pemadaman dan kemas kini yang berbeza. Dalam kedua-dua kes, penyelesaian kami juga berbeza.
Andaikan selepas utas A memadamkan nilai cache, utas B mula membaca data sebelum sempat mengemas kini pangkalan data (contohnya, terdapat kelewatan rangkaian, kemudian pada masa ini,). thread B akan mendapati bahawa cache tiada. Anda hanya boleh membaca daripada pangkalan data. Ini akan menyebabkan dua masalah:
Selepas thread B membaca data dari pangkalan data dan mengemas kini cache, thread A mula mengemas kini pangkalan data Pada masa ini, data dalam cache ialah nilai lama, manakala data dalam pangkalan data adalah nilai terkini. Kedua-duanya tidak konsisten.
Saya menggunakan jadual untuk meringkaskan keadaan ini.
Apa yang perlu saya lakukan? Biar saya berikan anda penyelesaian.
Selepas urutan A mengemas kini nilai pangkalan data, kami boleh membiarkannya tidur untuk tempoh masa yang singkat dan kemudian melakukan operasi pemadaman cache.
Sebab tempoh tidur ditambah adalah untuk membenarkan utas B membaca data daripada pangkalan data dahulu, kemudian menulis data yang hilang pada cache, dan kemudian utas A memadamkannya. Oleh itu, masa untuk thread A tidur perlu lebih besar daripada masa untuk thread B membaca data dan kemudian menulisnya ke cache. Bagaimana untuk menentukan masa ini? Anda disyorkan agar mengira masa operasi urutan membaca data dan menulis cache apabila program perniagaan dijalankan dan membuat anggaran berdasarkan ini.
Dengan cara ini, apabila utas lain membaca data, mereka akan mendapati bahawa cache tiada, jadi mereka akan membaca nilai terkini daripada pangkalan data. Oleh kerana penyelesaian ini akan melambatkan pemadaman untuk seketika selepas memadamkan nilai cache buat kali pertama, kami juga memanggilnya "pemadaman berganda tertunda".
Kod pseudo berikut ialah contoh penyelesaian "pemadaman dua kali tertunda", anda boleh lihat.
redis.delKey(X) db.update(X) Thread.sleep(N) redis.delKey(X)
Kes 2: Kemas kini nilai pangkalan data dahulu, dan kemudian padamkan nilai cache.
Jika utas A memadamkan nilai dalam pangkalan data, tetapi sebelum ia mempunyai masa untuk memadamkan nilai cache, utas B mula membaca data Pada masa ini, apabila utas B menanyakan cache, ia mencari hit cache Nilai lama akan dibaca terus daripada cache. Walau bagaimanapun, dalam kes ini, jika tidak terdapat banyak permintaan serentak daripada utas lain untuk membaca cache, maka tidak akan ada banyak permintaan untuk membaca nilai lama. Juga, Thread A biasanya akan memadamkan nilai cache dengan cepat, supaya apabila thread lain dibaca semula, kehilangan cache akan berlaku dan nilai terkini akan dibaca daripada pangkalan data. Oleh itu, keadaan ini kurang memberi kesan kepada perniagaan.
Saya akan melukis jadual lain untuk meringkaskan untuk anda situasi mengemas kini pangkalan data dahulu dan kemudian memadamkan nilai cache.
Baiklah, di sini kami telah mengetahui bahawa ketidakkonsistenan data antara cache dan pangkalan data biasanya disebabkan oleh dua sebab, dan saya telah memberikan anda penyelesaian yang sepadan.
Pembelajaran yang disyorkan: Tutorial video Redis
Atas ialah kandungan terperinci Bagaimanakah redis menyelesaikan masalah ketidakkonsistenan cache?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!