Redis gebruiken met Python is een krachtige combinatie voor data engineers die high-performance, schaalbare en onderhoudbare systemen willen bouwen. Of je nu caching-lagen optimaliseert, real-time eventstreams beheert of gedistribueerde locking implementeert, Redis biedt een flexibele en efficiënte oplossing.
In deze gids behandelen we de basis van Redis met Python, zodat je het naadloos kunt integreren in je data engineering-workflows.
Wat is Python Redis?
Redis is een open-source, in-memory datastore voor datastructuren die wordt gebruikt als database, cache en message broker. Het staat voor Remote Dictionary Server en is oorspronkelijk ontworpen als een key-value-opslagsysteem met snelle toegangstijden.
Het ondersteunt diverse datastructuren zoals strings, hashes, lijsten, sets en gesorteerde sets met range-queries. Redis biedt ook geavanceerde functies zoals transacties, pub/sub-messaging, Lua-scripting en ingebouwde replicatie- en clustermogelijkheden voor betere beschikbaarheid en schaalbaarheid.
Veelvoorkomende Redis-usecases
De mogelijke usecases voor Redis zijn talrijk en gevarieerd.
Enkele van de meest voorkomende usecases in data engineering zijn:
Caching: Versnel databasequery's en API-responses.
Message queues: Ondersteun event-driven architecturen en jobverwerkingspipelines.
Real-time analytics: Verwerk en analyseer streamingdata met minimale latency.
Leaderboards: Rangschik en haal topscores efficiënt op.
Sessie-opslag: Beheer sessiestatus snel en schaalbaar.
Jobqueuebeheer: Zorg voor efficiënte taakplanning en -uitvoering.
Geospatiale indexering: Sla locatiegegevens op en bevraag ze.
Redis wordt ook vaak gebruikt in combinatie met andere technologieën zoals webservers (bijv. NGINX), databases (bijv. MySQL) en messaging-systemen (bijv. Kafka) om prestaties en schaalbaarheid te optimaliseren.
Waarom Redis met Python gebruiken?
Python is een toonaangevende taal in data engineering dankzij de flexibiliteit, het uitgebreide ecosysteem en de eenvoudige integratie met bigdatatechnologieën.
De combinatie met Redis kan veel voordelen opleveren voor je applicaties:
Snelle prestaties: Omdat Redis data in het geheugen opslaat, biedt het aanzienlijk snellere toegangstijden dan traditionele databases die gegevens op schijf opslaan. Dit maakt het ideaal voor usecases die hoge prestaties vereisen, zoals caching en real-time apps.
Schaalbaarheid: Redis is ontworpen met schaalbaarheid in gedachten, waardoor je grote hoeveelheden data kunt verwerken zonder prestatiedaling.
Gebruiksgemak: Door de eenvoudige syntax en het rijke bibliotheek-ecosysteem is het in Python gemakkelijk werken met Redis. De officiële Redis-py clientbibliotheek biedt bovendien een gebruiksvriendelijke interface om vanuit je Python-code met Redis te communiceren.
Wat is Redis-py?
Redis-py is de officiële Redis-clientbibliotheek voor Python. Het biedt een gebruiksvriendelijke interface om vanuit je Python-code met Redis te communiceren.
Enkele van de belangrijkste functies zijn:
Ondersteuning voor alle Redis-datatypen
Pipelines en transacties voor efficiënte en atomaire operaties
Ondersteuning voor pub/sub-messaging
Automatische encodering/decodering van data naar/van bytes, strings en andere Python-typen
Clustermodusondersteuning voor werken met Redis-clusters
Redis instellen voor Python-ontwikkeling
Laten we bekijken hoe we Redis kunnen opzetten met Python.
Er zijn drie hoofdmanieren om Redis te laten draaien:
docker pull redis downloadt de nieuwste officiële Redis-image. docker run --name my-redis -p 6379:6379 -d redis start een nieuwe container met de naam my-redis. De parameter -p 6379:6379 koppelt poort 6379 van je lokale machine aan poort 6379 van de container, zodat je op localhost:6379 met Redis kunt verbinden. De vlag -d draait de container op de achtergrond (detached mode).
Vervolgens moet je de redis-py-bibliotheek installeren om via Python toegang te krijgen tot de database. Zorg ervoor dat zowel Python als Redis afzonderlijk zijn geïnstalleerd voordat je de bibliotheek installeert.
Deze opdracht downloadt en installeert de Python Redis-clientbibliotheek (redis-py) van PyPI. Als je een virtual environment gebruikt, activeer die dan voordat je deze opdracht uitvoert.
Dit zou een versienummer moeten printen (bijv. 5.2.1).
Een Redis-server instellen
Als je een van de bovenstaande methoden (Docker, WSL of een third-party build) hebt gevolgd, zou je nu een Redis-server hebben draaien op localhost:6379. Dat is voldoende voor lokale ontwikkeling op Windows.
Werken met Redis-datastructuren
Hieronder staan Python-voorbeelden die laten zien hoe je verbinding maakt met en verschillende Redis-datatypen bewerkt. Elk codeblok bevat toelichtende comments over hoe de methoden of opdrachten werken.
Strings in Redis
import redis
# Instantiate a Redis client, connecting to localhost on port 6379
r = redis.Redis(
host='localhost',
port=6379,
db=0# The default Redis database index)# 1. SET command: store a string under 'mykey'
r.set("mykey","hello from Windows")# 2. GET command: retrieve the value stored at 'mykey'
value = r.get("mykey")print(value)# Output is b'hello from Windows', since redis-py returns bytes.# 3. Convert bytes to stringprint(value.decode())# prints "hello from Windows"# 4. DEL command: remove 'mykey' from Redis
r.delete("mykey")Mogelijk gemaakt door
We maken een Redis-object dat verbinding maakt met de lokale Redis-server.
r.set("mykey", "hello from Windows") slaat de string "hello from Windows" op onder de sleutel "mykey".
r.get("mykey") haalt de waarde op die in mykey is opgeslagen. Redis retourneert bytes, dus we decoderen het voor leesbare output.
r.delete("mykey") verwijdert de sleutel mykey volledig.
Voorbeeld: gebruikerssessies opslaan en ophalen
Hier is een codevoorbeeld voor sessiebeheer van gebruikers:
import uuid
defstore_user_session(user_id):"""
Generates a unique session token (UUID) for a user and stores it in Redis.
The session is stored under the key pattern: user:{user_id}:session
"""
session_key =f"user:{user_id}:session"
token =str(uuid.uuid4())# Generate a random UUID as a session token
r.set(session_key, token)# Store token in Redisreturn token
defget_user_session(user_id):"""
Retrieves the stored session token for the given user_id.
Returns None if the session does not exist or is expired.
"""
session_key =f"user:{user_id}:session"
token = r.get(session_key)return token.decode('utf-8')if token elseNonedefdelete_user_session(user_id):"""
Deletes the session entry from Redis for the specified user_id.
"""
session_key =f"user:{user_id}:session"
r.delete(session_key)# Usage demonstration
session_token = store_user_session(1001)print(f"Stored session token: {session_token}")
retrieved_token = get_user_session(1001)print(f"Retrieved session token: {retrieved_token}")
delete_user_session(1001)print(f"Session after delete: {get_user_session(1001)}")# Should be None or emptyMogelijk gemaakt door
store_user_session(user_id): maakt een wereldwijd unieke ID via uuid.uuid4() en slaat die op onder een gebruikersspecifieke sleutel. get_user_session(user_id): leest de sessietoken terug. Als None, ontbreekt de sessie of is deze verlopen. delete_user_session(user_id): verwijdert de sessiesleutel uit Redis en logt de gebruiker effectief uit.
Lijsten in Redis
Redis-lijsten zijn geordende reeksen van strings. Je kunt aan beide uiteinden bewerkingen uitvoeren, wat ze handig maakt voor queues, stacks of logs.
# LPUSH: Push an element to the head (left) of the list
r.lpush("task_queue","task1")# RPUSH: Push an element to the tail (right) of the list
r.rpush("task_queue","task2")
r.rpush("task_queue","task3")# LPOP: Pop (remove and return) the element at the head
task = r.lpop("task_queue")print(task)# b'task1'# Optional: RPOP removes and returns the element at the tail
task = r.rpop("task_queue")print(task)# b'task3'Mogelijk gemaakt door
lpush("task_queue", "task1") voegt "task1" toe aan de linkerkant van een lijst genaamd "task_queue". rpush("task_queue", "task2") en rpush("task_queue", "task3") voegen taken toe aan de rechterkant. lpop("task_queue") and rpop("task_queue") verwijderen en retourneren items van respectievelijk het begin en het einde van de lijst.
Voorbeeld: een eenvoudige Redis-queue
defenqueue_task(queue_name, task):"""
Appends a task to the end (right) of the Redis list named queue_name.
"""
r.rpush(queue_name, task)defdequeue_task(queue_name):"""
Removes a task from the front (left) of the Redis list named queue_name.
Returns the task as a string, or None if the queue is empty.
"""
task = r.lpop(queue_name)return task.decode('utf-8')if task elseNone# Example usage:
enqueue_task("my_queue","send_email")
enqueue_task("my_queue","generate_report")whileTrue:
task = dequeue_task("my_queue")ifnot task:print("No more tasks in queue.")breakprint(f"Processing task: {task}")Mogelijk gemaakt door
enqueue_task voegt altijd nieuwe taken toe aan het einde van de lijst en simuleert zo een traditionele FIFO-queue. dequeue_task verwijdert taken van voren. Als de lijst leeg is, retourneert hij None.
De while-loop verwerkt taken totdat de queue leeg is en stopt dan.
Hashes in Redis
Hashes lijken op Python-dictionaries maar worden in Redis opgeslagen. Ze zijn ideaal om gerelateerde velden te groeperen (bijv. gebruikersgegevens).
# HSET: Store 'name' and 'email' fields for a user hash key
r.hset("user:1001","name","Alice")
r.hset("user:1001","email","[email protected]")# HGET: Retrieve a single field from the hash
email = r.hget("user:1001","email")print(email.decode('utf-8'))# [email protected]# HDEL: Remove a field from the hash
r.hdel("user:1001","email")Mogelijk gemaakt door
hset("user:1001", "name", "Alice") zet het veld "name" op de waarde "Alice" binnen de hash met sleutel "user:1001". hget("user:1001", "email") haalt het veld "email" op. hdel("user:1001", "email") verwijdert het veld "email" uit die hash.
Voorbeeld: gestructureerde gebruikersprofielen opslaan en benaderen
defcreate_user_profile(user_id, name, email):"""
Creates a user profile in Redis under the key 'user:{user_id}'.
'name' and 'email' are stored as separate fields in the hash.
"""
user_key =f"user:{user_id}"
r.hset(user_key, mapping={"name": name,"email": email})defget_user_profile(user_id):"""
Retrieves and returns all fields in the user profile hash
as a Python dictionary. Keys and values are decoded from bytes.
"""
user_key =f"user:{user_id}"
profile_data = r.hgetall(user_key)return{k.decode('utf-8'): v.decode('utf-8')for k, v in profile_data.items()}defdelete_user_profile(user_id):"""
Deletes the entire user profile key from Redis.
"""
user_key =f"user:{user_id}"
r.delete(user_key)# Usage demonstration
create_user_profile(1002,"Bob","[email protected]")print(get_user_profile(1002))# e.g. {'name': 'Bob', 'email': '[email protected]'}
delete_user_profile(1002)Mogelijk gemaakt door
We slaan de naam en e-mail van een gebruiker op in een hash. mapping={"name": name, "email": email} gebruikt de mogelijkheid van redis-py om meerdere velden tegelijk te zetten. r.hgetall(user_key) haalt alle velden en waarden op, geretourneerd als een dictionary van ruwe bytes die we naar strings decoderen. delete_user_profile verwijdert de gehele hash-sleutel.
Sets en gesorteerde sets
Data in Redis kan worden beheerd met sets of gesorteerde sets.
Sets zijn verzamelingen van unieke waarden, terwijl gesorteerde sets verzamelingen zijn van waarden met bijbehorende scores. Deze datastructuren bieden efficiënte manieren om data op te slaan en op te halen, wat ze nuttig maakt voor toepassingen die snelle lookups vereisen.
Sets
Een set in Redis is vergelijkbaar met een wiskundige set: een verzameling unieke elementen, zonder duplicaten. Sets kunnen worden gebruikt om relaties te modelleren, bijvoorbeeld gebruikers die een bericht leuk vonden op sociale media.
Hier is een demonstratie van sets:
# SADD: Add multiple members to a set
r.sadd("tags:python","redis","windows","backend")# SMEMBERS: Retrieve all unique members in the set
tags = r.smembers("tags:python")print(tags)# {b'redis', b'windows', b'backend'}Mogelijk gemaakt door
Redis-sets garanderen uniciteit van leden. Een poging om een duplicaat toe te voegen heeft geen effect.
Het resultaat van smembers is een Python-set van bytes.
Gesorteerde sets
Gesorteerde sets in Redis lijken op gewone sets, maar elk lid heeft ook een bijbehorende score. Dit maakt efficiënte sorteer- en rangschikbewerkingen mogelijk.
Gesorteerde sets worden vaak gebruikt voor leaderboards, waarbij de score de rang of punten van een speler vertegenwoordigt.
Hier is een demonstratie van gesorteerde sets:
# ZADD: Add members with scores
r.zadd("leaderboard",{"player1":10,"player2":20})# ZRANGE: Retrieve members in ascending order of score
leaders = r.zrange("leaderboard",0,-1, withscores=True)print(leaders)# [(b'player1', 10.0), (b'player2', 20.0)]Mogelijk gemaakt door
Gesorteerde sets bewaren leden in een specifieke volgorde bepaald door hun numerieke scores. zrange("leaderboard", 0, -1, withscores=True) retourneert alle leden van rang 0 tot het einde, inclusief hun scores.
Voorbeeld: tags of leaderboards beheren
Het gebruik van gesorteerde sets kan handig zijn bij het beheren van tags of het maken van leaderboards.
defadd_tag(post_id, tag):"""
Adds a 'tag' to the set of tags belonging to a specific post.
Each post has its own set under 'post:{post_id}:tags'.
"""
r.sadd(f"post:{post_id}:tags", tag)defget_tags(post_id):"""
Retrieves all tags for a specific post, decoding the bytes into strings.
"""
raw_tags = r.smembers(f"post:{post_id}:tags")return{tag.decode('utf-8')for tag in raw_tags}defupdate_leaderboard(player, score):"""
Updates or inserts a player's score in the 'game:leaderboard' sorted set.
A higher score indicates a better position if sorting descending.
"""
r.zadd("game:leaderboard",{player: score})defget_leaderboard():"""
Returns an ascending list of (player, score) tuples from the leaderboard.
To invert the sorting (highest first), you'd use ZREVRANGE.
"""
entries = r.zrange("game:leaderboard",0,-1, withscores=True)return[(player.decode('utf-8'), score)for player, score in entries]# Usage demonstration
add_tag(123,"python")
add_tag(123,"redis")print(get_tags(123))
update_leaderboard("Alice",300)
update_leaderboard("Bob",450)print(get_leaderboard())Mogelijk gemaakt door
add_tag en get_tags demonstreren een one-to-many-tagging-systeem met opslag in een Set. update_leaderboard en get_leaderboard laten zien hoe je een game-leaderboard kunt implementeren.
Redis-functies in Python-applicaties
Redis heeft verschillende functies die het populair maken voor dataopslag in Python-applicaties: queueing, locking en caching.
Hieronder zie je de implementaties in Python:
Redis als queue (met blocking)
Laten we Redis als queue met blocking verkennen met BLPOP.
BLPOP is een blokkerende operatie die wacht tot er een element beschikbaar is in een lijst.
defblocking_consumer(queue_name):"""
Continuously listens to the specified queue (Redis list) using BLPOP,
which blocks until new items are pushed. Once an item arrives,
it is removed from the queue and processed.
"""print(f"Waiting on queue: {queue_name}")whileTrue:
result = r.blpop(queue_name)if result:
list_name, task_bytes = result
task = task_bytes.decode('utf-8')print(f"Received task: {task}")else:print("Queue is empty or an error occurred.")breakdefenqueue_task(queue_name, task):"""
Pushes a task to the end of a Redis list (queue).
"""
r.rpush(queue_name, task)# Example usage:
enqueue_task("blocking_queue","task_block_1")
enqueue_task("blocking_queue","task_block_2")# In a real application, the consumer might run in a separate thread or process
blocking_consumer("blocking_queue")Mogelijk gemaakt door
blocking_consumer gebruikt blpop in een lus. Als de lijst leeg is, wacht blpop tot er een nieuw item wordt gepusht.
Zodra een item is ontvangen, wordt het uit de lijst verwijderd en geprint.
Deze aanpak is ideaal voor producer-consumerpatronen waarbij workers taken verwerken zodra ze verschijnen.
Locks implementeren in Redis
Gedistribueerde locks voorkomen dat meerdere clients of processen tegelijk dezelfde resource wijzigen. Redis helpt race conditions te vermijden in een gedistribueerde omgeving.
import time
from redis.exceptions import LockError
defprocess_critical_section():"""
Acquires a lock named 'resource_lock' with a timeout of 10 seconds.
The lock automatically expires after 10 seconds to prevent deadlocks.
"""
lock = r.lock("resource_lock", timeout=10)try:# Attempt to acquire the lock, wait for up to 5 seconds if another process holds it
acquired = lock.acquire(blocking=True, blocking_timeout=5)if acquired:print("Lock acquired; performing critical operation...")
time.sleep(3)# Simulate some operationelse:print("Failed to acquire lock within 5 seconds.")except LockError:print("A LockError occurred, possibly releasing already released lock.")finally:# Always release the lock in a finally block to ensure cleanup
lock.release()print("Lock released.")# Usage demonstration
process_critical_section()Mogelijk gemaakt door
We maken een lock met timeout=10, wat betekent dat als de lock niet handmatig wordt vrijgegeven, Redis deze na 10 seconden automatisch verwijdert om onbeperkte blokkering (deadlock) te voorkomen. lock.acquire(blocking=True, blocking_timeout=5) probeert de lock gedurende 5 seconden te verkrijgen voordat wordt opgegeven. Na afloop geeft lock.release() de resource vrij voor andere processen.
Cachen met Redis
Caching is een veelvoorkomend scenario: sla vaak geraadpleegde data in het geheugen op om de belasting van databases of externe API's te verminderen.
import requests
import json
defget_user_data(user_id):"""
Retrieves user data from a hypothetical API endpoint.
If the data is found in Redis (cache), use that. Otherwise, call the API,
store the response in Redis with a 60-second expiration, and return it.
"""
cache_key =f"user_data:{user_id}"
cached_data = r.get(cache_key)if cached_data:print("Cache hit!")return json.loads(cached_data)print("Cache miss. Fetching from API...")
response = requests.get(f"https://api.example.com/users/{user_id}")
user_info = response.json()# Store in Redis for 60 seconds
r.setex(cache_key,60, json.dumps(user_info))return user_info
# Usage
user = get_user_data(42)# First call => cache miss
user_again = get_user_data(42)# Subsequent call => cache hitMogelijk gemaakt door
We controleren of user_data:{user_id} in Redis bestaat. Zo ja, dan is dat een cache hit en slaan we de API-call over. Zo niet, dan halen we de data op bij de externe API en gebruiken we setex (set + vervaldatum) voor 60 seconden. Latere aanroepen binnen dat tijdsframe halen de gecachte data op en verlagen de latency.
Geavanceerde onderwerpen in Redis
Denk je dat je Redis al onder de knie hebt? Laten we enkele geavanceerdere onderwerpen doornemen.
Pub/Sub gebruiken met Redis
Pub/Sub (Publish/Subscribe) is een populair messagingpatroon voor realtime-communicatie. Publishers sturen berichten naar een kanaal, en alle subscribers van dat kanaal ontvangen die berichten.
import threading
defsubscriber(r, channel_name):"""
Subscribes to the given Redis channel and listens for messages.
When a new message is published on that channel, it is printed.
"""
pubsub = r.pubsub()
pubsub.subscribe(channel_name)print(f"Subscribed to {channel_name}")# pubsub.listen() yields messages from the subscribed channel(s) in real timefor message in pubsub.listen():if message['type']=='message':print(f"Received message: {message['data'].decode('utf-8')}")defpublisher(r, channel_name, message):"""
Publishes a message to the specified Redis channel.
All subscribers to this channel immediately receive the message.
"""
r.publish(channel_name, message)# Example usage
channel ="updates"# Start subscriber in a separate thread to avoid blocking the main thread
sub_thread = threading.Thread(target=subscriber, args=(r, channel))
sub_thread.start()# Publish messages
publisher(r, channel,"Hello from Windows!")
publisher(r, channel,"Another update!")Mogelijk gemaakt door
pubsub = r.pubsub() maakt een PubSub-object. pubsub.subscribe(channel_name) instrueert Redis om berichten van dat kanaal naar het PubSub-object te sturen. pubsub.listen() is een oneindige iterator die berichten oplevert zodra ze binnenkomen. r.publish(channel_name, message) stuurt een bericht naar alle abonnees van channel_name.
Sleutels laten verlopen in Redis
Redis ondersteunt time-to-live (TTL). Dit is essentieel voor tijdelijke data zoals sessies of kortlevende caches.
# EXPIRE: Set a 30-second expiration on a key
r.set("temp_key","some value")
r.expire("temp_key",30)# SETEX: Combined set + expire in one command
r.setex("temp_key2",60,"another value")Mogelijk gemaakt door
r.expire("temp_key", 30) zet een TTL van 30 seconden. Na 30 seconden wordt temp_key automatisch verwijderd. r.setex("temp_key2", 60, "another value") is een snelkoppeling die de sleutel én de vervaldatum in één keer zet.
Voorbeeld: sessieverval
Hier is een voorbeeld van hoe je sleutels met een vervaltijd kunt gebruiken om een sessie te laten verlopen na een opgegeven duur.
defstore_session_with_expiry(user_id, token, ttl=3600):"""
Stores a session token for a specific user with a time-to-live (TTL).
By default, the session expires after 1 hour (3600 seconds).
"""
session_key =f"user:{user_id}:session"
r.setex(session_key, ttl, token)defget_session_with_expiry(user_id):"""
Retrieves the session token for the user. Returns None if the key doesn't exist
or if it has expired.
"""
session_key =f"user:{user_id}:session"
token = r.get(session_key)return token.decode('utf-8')if token elseNone# Usage
store_session_with_expiry(2001,"session_token_abc",3600)
retrieved_token = get_session_with_expiry(2001)print(f"Retrieved token: {retrieved_token}")Mogelijk gemaakt door
store_session_with_expiry gebruikt onder de motorkap setex om user:{user_id}:session met een opgegeven TTL op te slaan. Als je geen TTL doorgeeft, kan de sleutel onbeperkt blijven bestaan.
Wanneer de TTL verloopt, verwijdert Redis de sleutel automatisch, waardoor de sessie niet meer kan worden opgehaald.
Best practices voor het gebruik van Redis met Python
Werken met Redis vraagt om enkele aandachtspunten en best practices om optimale prestaties te waarborgen en valkuilen te vermijden.
Enkele tips om in gedachten te houden:
Configureer persistentie-opties goed voor datasafety.
Monitor het geheugengebruik om out-of-memory-fouten te voorkomen.
Gebruik pipelining voor efficiënte batchoperaties.
Let op netwerklatency, omdat dit de prestaties kan beïnvloeden bij werken met een externe Redis-server.
Beveilig Redis-verbindingen met wachtwoorden en firewalls.
Conclusie
Redis is een krachtig en veelzijdig hulpmiddel voor databeheer in Python-applicaties. Python met Redis kan veel toepassingen en usecases mogelijk maken, van het cachen van data tot het beheren van queues.
Wil je meer leren over Redis? Onze Introduction to NoSQL-cursus helpt je omgaan met key-value-data. Liever Python? Dan is onze Python Data Fundamentals skill track een goed startpunt.
Python Redis FAQ's
Waarom Python gebruiken voor Redis?⌄
Python is een veelzijdige en populaire programmeertaal waarmee je data efficiënt en eenvoudig kunt manipuleren, wat het een ideale keuze maakt voor het werken met Redis-databases.
Kan ik naast Python ook andere talen gebruiken met Redis?⌄
Ja, Redis ondersteunt meerdere talen zoals Java, JavaScript, PHP en meer. Python staat echter bekend om zijn eenvoud en flexibiliteit bij het werken met Redis.
Is Redis moeilijk te leren voor een beginner?⌄
Hoewel er in het begin een leercurve kan zijn, maakt de duidelijke syntax van Python het relatief eenvoudig om op te pikken. Bovendien zijn er online veel bronnen beschikbaar om beginners te helpen Redis te leren.
Wat kan ik doen met Python en Redis? ⌄
Met Python en Redis kun je allerlei taken uitvoeren, zoals datamanipulatie, caching, messaging en meer. Je kunt Redis ook integreren met andere tools en technologieën om je applicaties te versterken.
Wat zijn praktische usecases voor het samen gebruiken van Python en Redis?⌄
Veelvoorkomende usecases zijn real-time analytics, sessiebeheer, taakqueues en databasecaching. Daarnaast kun je met Python en Redis schaalbare webapplicaties, chatbots en machinelearningmodellen bouwen.
Ik ben Austin, een blogger en techschrijver met jarenlange ervaring als zowel datascientist als data-analist in de gezondheidszorg. Ik begon mijn techreis met een achtergrond in biologie en help nu anderen dezelfde overstap te maken via mijn techblog. Mijn passie voor technologie heeft geleid tot schrijfbijdragen aan tientallen SaaS-bedrijven, waarmee ik anderen inspireer en mijn ervaringen deel.
Leer de vaardigheden die je nodig hebt om data efficiënt te verzamelen, op te schonen en te beheren, en om pijplijnen te plannen en te monitoren, zodat je je kunt onderscheiden op het gebied van data-engineering.
Duik diep in geavanceerde vaardigheden en de nieuwste tools die de wereld van data-engineering nu op z'n kop zetten met ons Professional Data Engineer-traject.
Redis gebruiken met Python is een krachtige combinatie voor data engineers die high-performance, schaalbare en onderhoudbare systemen willen bouwen. Of je nu caching-lagen optimaliseert, real-time eventstreams beheert of gedistribueerde locking implementeert, Redis biedt een flexibele en efficiënte oplossing.
In deze gids behandelen we de basis van Redis met Python, zodat je het naadloos kunt integreren in je data engineering-workflows.
Wat is Python Redis?
Redis is een open-source, in-memory datastore voor datastructuren die wordt gebruikt als database, cache en message broker. Het staat voor Remote Dictionary Server en is oorspronkelijk ontworpen als een key-value-opslagsysteem met snelle toegangstijden.
Het ondersteunt diverse datastructuren zoals strings, hashes, lijsten, sets en gesorteerde sets met range-queries. Redis biedt ook geavanceerde functies zoals transacties, pub/sub-messaging, Lua-scripting en ingebouwde replicatie- en clustermogelijkheden voor betere beschikbaarheid en schaalbaarheid.
Veelvoorkomende Redis-usecases
De mogelijke usecases voor Redis zijn talrijk en gevarieerd.
Enkele van de meest voorkomende usecases in data engineering zijn:
Redis wordt ook vaak gebruikt in combinatie met andere technologieën zoals webservers (bijv. NGINX), databases (bijv. MySQL) en messaging-systemen (bijv. Kafka) om prestaties en schaalbaarheid te optimaliseren.
Waarom Redis met Python gebruiken?
Python is een toonaangevende taal in data engineering dankzij de flexibiliteit, het uitgebreide ecosysteem en de eenvoudige integratie met bigdatatechnologieën.
De combinatie met Redis kan veel voordelen opleveren voor je applicaties:
Wat is Redis-py?
Redis-py is de officiële Redis-clientbibliotheek voor Python. Het biedt een gebruiksvriendelijke interface om vanuit je Python-code met Redis te communiceren.
Enkele van de belangrijkste functies zijn:
Redis instellen voor Python-ontwikkeling
Laten we bekijken hoe we Redis kunnen opzetten met Python.
Er zijn drie hoofdmanieren om Redis te laten draaien:
Methode A: met Docker
Als je Docker gebruikt, moet Docker Desktop eerst op je machine zijn geïnstalleerd. Dit kun je downloaden via de DockerHub-website.
Zodra Docker is geïnstalleerd, open je je opdrachtprompt en voer je de volgende opdracht in.
Vervolgens starten we een nieuwe container.
docker pull redisdownloadt de nieuwste officiële Redis-image.docker run --name my-redis -p 6379:6379 -d redisstart een nieuwe container met de naam my-redis. De parameter-p 6379:6379koppelt poort 6379 van je lokale machine aan poort 6379 van de container, zodat je oplocalhost:6379met Redis kunt verbinden. De vlag-ddraait de container op de achtergrond (detached mode).Om te verifiëren, voer uit:
Je zou
PONGals reactie moeten krijgen.Methode B: met Windows Subsystem for Linux (WSL)
Voor Windows-machines is een andere mogelijke methode installatie via Windows Subsystem. Dit gebruikt Linux voor de installatie.
Deze opdracht installeert en configureert de standaard Ubuntu-distributie binnen WSL. Herstart indien nodig.
Open vervolgens je Ubuntu-terminal (via Microsoft Store of door wsl in PowerShell te typen) en voer uit:
Start daarna je Redis-server.
Laten we testen of de server actief is.
Hier is een toelichting op de bovenstaande opdrachten:
sudo apt-get updatehaalt de nieuwste pakketdefinities op.sudo apt-get install redis-serverinstalleert Redis binnen de Ubuntu-omgeving.sudo service redis-server startstart de Redis-service direct.redis-cli pingtest de connectiviteit met de lokale Redis-server en retourneertPONGbij succes.Methode C: Third-party builds
Deze oplossingen bieden native Windows-binaries. Na downloaden en installeren of uitpakken, voer uit:
Na het starten zou redis-server.exe logs moeten tonen dat het luistert op 127.0.0.1:6379.
Je kunt dit bevestigen met de meegeleverde CLI (indien aanwezig):
Je mag bij succes een
PONG-resultaat verwachten.De redis-py-bibliotheek installeren
Vervolgens moet je de redis-py-bibliotheek installeren om via Python toegang te krijgen tot de database. Zorg ervoor dat zowel Python als Redis afzonderlijk zijn geïnstalleerd voordat je de bibliotheek installeert.
Deze opdracht downloadt en installeert de Python Redis-clientbibliotheek (redis-py) van PyPI. Als je een virtual environment gebruikt, activeer die dan voordat je deze opdracht uitvoert.
Verifieer met:
Dit zou een versienummer moeten printen (bijv. 5.2.1).
Een Redis-server instellen
Als je een van de bovenstaande methoden (Docker, WSL of een third-party build) hebt gevolgd, zou je nu een Redis-server hebben draaien op
localhost:6379. Dat is voldoende voor lokale ontwikkeling op Windows.Werken met Redis-datastructuren
Hieronder staan Python-voorbeelden die laten zien hoe je verbinding maakt met en verschillende Redis-datatypen bewerkt. Elk codeblok bevat toelichtende comments over hoe de methoden of opdrachten werken.
Strings in Redis
We maken een Redis-object dat verbinding maakt met de lokale Redis-server.
r.set("mykey", "hello from Windows")slaat de string "hello from Windows" op onder de sleutel "mykey".r.get("mykey")haalt de waarde op die in mykey is opgeslagen. Redis retourneert bytes, dus we decoderen het voor leesbare output.r.delete("mykey")verwijdert de sleutel mykey volledig.Voorbeeld: gebruikerssessies opslaan en ophalen
Hier is een codevoorbeeld voor sessiebeheer van gebruikers:
store_user_session(user_id): maakt een wereldwijd unieke ID viauuid.uuid4()en slaat die op onder een gebruikersspecifieke sleutel.get_user_session(user_id): leest de sessietoken terug. AlsNone, ontbreekt de sessie of is deze verlopen.delete_user_session(user_id): verwijdert de sessiesleutel uit Redis en logt de gebruiker effectief uit.Lijsten in Redis
Redis-lijsten zijn geordende reeksen van strings. Je kunt aan beide uiteinden bewerkingen uitvoeren, wat ze handig maakt voor queues, stacks of logs.
lpush("task_queue", "task1")voegt"task1"toe aan de linkerkant van een lijst genaamd "task_queue".rpush("task_queue", "task2")enrpush("task_queue", "task3")voegen taken toe aan de rechterkant.lpop("task_queue") and rpop("task_queue")verwijderen en retourneren items van respectievelijk het begin en het einde van de lijst.Voorbeeld: een eenvoudige Redis-queue
enqueue_taskvoegt altijd nieuwe taken toe aan het einde van de lijst en simuleert zo een traditionele FIFO-queue.dequeue_taskverwijdert taken van voren. Als de lijst leeg is, retourneert hijNone.De while-loop verwerkt taken totdat de queue leeg is en stopt dan.
Hashes in Redis
Hashes lijken op Python-dictionaries maar worden in Redis opgeslagen. Ze zijn ideaal om gerelateerde velden te groeperen (bijv. gebruikersgegevens).
hset("user:1001", "name", "Alice")zet het veld"name"op de waarde "Alice" binnen de hash met sleutel "user:1001".hget("user:1001", "email")haalt het veld"email"op.hdel("user:1001", "email")verwijdert het veld"email"uit die hash.Voorbeeld: gestructureerde gebruikersprofielen opslaan en benaderen
We slaan de naam en e-mail van een gebruiker op in een hash.
mapping={"name": name, "email": email}gebruikt de mogelijkheid vanredis-pyom meerdere velden tegelijk te zetten.r.hgetall(user_key)haalt alle velden en waarden op, geretourneerd als een dictionary van ruwe bytes die we naar strings decoderen.delete_user_profileverwijdert de gehele hash-sleutel.Sets en gesorteerde sets
Data in Redis kan worden beheerd met sets of gesorteerde sets.
Sets zijn verzamelingen van unieke waarden, terwijl gesorteerde sets verzamelingen zijn van waarden met bijbehorende scores. Deze datastructuren bieden efficiënte manieren om data op te slaan en op te halen, wat ze nuttig maakt voor toepassingen die snelle lookups vereisen.
Sets
Een set in Redis is vergelijkbaar met een wiskundige set: een verzameling unieke elementen, zonder duplicaten. Sets kunnen worden gebruikt om relaties te modelleren, bijvoorbeeld gebruikers die een bericht leuk vonden op sociale media.
Hier is een demonstratie van sets:
Redis-sets garanderen uniciteit van leden. Een poging om een duplicaat toe te voegen heeft geen effect.
Het resultaat van
smembersis een Python-set van bytes.Gesorteerde sets
Gesorteerde sets in Redis lijken op gewone sets, maar elk lid heeft ook een bijbehorende score. Dit maakt efficiënte sorteer- en rangschikbewerkingen mogelijk.
Gesorteerde sets worden vaak gebruikt voor leaderboards, waarbij de score de rang of punten van een speler vertegenwoordigt.
Hier is een demonstratie van gesorteerde sets:
Gesorteerde sets bewaren leden in een specifieke volgorde bepaald door hun numerieke scores.
zrange("leaderboard", 0, -1, withscores=True)retourneert alle leden van rang 0 tot het einde, inclusief hun scores.Voorbeeld: tags of leaderboards beheren
Het gebruik van gesorteerde sets kan handig zijn bij het beheren van tags of het maken van leaderboards.
add_tagenget_tagsdemonstreren een one-to-many-tagging-systeem met opslag in een Set.update_leaderboardenget_leaderboardlaten zien hoe je een game-leaderboard kunt implementeren.Redis-functies in Python-applicaties
Redis heeft verschillende functies die het populair maken voor dataopslag in Python-applicaties: queueing, locking en caching.
Hieronder zie je de implementaties in Python:
Redis als queue (met blocking)
Laten we Redis als queue met blocking verkennen met
BLPOP.BLPOPis een blokkerende operatie die wacht tot er een element beschikbaar is in een lijst.blocking_consumergebruiktblpopin een lus. Als de lijst leeg is, wachtblpoptot er een nieuw item wordt gepusht.Zodra een item is ontvangen, wordt het uit de lijst verwijderd en geprint.
Deze aanpak is ideaal voor producer-consumerpatronen waarbij workers taken verwerken zodra ze verschijnen.
Locks implementeren in Redis
Gedistribueerde locks voorkomen dat meerdere clients of processen tegelijk dezelfde resource wijzigen. Redis helpt race conditions te vermijden in een gedistribueerde omgeving.
We maken een lock met
timeout=10, wat betekent dat als de lock niet handmatig wordt vrijgegeven, Redis deze na 10 seconden automatisch verwijdert om onbeperkte blokkering (deadlock) te voorkomen.lock.acquire(blocking=True, blocking_timeout=5)probeert de lock gedurende 5 seconden te verkrijgen voordat wordt opgegeven. Na afloop geeftlock.release()de resource vrij voor andere processen.Cachen met Redis
Caching is een veelvoorkomend scenario: sla vaak geraadpleegde data in het geheugen op om de belasting van databases of externe API's te verminderen.
We controleren of
user_data:{user_id}in Redis bestaat. Zo ja, dan is dat een cache hit en slaan we de API-call over. Zo niet, dan halen we de data op bij de externe API en gebruiken wesetex(set + vervaldatum) voor 60 seconden. Latere aanroepen binnen dat tijdsframe halen de gecachte data op en verlagen de latency.Geavanceerde onderwerpen in Redis
Denk je dat je Redis al onder de knie hebt? Laten we enkele geavanceerdere onderwerpen doornemen.
Pub/Sub gebruiken met Redis
Pub/Sub (Publish/Subscribe) is een populair messagingpatroon voor realtime-communicatie. Publishers sturen berichten naar een kanaal, en alle subscribers van dat kanaal ontvangen die berichten.
pubsub = r.pubsub()maakt een PubSub-object.pubsub.subscribe(channel_name)instrueert Redis om berichten van dat kanaal naar het PubSub-object te sturen.pubsub.listen()is een oneindige iterator die berichten oplevert zodra ze binnenkomen.r.publish(channel_name, message)stuurt een bericht naar alle abonnees vanchannel_name.Sleutels laten verlopen in Redis
Redis ondersteunt time-to-live (TTL). Dit is essentieel voor tijdelijke data zoals sessies of kortlevende caches.
r.expire("temp_key", 30)zet een TTL van 30 seconden. Na 30 seconden wordttemp_keyautomatisch verwijderd.r.setex("temp_key2", 60, "another value")is een snelkoppeling die de sleutel én de vervaldatum in één keer zet.Voorbeeld: sessieverval
Hier is een voorbeeld van hoe je sleutels met een vervaltijd kunt gebruiken om een sessie te laten verlopen na een opgegeven duur.
store_session_with_expirygebruikt onder de motorkapsetexomuser:{user_id}:sessionmet een opgegeven TTL op te slaan. Als je geen TTL doorgeeft, kan de sleutel onbeperkt blijven bestaan.Wanneer de TTL verloopt, verwijdert Redis de sleutel automatisch, waardoor de sessie niet meer kan worden opgehaald.
Best practices voor het gebruik van Redis met Python
Werken met Redis vraagt om enkele aandachtspunten en best practices om optimale prestaties te waarborgen en valkuilen te vermijden.
Enkele tips om in gedachten te houden:
Conclusie
Redis is een krachtig en veelzijdig hulpmiddel voor databeheer in Python-applicaties. Python met Redis kan veel toepassingen en usecases mogelijk maken, van het cachen van data tot het beheren van queues.
Wil je meer leren over Redis? Onze Introduction to NoSQL-cursus helpt je omgaan met key-value-data. Liever Python? Dan is onze Python Data Fundamentals skill track een goed startpunt.