Penggunaan Redis Pada Python
Manfaatkan penyimpanan data dalam memori untuk membuat aplikasi Python dengan cepat. Mencakup semuanya mulai dari mengelola klien Python Redis hingga mempelajari seluk-beluk struktur data Redis.
Butuh sepuluh tahun untuk pengembangan perangkat lunak. Saya pribadi senang mengamati erangan dan keluhan terus-menerus dari sesama pengembang tentang topik "framework baru". Dalam retorika standar, orang akan berpikir bahwa karier kita dikepung karena mempelajari teknologi baru. Mau tak mau saya bertanya-tanya bagaimana para profesional yang dihadapkan pada kemungkinan serupa bereaksi terhadap munculnya layanan cloud. Bagi mereka yang takut untuk belajar, mudah membayangkan perasaan mereka tentang penerapan paradigma baru yang hadir dengan layanan cloud yang baru lahir. Atau beberapa orang seperti saya. Seorang anak dewasa menyamar sebagai dunia orang dewasa. Kami mungkin terlihat lebih tua, tetapi kami hanya mengalihkan obsesi hidup kami dari set LEGO ke layanan cloud.
Saya telah menjadi korban lebih banyak siklus hype "teknologi baru" daripada yang ingin saya akui. Tersesat dalam alat buntu bisa menjadi tugas yang menakutkan. Saya pikir Anda ingat ketika seluruh dunia secara sewenang-wenang memutuskan untuk mengganti database relasional dengan alternatif NoSQL. Saya menyadari bagaimana keputusan arsitektur yang impulsif dapat menciptakan hutang teknis yang menghancurkan. Jadi saya tidak akan mendorong alat yang belum teruji oleh waktu dan utilitas nyata. Redis adalah salah satu alat tersebut, mungkin di antara lima besar teknologi baru yang berguna dalam dekade terakhir.
Mengapa Redis Tho?
Mengapa Anda memilih untuk mengotori basis data NoSQL sebelum mempertahankan Redis (penyimpanan data NoSQL)? MongoDB, seperti database SQL, menyimpan catatan di ruang disk. Mengalokasikan ruang disk untuk menyimpan catatan berarti informasi yang disimpan, seperti akun pengguna, entri blog, dan izin, dimaksudkan untuk dipertahankan. Sebagian besar data yang layak dipertahankan termasuk dalam kategori ini.
Memang, tidak semua yang kita lakukan di internet layak disimpan selamanya. Aneh (dan tidak efisien) menyimpan informasi seperti item di keranjang belanja pengguna atau halaman terakhir yang dikunjungi pengguna di aplikasi Anda. Meskipun informasi semacam ini mungkin berguna dalam jangka pendek, jangan biarkan I/O disk tanpa akhir merusak database yang sesuai dengan ACID yang diandalkan oleh bisnis kita. Untungnya ada hal kecil yang disebut RAM yang telah menangani skenario serupa sejak awal komputasi. Redis adalah basis data dalam memori yang menyimpan value sebagai pasangan key-value. Membaca dan menulis ke memori lebih cepat daripada menulis ke disk, jadi memori cocok untuk menyimpan data sekunder. Data ini memungkinkan kami untuk menjaga database tetap bersih sambil memberikan pengalaman pengguna yang lebih baik. Jika nanti Anda memutuskan bahwa menyimpan data dalam memori itu layak, Anda selalu dapat menulisnya nanti ke disk (seperti database SQL).
Penyimpanan data dalam memori seperti Redis atau Memcached berada di suatu tempat di arsitektur Anda antara aplikasi dan database Anda. Layanan ini harus dipertimbangkan sebagai alternatif untuk menyimpan informasi melalui cookie. Cookie terikat ke satu browser, dan semua pengguna dapat menghapus atau menonaktifkan cookie browser mereka kapan saja, sehingga Anda tidak dapat mengandalkannya untuk bekerja seperti yang diharapkan. Menyimpan data sesi di cloud menghilangkan masalah ini dengan manfaat tambahan berbagi data sesi di seluruh perangkat. Keranjang belanja pengguna sekarang dapat dilihat dari perangkat apa pun, bukan dari browser yang mereka gunakan saat itu.
Hari ini kita akan berkenalan dengan redis-py, paket go-to Redis Python. redis-py tidak nyaman disebut redis dalam Python, mungkin karena penulis redis-py suka memberikan rasa sakit. Kunjungi dokumentasi resmi redis-py untuk memeriksanya. Ini adalah satu halaman yang mencantumkan semua metode di perpustakaan dalam urutan abjad.
Jika Anda berencana untuk menggunakan Redis dengan kerangka web Python Anda, sebaiknya gunakan paket khusus framework (seperti Flask-Redis) daripada redis-py. Jangan khawatir: hampir semua pustaka Redis Python mengikuti sintaks yang tepat dari redis-py, dengan beberapa keuntungan kecil dari integrasi khusus framework. Semua hal berikut berlaku terlepas dari perpustakaan mana yang Anda gunakan.
Menyiapkan Redis
Jika Anda belum memiliki instans Redis, perwakilan Redis Labs menawarkan tingkat gratis yang murah hati untuk orang-orang seperti Anda dan saya yang kehilangan banyak uang. Mereka adalah host Redis yang sangat bereputasi baik. Mungkin karena kami menemukan Redis sejak awal. Setelah menyiapkan instans Anda, catat host, kata sandi, dan porta.
Cukup berbicara. Mari kita gali Python. Kamu tahu apa yang harus dilakukan:
pip install redis
Redis URIs
Seperti database reguler lainnya, Anda dapat terhubung ke instans Redis dengan membuat URI string koneksi. URI Redis yang sebenarnya terlihat seperti ini:
redis://:hostname.redislabs.com@mypassword:12345/0
Inilah yang terjadi sepotong demi sepotong:
[CONNECTION_METHOD]:[HOSTNAME]@[PASSWORD]:[PORT]/[DATABASE]
- CONNECTION_METHOD: Ini adalah akhiran di depan semua URI Redis yang menentukan cara terhubung ke instance.
redis://
adalah koneksi standar,redis://
(double S) mencoba terhubung melalui SSL.redis-socket://
dicadangkan untuk soket domain Unix. Ketersediaan kluster Redis... mungkin untuk orang yang tidak terlalu rusak dibandingkan kami. - HOSTNAME: URL atau IP instance Redis Anda. Jika Anda menggunakan instans yang dihosting di cloud, ini mungkin terlihat seperti alamat AWS EC2. Ini adalah efek samping kecil dari kapitalisme modern yang beralih ke model di mana setiap perusahaan adalah pengecer AWS dengan perangkat lunak yang telah dikonfigurasi sebelumnya.
- PASSWORD: Mesin virtual Redis Anda memiliki kata sandi tetapi tidak memiliki pengguna. Ini mungkin karena nama pengguna yang persisten pada dasarnya sulit dikelola di penyimpanan data berbasis memori.
- PORT: PORT yang Anda hubungi setelah menjarah seorang pedagang Inggris. Hanya untuk memastikan kau masih di sini.
- DATABASE: Jika Anda tidak tahu harus seperti apa, setel ke 0. Orang-orang melakukannya sepanjang waktu.
Buat Redis Client
Hebat, kami memiliki URI. Mari terhubung ke Redis dengan membuat objek Redis Client.
import redis
from config import redis_uri
r = redis.StrictRedis(url=redis_uri)
Mengapa StrictRedis Ada dua cara untuk membuat instance Redis Client: redis.Redis()
dan redis.StrictRedis()
. StrictRedis berusaha untuk menegakkan tipe data Redis dengan benar dengan cara yang tidak diterapkan dalam instans Redis yang lebih lama. redis.Redis()
kompatibel mundur dengan instance Redis lama dengan data sampah, sedangkan redis.StrictRedis()
tidak. Jika ragu, gunakan StrictRedis.
Ada banyak argumen lain yang dapat (dan harus) diteruskan ke redis.StrictRedis() untuk membuat hidup Anda lebih mudah. Melewati argumen kata key decode_responses=True sangat disarankan. Ini menghemat Anda harus secara eksplisit mendekode setiap value yang Anda ambil dari Redis. Mengatur charset tidak ada salahnya:
Bird-Eye view Untuk Redis
Penyimpanan key/value Redis adalah konsep yang mirip dengan kamus Python, jadi arti di balik namanya adalah layanan kamus jarak jauh. key selalu berupa string, tetapi ada beberapa tipe data yang dapat disimpan sebagai value. Mari isi instance Redis kita dengan beberapa catatan dan lihat lebih dekat cara kerja database Redis.
r.set('ip_address', '0.0.0.0')
r.set('timestamp', int(time.time()))
r.set('user_agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3)')
r.set('last_page_visited', 'account')
r.set([KEY], [VALUE])
adalah roti dan mentega untuk menyetel value tunggal. Ini terlihat sederhana. Parameter pertama adalah key pasangan dan parameter kedua adalah value yang diberikan ke key itu.
Seperti database biasa, Anda dapat terhubung ke instans Redis melalui GUI seperti TablePlus dan memeriksa data. Setelah menjalankan potongan di atas database terlihat seperti ini:
Kedengarannya seperti semuanya berjalan lancar. Anda dapat mempelajari sedikit tentang Redis hanya dengan melihat tabel ini. Mari kita mulai dengan kolom tipe.
tipe data Redis
value yang disimpan di Redis dapat berupa salah satu dari lima tipe data:
- STRING: Semua value yang dibuat dengan
r.set()
disimpan sebagai tipe string. Anda akan melihat bahwa skrip Python menyetel value stempel waktu ke bilangan bulat, tetapi di sini ditampilkan sebagai string. Ini mungkin tampak sangat merepotkan. String di Redis lebih dari yang terlihat. Pertama, string Redis aman untuk biner. Ini berarti dapat digunakan untuk menyimpan hampir semua konten, termasuk gambar dan objek berseri. String juga memiliki beberapa fungsi bawaan yang memungkinkan Anda memanipulasi string seolah-olah itu adalah angka, seperti menambahkannya dengan perintah INC. - LIST: Daftar Redis adalah larik string yang dapat dimodifikasi, setiap string diurutkan dalam urutan kejadian pertama. Setelah daftar dibuat, item baru dapat ditambahkan ke akhir array menggunakan perintah RPUSH, atau pada indeks nol menggunakan perintah LPUSH. Anda juga dapat menggunakan perintah LTRIM untuk membatasi jumlah maksimum item dalam daftar. Jika Anda adalah tipe geek yang suka membuat cache LRU dan semacamnya, Anda akan segera melihat manfaatnya.
- SET: Satu set adalah daftar string yang tidak diurutkan. Seperti set Python, set Redis tidak dapat berisi duplikat. Kumpulan memiliki kemampuan unik untuk melakukan penggabungan atau persimpangan antara kumpulan lainnya, menjadikannya cara yang bagus untuk menggabungkan atau membandingkan data dengan cepat.
- ZSET: Tetap dengan saya di sini ... ZSET adalah set yang dipesan dan menjaga batasan yang sama dengan tidak mengizinkan duplikat. Item dalam daftar dapat diurutkan ulang setelah dibuat, jadi ZSET sangat berguna untuk memeringkat item unik. Ini seperti kamus terurut Python, kecuali untuk key per value (yang tidak diperlukan karena semua value yang ditetapkan unik).
- HASH: Redis hash itu sendiri adalah pasangan value key, dan kumpulan pasangan value key dapat ditetapkan sebagai value pasangan value key. Hash tidak dapat disarangkan.
Kedaluwarsa data
Basis data Redis berisi kolom keempat berlabel ttl. Sejauh ini, value kolom ini untuk setiap baris adalah -1. Jika angka ini disetel ke bilangan bulat positif, ini menunjukkan jumlah detik yang tersisa sebelum data kedaluwarsa. Saya telah menetapkan bahwa Redis adalah cara yang bagus untuk menyimpan sementara data yang berguna, tetapi biasanya tidak layak disimpan. Di sini berguna untuk menetapkan tanggal kedaluwarsa pada value baru. Ini secara otomatis memastikan bahwa memori instance tidak macet dengan informasi yang tidak diperlukan lagi.
Mari kembali ke contoh kami menyimpan informasi sesi pengguna dan menetapkan value dengan tanggal kedaluwarsa.
...
r.set('last_page_visited', 'account', 86400)
Kali ini kita meneruskan value ketiga ke r.set(). Ini mewakili jumlah detik pasangan akan disimpan sebelum penghancuran diri. Mari kita periksa databasenya.
Jika Anda menggunakan GUI untuk me-refresh tabel secara berkala, Anda akan melihat bahwa angka ini sebenarnya menghitung mundur.
Operasi pada setiap tipe data
Saya yakin Anda suka mendengar saya dengung, tetapi kami tahu mengapa Anda ada di sini: untuk menyalin dan menempelkan kode yang Anda perlukan untuk pekerjaan sehari-hari. Berikut adalah beberapa lembar contekan yang menunjukkan kasus penggunaan umum saat bekerja dengan masing-masing Redis lima tipe data.
string
Jika string berisi value integer, ada banyak metode yang dapat digunakan untuk memodifikasi string seolah-olah merupakan integer. Lihat cara menggunakan .incr(), .decr() dan .incrby() di sini.
# Create string value
r.set('index', '1')
logger.info(f"index: {r.get('index')}")
# Increment string by 1
r.incr('index')
logger.info(f"index: {r.get('index')}")
# Decrement string by 1
r.decr('index')
logger.info(f"index: {r.get('index')}")
# Increment string by 3
r.incrby('index', 3)
logger.info(f"index: {r.get('index')}")
Ini memberikan value "1" ke indeks, menambah value indeks dengan 1, mengurangi value indeks dengan 1, dan akhirnya menambah value indeks dengan 3.
index: 1
index: 2
index: 1
index: 4
daftar
Di bawah ini kami menggunakan kombinasi .lpush() dan .rpush() untuk menambahkan item ke daftar Redis dan .lpop() untuk mengeluarkan item. Anda tahu, daftar hal-hal yang khas:
r.lpush('my_list', 'A')
logger.info(f"my_list: {r.lrange('my_list', 0, -1)}")
# Push second string to list from the right.
r.rpush('my_list', 'B')
logger.info(f"my_list: {r.lrange('my_list', 0, -1)}")
# Push third string to list from the right.
r.rpush('my_list', 'C')
logger.info(f"my_list: {r.lrange('my_list', 0, -1)}")
# Remove 1 instance from the list where the value equals 'C'.
r.lrem('my_list', 1, 'C')
logger.info(f"my_list: {r.lrange('my_list', 0, -1)}")
# Push a string to our list from the left.
r.lpush('my_list', 'C')
logger.info(f"my_list: {r.lrange('my_list', 0, -1)}")
# Pop first element of our list and move it to the back.
r.rpush('my_list', r.lpop('my_list'))
logger.info(f"my_list: {r.lrange('my_list', 0, -1)}")
Daftar setelah setiap perintah terlihat seperti ini:
my_list: ['A']
my_list: ['A', 'B']
my_list: ['A', 'B', 'C']
my_list: ['A', 'B']
my_list: ['C', 'A', 'B']
my_list: ['A', 'B', 'C']
mengatur
Set di Redis sangat kuat, sebagian karena dapat berinteraksi dengan set lainnya. Di bawah ini saya membuat dua set terpisah dan menjalankan .sunion()
dan .sinter()
pada keduanya.
# Add item to set 1
r.sadd('my_set_1', 'Y')
logger.info(f"my_set_1: {r.smembers('my_set_1')}'")
# Add item to set 1
r.sadd('my_set_1', 'X')
logger.info(f"my_set_1: {r.smembers('my_set_1')}'")
# Add item to set 2
r.sadd('my_set_2', 'X')
logger.info(f"my_set_2: {r.smembers('my_set_2')}'")
# Add item to set 2
r.sadd('my_set_2', 'Z')
logger.info(f"my_set2: {r.smembers('my_set_2')}'")
# Union set 1 and set 2
logger.info(f"Union: {r.sunion('my_set_1', 'my_set_2')}")
# Interset set 1 and set 2
logger.info(f"Intersect: {r.sinter('my_set_1', 'my_set_2')}")
Seperti yang diharapkan, serikat menggabungkan set tanpa duplikat, dan persimpangan menemukan value yang umum untuk kedua set.
my_set_1: {'Y'}'
my_set_1: {'X', 'Y'}'
my_set_2: {'X'}'
my_set2: {'X', 'Z'}'
Union: {'X', 'Z', 'Y'}
Intersect: {'X'}
himpunan terurut
Menambahkan catatan ke set yang diurutkan menggunakan .zadd()
memiliki sintaks yang sedikit lebih menarik. Perhatikan bahwa menambahkan kumpulan rekaman yang diurutkan memerlukan kamus dalam bentuk {[VALUE]: [INDEX]}.
# Initialize sorted set with 3 values
r.zadd('top_songs_set', {'Never Change - Jay Z': 1,
'Rich Girl - Hall & Oats': 2,
'The Prayer - Griz': 3})
logger.info(f"top_songs_set: {r.zrange('top_songs_set', 0, -1)}'")
# Add item to set with conflicting value
r.zadd('top_songs_set', {'Can\'t Figure it Out - Bishop Lamont': 3})
logger.info(f"top_songs_set: {r.zrange('top_songs_set', 0, -1)}'")
# Shift index of a value
r.zincrby('top_songs_set', 3, 'Never Change - Jay Z')
logger.info(f"top_songs_set: {r.zrange('top_songs_set', 0, -1)}'")
Item dalam kumpulan yang disortir tidak dapat berbagi indeks yang sama, jadi mencoba memasukkan value ke dalam indeks di mana value sudah ada akan mendorong value yang ada (dan value berikutnya) ke bawah untuk memberi ruang. Anda juga dapat mengubah indeks value setelah membuatnya.
top_songs_set: ['Never Change - Jay Z',
'Rich Girl - Hall & Oats',
'The Prayer - Griz']
top_songs_set: ['Never Change - Jay Z',
'Rich Girl - Hall & Oats',
'Can\'t Figure it Out - Bishop Lamont',
'The Prayer - Griz']
top_songs_set: ['Rich Girl - Hall & Oats',
'Can\'t Figure it Out - Bishop Lamont',
The Prayer - Griz',
'Never Change - Jay Z']
hash
Oke, saya tidak melakukan sesuatu yang menarik dengan hash. menuntutku Tetap saja, agak keren untuk membuat dan mengambil value hash, bukan?
record = {
"name": "Hackers and Slackers",
"description": "Mediocre tutorials",
"website": "https://hackersandslackers.com/",
"github": "https://github.com/hackersandslackers"
}
r.hmset('business', record)
logger.info(f"business: {r.hgetall('business')}")
Outputnya persis sama dengan inputnya...tidak ada kejutan di sana:
business: {'name': 'Hackers and Slackers',
'description': 'Mediocre tutorials',
'website': 'https://hackersandslackers.com/',
'github': 'https://github.com/hackersandslackers'}
Maju terus
Ada banyak fitur Redis dan redis-py
yang belum kami jelajahi, tetapi Anda harus memiliki lebih dari cukup untuk memulai. Lebih penting lagi, semoga tutorial ini memiliki beberapa bagian dalam mendemonstrasikan mengapa Redis dapat berguna di tumpukan Anda… atau tidak!Jika saya dapat mengklaim bagian apa pun dalam mencegah arsitektur sistem yang buruk, itu adalah kemenangan.