Salah satu hal yang sering membingungkan pengguna yang terbiasa dengan database lain ketika mereka mencoba Redis, adalah kurangnya visibilitas ke dalam database:Tidak ada set tabel atau koleksi untuk lihat, hanya ruang kunci datar yang bisa (berpotensi) memiliki jutaan kunci. Oleh karena itu, kemampuan untuk beralih secara murah pada ruang kunci ini menjadi sangat penting untuk membiasakan diri dengan konten basis data.
Mengulangi ruang kunci Redis memiliki kasus penggunaan penting lainnya, juga beberapa yang terlintas dalam pikiran adalah:
- pengumpulan sampah atau kunci pembersihan yang cocok dengan pola tertentu
- pergerakan data dan perubahan skema atau memindahkan kumpulan kunci tertentu ke struktur data lain
- debugging, pengambilan sampel data, perbaikan data atau menemukan dan memperbaiki semua kunci yang kacau karena perubahan terbaru
Dalam postingan ini, kita akan menggali lebih dalam berbagai opsi iterasi ruang utama yang tersedia di Redis.
O(N) Iterator:KUNCI
Perintah Redis KEYS mengembalikan semua kunci dalam database yang cocok dengan suatu pola (atau semua kunci di ruang kunci). Perintah serupa untuk mengambil semua bidang yang disimpan dalam hash adalah HGETALL dan untuk semua mengambil anggota SMEMBERS. Kunci dalam Redis sendiri disimpan dalam kamus (alias tabel hash). Perintah KEYS bekerja dengan mengulangi kamus ini dan mengirimkan semua yang cocok dengan pola sebagai balasan Array tunggal. Perintah lainnya bekerja dengan cara yang sama.
Kinerja operasi semacam itu tergantung pada ukuran koleksi yaitu O(N). Oleh karena itu, penggunaan KEYS sangat tidak disarankan di lingkungan produksi dengan jumlah kunci yang banyak. Redis menjadi utas tunggal, diblokir selama iterasi ini sehingga memblokir operasi lain. Dengan demikian, KUNCI harus digunakan hanya untuk debugging dan acara-acara khusus lainnya di mana kinerja tidak menjadi perhatian (seperti ketika database telah dibawa offline untuk menerapkan perbaikan data). Hal penting lainnya yang perlu diingat tentang algoritme ini adalah ia mengirimkan semua kunci yang cocok bersama-sama sebagai respons tunggal. Ini mungkin sangat nyaman ketika ruang kunci kecil tetapi akan menciptakan banyak masalah pada ruang kunci yang besar. KEYS bagaimanapun adalah perintah favorit di antara pengembang di lingkungan dev mereka sendiri.
KUNCI dalam Tindakan:
127.0.0.1:6379[1]> MSET satu 1 dua 2 tiga 3 empat 4OK# Semua kunci127.0.0.1:6379[1]> kunci *1) "empat"2) "tiga"3) " dua"4) "satu"# kunci yang dimulai dengan huruf 't'127.0.0.1:6379[1]> kunci t*1) "tiga"2) "dua"# kunci yang memiliki 'ee' di dalamnya127. 0.0.1:6379[1]> kunci *ee*1) "tiga"
Iterator Berbasis Kursor:SCAN
SCAN dan perintah saudaranya, SSCAN (untuk set), HSCAN (untuk hash) dan ZSCAN (untuk set yang diurutkan) menyediakan pendekatan berbasis kursor untuk iterasi pada struktur data Redis. Mereka telah tersedia di Redis sejak 2.8.0.
Kunci dikembalikan dalam iterasi tambahan dengan jaminan waktu konstan untuk setiap iterasi. Kursor (dalam kasus ini bilangan bulat) dikembalikan ketika iterasi diinisialisasi dan kursor yang diperbarui dikembalikan dan setiap iterasi. Siklus iterasi dimulai saat kursor disetel ke 0 dalam permintaan SCAN, dan berakhir saat kursor yang dikembalikan oleh server adalah 0. Karena nuansa arsitektur Redis dan implementasi algoritme kursor, berikut adalah beberapa keanehan dari pendekatan ini:
- Sebuah iterasi penuh selalu mengambil semua elemen yang ada dalam koleksi dari awal hingga akhir iterasi penuh.
- Sebuah iterasi penuh tidak pernah mengembalikan elemen apa pun yang TIDAK ada dalam koleksi dari awal hingga akhir iterasi penuh.
- Elemen tertentu dapat dikembalikan beberapa kali. Terserah aplikasi untuk menangani kasus elemen duplikat
- Elemen yang tidak selalu ada dalam koleksi selama iterasi penuh, dapat dikembalikan atau tidak:tidak ditentukan.
- Jumlah elemen yang dikembalikan selama setiap hitungan bervariasi dan bisa juga 0. Namun, iterasi tidak selesai sampai server mengembalikan nilai kursor 0.
- JUMLAH opsi dapat digunakan untuk membatasi jumlah elemen yang dikembalikan dalam setiap iterasi. Nilai default adalah 10. Namun, ini dianggap hanya saran dan tidak diterapkan dalam semua kasus. Nilai COUNT dapat diubah selama setiap panggilan iterasi.
- The MATCH opsi memungkinkan penentuan pola seperti yang diizinkan oleh perintah KEYS.
- Implementasi kursor benar-benar stateless di sisi server. Itu memungkinkan (berpotensi) iterasi tak terbatas untuk memulai secara paralel. Selain itu, tidak ada persyaratan untuk memastikan bahwa iterasi berlanjut hingga akhir dan dapat dihentikan kapan saja.
Meskipun memiliki kekhasan, SCAN adalah perintah yang sangat berguna dan perintah yang tepat untuk memilih iterasi ruang utama untuk sebagian besar kasus penggunaan.
SCAN adalah perintah yang sangat berguna dan perintah yang tepat untuk memilih iterasi ruang utama di #RedisClick To TweetPindai dalam Tindakan
127.0.0.1:6379[1]> tombol flushdbOK127.0.0.1:6379[1]> *(daftar atau set kosong)127.0.0.1:6379[1]> debug mengisi 33OK127.0.0.1:6379[ 1]> pindai 0 COUNT 51) "4"2) 1) "key:1" 2) "key:9" 3) "key:13" 4) "key:29" 5) "key:23"127.0. 0.1:6379[1]> scan 4 1) "42"2) 1) "key:24" 2) "key:28" 3) "key:18" 4) "key:16" 5) "key:12 " 6) "key:2" 7) "key:6" 8) "key:31" 9) "key:27" 10) "key:19"127.0.0.1:6379[1]> scan 421) "9 "2) 1) "key:3" 2) "key:4" 3) "key:20" 4) "key:8" 5) "key:32" 6) "key:5" 7) "key:26" 8) "key:10" 9) "key:21" 10) "key:14"127.0.0.1:6379[1]> pindai 9 COUNT 1001) "0"2) 1) "key:25" 2 ) "key:30" 3) "key:22" 4) "key:17" 5) "key:15" 6) "key:0" 7) "key:11" 8) "key:7"Di Balik Terpal
Algoritme yang digunakan SCAN (dan perintah saudaranya) untuk memindai adalah yang menarik dan mengarah ke beberapa karakteristik perintah yang kami jelaskan di atas. Antirez menggambarkannya pada tingkat tinggi di posting blognya dan dijelaskan (sedikit lebih baik) di komentar di atas implementasi (fungsi dictScan). Mendeskripsikan secara mendetail akan membuat postingan ini terlalu panjang, jadi saya akan memberikan deskripsi yang cukup untuk memperjelas implikasinya.
- Sebagian besar struktur data Redis direpresentasikan secara internal sebagai kamus (setidaknya sebagian dalam kasus kumpulan yang diurutkan). Mereka diimplementasikan sebagai tabel hash berukuran kekuatan dua dengan rantai untuk tabrakan. Tantangan dalam menulis algoritme iteratif berbasis kursor di sini adalah untuk dapat menangani pertumbuhan dan penyusutan hash tanpa mengorbankan prinsip kesederhanaan (API) dan kecepatan Redis.
- SCAN pada dasarnya memindai sekumpulan hash bucket setiap iterasi dan mengembalikan elemen yang cocok dengan pola di dalamnya. Karena hanya melihat daftar ember yang tetap, beberapa iterasi waktu mungkin tidak mengembalikan nilai sama sekali.
- Kursor yang dikembalikan pada dasarnya adalah offset ke tabel hash yang diulang. Ini berkaitan dengan pertumbuhan dan penyusutan tabel hash (yaitu pengulangan) dengan manipulasi cerdas bit tingkat offset yang lebih tinggi sambil meningkatkan offset bersama dengan properti tabel hash. Implikasi dari pendekatan ini adalah bahwa elemen baru yang ditambahkan selama iterasi dapat dikembalikan atau tidak. Namun, kursor itu sendiri, tidak perlu dimulai ulang pada perubahan ukuran tabel hash.
- Ember tertentu harus dikunjungi sekali saja dan semua kuncinya harus dikembalikan dalam sekali jalan. Ini sekali lagi untuk memastikan bahwa pengubahan ukuran hash (yaitu pengulangan) tidak mempersulit kemajuan iterasi. Namun, ini menyebabkan argumen COUNT tidak dapat ditegakkan secara ketat.
- Karena pendekatan di atas benar-benar stateless di sisi server, pada dasarnya ini menyiratkan bahwa iterasi dapat dihentikan atau sejumlah besar iterasi dapat dimulai secara paralel tanpa peningkatan penggunaan memori.
Ringkasan
Pada level tinggi, dua pilihan yang tersedia untuk diulang di atas ruang tombol Redis adalah:
- Gunakan KEYS saat performa tidak menjadi perhatian atau saat ruang kunci berukuran cukup.
- Di lain waktu, gunakan SCAN.
Tahukah Anda bahwa kami sekarang mendukung hosting untuk Redis™*? Dapatkan hosting yang terkelola sepenuhnya untuk Redis™ dengan keamanan akun cloud Anda sendiri, dan manfaatkan kredit AWS/Azure untuk penerapan Redis™ Anda.