کتابخانه redis-py در پایتون
کتابخانه redis-py یکی از پراستفادهترین کلاینتهای Redis برای زبان پایتون است که رابطی ساده و پرقدرت برای کار با دیتابیس در حافظه Redis فراهم میکند. این کتابخانه از نسخههای مدرن Redis، امکاناتی مانند پایپلاین (pipeline)، تراکنشها، Pub/Sub، Sentinel و حتی پشتیبانی از حالت async و کلاستر را پوشش میدهد. در ادامه با نصب، مبانی استفاده و بهترین شیوهها آشنا میشویم.
نصب و نسخهها
برای نصب نسخهٔ رسمی و بهروز:
pip install redisاین نسخه از redis-py (نسخهٔ 4.x به بعد) شامل پشتیبانی از asyncio و امکانات جدید است. همیشه با pip show redis نسخه را بررسی کنید.
اتصال به سرور Redis
from redis import Redis
r = Redis(host='localhost', port=6379, db=0, decode_responses=True)
r.set('greeting', 'سلام دنیا')
print(r.get('greeting')) # 'سلام دنیا'در این مثال، یک شیٔ Redis ایجاد میکنیم که به localhost متصل است. پارامتر decode_responses=True باعث میشود پاسخها به صورت رشته (str) بازگردانده شوند بهجای بایتها. متدهای پایه مثل set و get برای کار با کلیدها استفاده میشوند.
پایپلاین و تراکنشها (Pipeline & Transactions)
پایپلاین باعث میشود چندین دستور پشت سر هم بدون انتظار پاسخ اجرا و سپس نتایج یکجا دریافت شوند؛ مفید برای بهبود کارایی.
pipe = r.pipeline()
pipe.set('a', 1)
pipe.incr('a')
pipe.get('a')
results = pipe.execute()
print(results) # [True, 2, '2']در کد بالا سه دستور در پایپلاین اضافه شده و سپس با execute ارسال میشوند. اگر بخواهیم تراکنش اتمیک داشته باشیم، میتوانیم از transaction=True یا از بلوک with استفاده کنیم تا چند دستور در یک MULTI/EXEC اجرا شوند.
استفادهٔ Async (asyncio)
import asyncio
from redis.asyncio import Redis
async def main():
r = Redis(host='localhost', port=6379, decode_responses=True)
await r.set('counter', 0)
await r.incr('counter')
print(await r.get('counter'))
await r.close()
asyncio.run(main())این مثال نشان میدهد چگونه با استفاده از redis.asyncio میتوان در کدهای async/await از Redis استفاده کرد. توجه داشته باشید که باید در پایان اتصال را ببندید یا از مدیریت منابع استفاده کنید.
Pub/Sub برای انتشار و اشتراک پیام
# Publisher
r.publish('channel:news', 'خبر جدید')
# Subscriber (همزمانی ساده)
pub = r.pubsub()
pub.subscribe('channel:news')
for message in pub.listen():
print(message)الگوی Pub/Sub برای ساختن سیستمهای نوتیفیکیشن، پیامرسانی بین سرویسها یا بروزرسانیهای بلادرنگ کاربرد دارد. در نسخههای async نیز میتوان با کلاسهای مربوطه از Pub/Sub استفاده کرد.
پشتیبانی از Sentinel و Cluster
اگر از Redis Sentinel برای HA یا از Redis Cluster برای شاردینگ استفاده میکنید، redis-py ابزارهایی دارد تا اتصال مدیریت شود.
from redis.sentinel import Sentinel
sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
master = sentinel.master_for('mymaster', decode_responses=True)
master.set('k', 'v')کد بالا به یک Sentinel متصل میشود و از master_for برای گرفتن اتصال به مستر فعلی استفاده میکند. برای Redis Cluster نیز میتوان از RedisCluster استفاده کرد:
from redis.cluster import RedisCluster
rc = RedisCluster(startup_nodes=[{"host": "127.0.0.1", "port": "7000"}], decode_responses=True)
rc.set('c', 'clustered')
print(rc.get('c'))با این کد میتوانید از کلاستر استفاده کنید؛ توجه داشته باشید که پیکربندی کلاستر و نسخهٔ سرور اهمیت زیادی دارد.
ذخیرهٔ دادههای پیچیده (مثلاً JSON)
Redis ماژولهایی مانند RedisJSON دارد، اما سادهترین روش در نبود ماژول ذخیرهٔ JSON، سریالایز کردن دستی است:
import json
r.set('user:1', json.dumps({'id': 1, 'name': 'Ali'}))
user = json.loads(r.get('user:1'))در این روش با json.dumps داده را به رشته تبدیل و ذخیره میکنیم و با json.loads آن را برمیگردانیم. اگر از ماژول RedisJSON استفاده کنید، میتوانید عملیات مستقیم روی ساختارهای JSON انجام دهید اما نیازمند نصب و پیکربندی ماژول در سرور است.
نمونه جدول: مقایسهٔ کاربردی چند نوع دیتا
| نوع داده | موارد استفاده | مثال متدها |
|---|---|---|
| String | کش، توکن، وضعیتها | GET, SET, INCR |
| List | صف پیام، لاگ ساده | LPUSH, RPOP, LRANGE |
| Set | مجموعهی بدون تکرار | SADD, SREM, SMEMBERS |
| Hash | اشیاء با فیلدها | HSET, HGETALL |
| ZSet | رتبهبندی، صف اولویت | ZADD, ZRANGE |
نکات کاربردی و بهترین شیوهها
- همیشه از connection pool (پیشفرض فعال است) استفاده کنید تا مدیریت اتصالات بهتر شود.
- برای مقادیر باینری یا بزرگ، از decode_responses=False استفاده کرده و مدیریت بایتها را خودتان انجام دهید.
- برای عملیات اتمیک و چند مرحلهای از Lua scripting استفاده کنید تا از شرایط رقابتی جلوگیری شود.
- پایپلاینها را برای کاهش تعداد round-tripها به کار ببرید؛ اما مراقب محدودیت حافظه سرور باشید.
- در محیطهای چندنخی (threaded)، از کلاینتهایی که به درستی thread-safe هستند یا از pool استفاده کنید.
مثال اسکریپت Lua برای افزایش شرطی
lua = """
local key = KEYS[1]
local inc = tonumber(ARGV[1])
local val = tonumber(redis.call('get', key) or '0')
val = val + inc
redis.call('set', key, val)
return val
"""
res = r.eval(lua, 1, 'counter', 5)
print(res)در این مثال یک اسکریپت Lua اجرا میکنیم که مقدار یک کلید را بهصورت اتمیک افزایش میدهد. eval با ارسال کد Lua به سرور اجرا میشود و مزیت آن جلوگیری از race condition است.
عیبیابی و خطاهای متداول
- ConnectionError یا Timeout: بررسی کنید سرور Redis در دسترس است و پارامترهای timeout و socket مشخص شده مناسباند.
- پیغامهای مربوط به نسخهٔ سرور: برخی امکانات نیازمند نسخهٔ خاص Redis یا ماژولهای اضافهاند.
- Memory errors: با دستور INFO و MONITOR مصرف حافظه را بررسی و سیاست eviction مناسب را تنظیم کنید.
جمعبندی
redis-py یک ابزار کامل و بالغ برای کار با Redis در پایتون است؛ با یادگیری مفاهیم پایه مانند اتصال، پایپلاین، تراکنش و الگوهای Pub/Sub میتوانید از Redis در پروژههای وب، کشینگ، صفهای پیام و سیستمهای real-time بهره ببرید. توجه به نسخهٔ کتابخانه، ویژگیهای سرور و رعایت بهترین شیوهها (مثل استفاده از pool و پایپلاین) کیفیت عملکرد برنامهٔ شما را بهطور چشمگیری بهبود میدهد.
آیا این مطلب برای شما مفید بود ؟





