کتابخانه‌ی استاندارد · پایگاه داده

ردیس db/redis

کارخواه Redis: کلید و مقدار، هش، لیست، مجموعه و انتشار.

واردسازی دیتابیس.ردیس

ردیس یک پایگاه داده‌ی درون حافظه برای کش، نشست، شمارنده، صف و جدول امتیاز است. این بسته پروتکل ردیس را مستقیم روی سوکت و بدون هیچ کتابخانه‌ی خارجی پیاده می‌کند: برای دستورهای پرکاربرد رشته، هش، لیست و مجموعه یک تابع دارد، و دستور هر دستور دیگری را با آرگومان‌هایش می‌فرستد و پاسخ خام را برمی‌گرداند. این صفحه با یک آموزش شروع می‌شود و مرجع کامل همه‌ی تابع‌ها و نوع‌ها پس از آن می‌آید.

آموزش: کوتاه‌کننده‌ی پیوند در دوازده گام

گام‌های زیر بخش ذخیره‌سازی یک کوتاه‌کننده‌ی پیوند کوچک را می‌سازند: رکورد پیوندها، شمارنده‌ی کلیک، فهرست پیوندهای تازه، بازدیدکنندگان یکتا و جدول برترین‌ها. هر گام یک برنامه‌ی کامل است و خروجی زیر آن همان چیزی است که در برابر یک ردیس ۷.۴ واقعی چاپ کرد. گام‌ها را به ترتیب اجرا کنید، چون هر گام از کلیدهایی که گام‌های قبل گذاشته‌اند استفاده می‌کند. گام آخر همه را دوباره پاک می‌کند. مقدارها در این آموزش فارسی‌اند و ردیس متن UTF-8 را بی هیچ تنظیمی نگه می‌دارد.

اول یک سرور با گذرواژه راه بیندازید. با داکر یک فرمان کافی است:

docker run -p 6379:6379 redis:7.4 redis-server --requirepass s3cret

برنامه‌ها به 127.0.0.1:6379 وصل می‌شوند و با گذرواژه‌ی s3cret وارد می‌شوند. برای شروع دوباره، در کانتینر با docker exec فرمان redis-cli -a s3cret flushall را اجرا کنید و از گام ۱ آغاز کنید.

۱. اتصال و ورود

اتصال یک اتصال TCP باز می‌کند و یک کلاینت برمی‌گرداند. معتبر می‌گوید این کار شد یا نه و خطا می‌گوید چرا نشد. سروری که گذرواژه دارد تا احراز هویت موفق نشود هیچ دستوری را نمی‌پذیرد؛ برای همین نخستین پینگ نادرست است. انتخاب پایگاه داده به پایگاه شماره‌دار دیگری می‌رود؛ سرور پیش‌فرض ۱۶ پایگاه دارد، از ۰ تا ۱۵.

db-redis-connect.salam
واردسازی دیتابیس.ردیس

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    اگر وارونه ردیس.معتبر(ک):
        سرچاپ "به ردیس نمی‌رسیم:"، ردیس.خطا(ک)
        برگشت 1
    پایان
    دیرکن ردیس.بستن(ک)

    سرچاپ "پینگ پیش از ورود:"، ردیس.پینگ(ک)
    سرچاپ "گذرواژه‌ی نادرست:"، ردیس.احراز هویت(ک، "guess")
    سرچاپ "گذرواژه‌ی درست:"، ردیس.احراز هویت(ک، "s3cret")
    سرچاپ "پینگ پس از ورود:"، ردیس.پینگ(ک)

    سرچاپ "پایگاه ۱۵:"، ردیس.انتخاب پایگاه داده(ک، 15)
    سرچاپ "پایگاه ۹۹:"، ردیس.انتخاب پایگاه داده(ک، 99)
    سرچاپ "بازگشت به ۰:"، ردیس.انتخاب پایگاه داده(ک، 0)

    خاموش := ردیس.اتصال("127.0.0.1"، 6390)
    سرچاپ "درگاه ۶۳۹۰:"، ردیس.معتبر(خاموش)، ردیس.خطا(خاموش)
پایان
خروجیپینگ پیش از ورود: false گذرواژه‌ی نادرست: false گذرواژه‌ی درست: true پینگ پس از ورود: true پایگاه ۱۵: true پایگاه ۹۹: false بازگشت به ۰: true درگاه ۶۳۹۰: false no connection

همه‌ی تابع‌های این بسته به جای شیء خطا یک مقدار ساده برمی‌گردانند: منطقی، عدد، رشته یا وکتور. اگر کاری نشود مقدار خالی می‌گیرید: نادرست، صفر یا رشته‌ی خالی. گام ۱۰ نشان می‌دهد هر جا لازم بود چطور این حالت‌ها را از هم جدا کنید. کلاینت را همیشه با بستن ببندید تا سوکت بسته و حافظه‌ی آن آزاد شود.

۲. رشته‌ها و کلیدهای ناموجود

ساده‌ترین مقدار ردیس یک رشته زیر یک کلید است. تنظیم آن را نگه می‌دارد، دریافت برمی‌گرداند و پیوست به انتهایش می‌افزاید. ردیس NULL ندارد: کلید یا هست یا نیست. دریافت در هر دو حالت رشته‌ی خالی می‌دهد؛ پس اگر مقدار خالی برایتان معنا دارد، از وجود دارد بپرسید، یا GET را با دستور بفرستید و پاسخ را با پاسخ خالی است بسنجید.

db-redis-strings.salam
واردسازی دیتابیس.ردیس
واردسازی رشته

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    ردیس.تنظیم(ک، "site:name"، "پیوند کوتاه")
    ردیس.تنظیم(ک، "site:motto"، "")
    سرچاپ "نام:"، ردیس.دریافت(ک، "site:name")
    سرچاپ "شعار: [" + ردیس.دریافت(ک، "site:motto") + "]"، ردیس.وجود دارد(ک، "site:motto")
    سرچاپ "مالک: [" + ردیس.دریافت(ک، "site:owner") + "]"، ردیس.وجود دارد(ک، "site:owner")

    ناپایا آرگ‌ها := وکتور {} برگردان وکتور<رشته>
    آرگ‌ها.بیفزا("GET")
    آرگ‌ها.بیفزا("site:owner")
    پ := ردیس.دستور(ک، آرگ‌ها)
    سرچاپ "پاسخ GET site:owner تهی است:"، ردیس.پاسخ خالی است(پ)
    ردیس.آزادسازی پاسخ(پ)

    متن دردسرساز := "x\r\nFLUSHALL\r\n"
    ردیس.تنظیم(ک، "site:tricky"، متن دردسرساز)
    سرچاپ "بایت‌های ذخیره‌شده:"، ردیس.طول رشته(ک، "site:tricky")، "از"، متن دردسرساز.طول()
    سرچاپ "همان متن برگشت:"، رشته.یکسان است(ردیس.دریافت(ک، "site:tricky")، متن دردسرساز)
    سرچاپ "نام هنوز هست:"، ردیس.وجود دارد(ک، "site:name")
    ردیس.حذف(ک، "site:tricky")

    سرچاپ "طول پس از پیوست:"، ردیس.پیوست(ک، "site:name"، " با سلام")
    سرچاپ "نام:"، ردیس.دریافت(ک، "site:name")
پایان
خروجینام: پیوند کوتاه شعار: [] true مالک: [] false پاسخ GET site:owner تهی است: true بایت‌های ذخیره‌شده: 13 از 13 همان متن برگشت: true نام هنوز هست: true طول پس از پیوست: 35 نام: پیوند کوتاه با سلام

نگرانی تزریق دستور وجود ندارد. هر آرگومان با طولش و سپس بایت‌هایش فرستاده می‌شود، پس مقداری که فاصله، گیومه یا شکست خط دارد درست همان‌طور ذخیره می‌شود و هرگز دستور دوم خوانده نمی‌شود. تنها محدودیت بایت NUL است: رشته‌های سلام در نخستین NUL تمام می‌شوند، پس داده‌ی دودویی را به این تابع‌ها ندهید یا اول آن را رمزگذاری کنید، برای نمونه با Base64EncodeBytes از بسته‌ی encoding. ستون طول در خروجی بایت‌ها را می‌شمارد، نه حرف‌ها را؛ هر حرف فارسی دو بایت است.

۳. رکوردها در هش

هش چند فیلد نام‌دار را زیر یک کلید نگه می‌دارد و جای طبیعی یک رکورد است. افزایش روی یک کلید شمارنده شناسه‌هایی می‌دهد که هرگز تکرار نمی‌شوند، حتی وقتی چند برنامه هم‌زمان پیوند می‌افزایند. تنظیم فیلد هش یک فیلد را می‌نویسد، دریافت همه هش همه را در یک نگاشت می‌خواند و از آن‌جا پر کردن ساختار خودتان یک خط است. همه‌ی مقدارها رشته برمی‌گردند؛ عددها را خودتان تبدیل کنید. نام فیلدها هم می‌توانند فارسی باشند، همان‌طور که این‌جا هستند.

db-redis-hashes.salam
واردسازی دیتابیس.ردیس
واردسازی تبدیل

ساختار پیوند:
    همگانی شناسه: صحیح۶۴ = 0
    همگانی نشانی: رشته = ""
    همگانی عنوان: رشته = ""
    همگانی مالک: رشته = ""
پایان

تابع ذخیره(ک: ردیس.کلاینت، نشانی: رشته، عنوان: رشته، مالک: رشته): صحیح۶۴:
    شناسه := ردیس.افزایش(ک، "links:next")
    کلید := "link:" + تبدیل.قالب عدد(شناسه)
    ردیس.تنظیم فیلد هش(ک، کلید، "نشانی"، نشانی)
    ردیس.تنظیم فیلد هش(ک، کلید، "عنوان"، عنوان)
    ردیس.تنظیم فیلد هش(ک، کلید، "مالک"، مالک)
    برگشت شناسه
پایان

تابع بارگذاری(ک: ردیس.کلاینت، شناسه: صحیح۶۴): پیوند:
    نگاشت := ردیس.دریافت همه هش(ک، "link:" + تبدیل.قالب عدد(شناسه))
    اگر نگاشت.اندازه() برابر 0:
        برگشت پیوند {}
    پایان
    برگشت پیوند { شناسه = شناسه، نشانی = نگاشت.بگیر("نشانی")، عنوان = نگاشت.بگیر("عنوان")، مالک = نگاشت.بگیر("مالک") }
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    ذخیره(ک، "https://salamlang.ir"، "خانه‌ی سلام"، "سارا")
    ذخیره(ک، "https://salamlang.ir/learn/"، "دوره‌ی سلام"، "امید")
    ذخیره(ک، "https://github.com/SalamLang/Salam"، "سلام در گیت‌هاب"، "سارا")

    تکرار 3 در ش:
        پ := بارگذاری(ک، (ش + 1) برگردان صحیح۶۴)
        سرچاپ پ.شناسه، پ.عنوان، "<-"، پ.نشانی، "از"، پ.مالک
    پایان
    سرچاپ "پیوند ۹ پیدا شد:"، بارگذاری(ک، 9).شناسه نابرابر 0

    سرچاپ "فیلدهای link:2:"، ردیس.تعداد فیلدهای هش(ک، "link:2")
    سرچاپ "مالک link:2:"، ردیس.دریافت فیلد هش(ک، "link:2"، "مالک")
    ردیس.تنظیم فیلد هش(ک، "link:2"، "یادداشت"، "برای دانشجوهای تازه")
    سرچاپ "یادداشت دارد:"، ردیس.فیلد هش وجود دارد(ک، "link:2"، "یادداشت")
    سرچاپ "یادداشت حذف شد:"، ردیس.حذف فیلد هش(ک، "link:2"، "یادداشت")
    سرچاپ "یادداشت دارد:"، ردیس.فیلد هش وجود دارد(ک، "link:2"، "یادداشت")
پایان
خروجی1 خانه‌ی سلام <- https://salamlang.ir از سارا 2 دوره‌ی سلام <- https://salamlang.ir/learn/ از امید 3 سلام در گیت‌هاب <- https://github.com/SalamLang/Salam از سارا پیوند ۹ پیدا شد: false فیلدهای link:2: 3 مالک link:2: امید یادداشت دارد: true یادداشت حذف شد: true یادداشت دارد: false

دریافت همه هش برای کلیدی که نیست نگاشت خالی برمی‌گرداند و بارگذاری از همین راه پیوند ناموجود را تشخیص می‌دهد. برای نوشتن چند فیلد در یک رفت و برگشت، HSET key f1 v1 f2 v2 را با دستور بفرستید، همان‌طور که گام ۹ می‌کند.

۴. شمارنده‌ها

افزایش، افزایش با مقدار و کاهش عددی را که به شکل رشته ذخیره شده تغییر می‌دهند و مقدار تازه را برمی‌گردانند. ردیس هر دستور را تنها اجرا می‌کند، پس دو برنامه که یک کلید را می‌شمارند هیچ به‌روزرسانی‌ای را گم نمی‌کنند. کلیدی که نیست صفر حساب می‌شود، پس آماده‌سازی لازم نیست. مقدار باز هم رشته است: دریافت رقم‌هایش را می‌دهد و تبدیل.تجزیه عدد آن را عدد می‌کند.

db-redis-counters.salam
واردسازی دیتابیس.ردیس
واردسازی تبدیل

تابع کلیک(ک: ردیس.کلاینت، شناسه: صحیح): صحیح۶۴:
    برگشت ردیس.افزایش(ک، "clicks:" + تبدیل.قالب عدد(شناسه برگردان صحیح۶۴))
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    کلیک(ک، 1)
    کلیک(ک، 1)
    کلیک(ک، 3)
    کلیک(ک، 3)
    سرچاپ "کلیک‌های پیوند ۱:"، کلیک(ک، 1)
    سرچاپ "کلیک‌های واردشده‌ی پیوند ۲:"، ردیس.افزایش با مقدار(ک، "clicks:2"، 40)
    سرچاپ "پیوند ۲ پس از برگشت دو کلیک:"، ردیس.افزایش با مقدار(ک، "clicks:2"، -2)
    سرچاپ "پیوند ۳ پس از حذف کلیک ربات:"، ردیس.کاهش(ک، "clicks:3")

    خام := ردیس.دریافت(ک، "clicks:2")
    سرچاپ "به شکل متن:"، خام، "نوع"، ردیس.نوع(ک، "clicks:2")
    مقدار := تبدیل.تجزیه عدد(خام)
    سرچاپ "به شکل عدد به اضافه‌ی یک:"، مقدار + 1

    سرچاپ "شناسه‌ی پیوند بعدی:"، تبدیل.تجزیه عدد(ردیس.دریافت(ک، "links:next")) + 1
پایان
خروجیکلیک‌های پیوند ۱: 3 کلیک‌های واردشده‌ی پیوند ۲: 40 پیوند ۲ پس از برگشت دو کلیک: 38 پیوند ۳ پس از حذف کلیک ربات: 1 به شکل متن: 38 نوع string به شکل عدد به اضافه‌ی یک: 39 شناسه‌ی پیوند بعدی: 4

۵. لیست‌ها

لیست رشته‌ها را به ترتیب نگه می‌دارد. افزودن به ابتدای لیست به جلو و افزودن به انتهای لیست به ته می‌افزاید؛ برداشتن از ابتدای لیست و برداشتن از انتهای لیست یکی برمی‌دارند. بازه لیست بخشی را بر پایه‌ی جایگاه می‌خواند و هر دو سر را شامل می‌شود؛ جایگاه منفی از ته شمرده می‌شود، پس 0، -1 کل لیست است. افزودن شناسه‌های تازه به جلو فهرستی می‌سازد که تازه‌ترین‌ها اول‌اند.

db-redis-lists.salam
واردسازی دیتابیس.ردیس
واردسازی تبدیل

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    تکرار 3 در ش:
        ردیس.افزودن به ابتدای لیست(ک، "links:recent"، تبدیل.قالب عدد((ش + 1) برگردان صحیح۶۴))
    پایان
    سرچاپ "شمار تازه‌ها:"، ردیس.طول لیست(ک، "links:recent")

    هر شناسه در ردیس.بازه لیست(ک، "links:recent"، 0، -1):
        سرچاپ "  پیوند"، شناسه، ردیس.دریافت فیلد هش(ک، "link:" + شناسه، "عنوان")
    پایان

    سرچاپ "دو تای تازه‌تر:"، ردیس.بازه لیست(ک، "links:recent"، 0، 1).طول()
    سرچاپ "قدیمی‌ترین:"، ردیس.بازه لیست(ک، "links:recent"، -1، -1).بگیر(0)

    ردیس.افزودن به انتهای لیست(ک، "links:review"، "2")
    ردیس.افزودن به انتهای لیست(ک، "links:review"، "3")
    سرچاپ "اولی برای بازبینی:"، ردیس.برداشتن از ابتدای لیست(ک، "links:review")
    سرچاپ "آخری برای بازبینی:"، ردیس.برداشتن از انتهای لیست(ک، "links:review")
    سرچاپ "بازبینی خالی: [" + ردیس.برداشتن از ابتدای لیست(ک، "links:review") + "]"، ردیس.طول لیست(ک، "links:review")
پایان
خروجیشمار تازه‌ها: 3 پیوند 3 سلام در گیت‌هاب پیوند 2 دوره‌ی سلام پیوند 1 خانه‌ی سلام دو تای تازه‌تر: 2 قدیمی‌ترین: 1 اولی برای بازبینی: 2 آخری برای بازبینی: 3 بازبینی خالی: [] 0

لیستی که خالی شود حذف می‌شود و برداشتن از آن رشته‌ی خالی می‌دهد. برای نگه داشتن فهرست در طولی ثابت، پس از هر افزودن LTRIM links:recent 0 99 را با دستور بفرستید.

۶. مجموعه‌ها

مجموعه هر عضو را یک بار نگه می‌دارد. افزودن به مجموعه برای عضو تازه ۱ و برای عضوی که از قبل بوده ۰ برمی‌گرداند؛ این یعنی پرسش «این را قبلا دیده‌ام؟» در یک گام. اندازه مجموعه اعضا را می‌شمارد، عضو مجموعه است یکی را می‌سنجد و اعضای مجموعه همه را برمی‌گرداند.

db-redis-sets.salam
واردسازی دیتابیس.ردیس
واردسازی مرتب سازی

تابع بازدید(ک: ردیس.کلاینت، پیوند: رشته، کاربر: رشته): منطقی:
    برگشت ردیس.افزودن به مجموعه(ک، "visitors:" + پیوند، کاربر) برابر 1
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    سرچاپ "نخستین بازدید سارا:"، بازدید(ک، "1"، "سارا")
    سرچاپ "نخستین بازدید امید:"، بازدید(ک، "1"، "امید")
    سرچاپ "سارا دوباره:"، بازدید(ک، "1"، "سارا")
    بازدید(ک، "1"، "رضا")
    بازدید(ک، "3"، "سارا")

    سرچاپ "بازدیدکنندگان یکتای پیوند ۱:"، ردیس.اندازه مجموعه(ک، "visitors:1")
    سرچاپ "رضا پیوند ۳ را دید:"، ردیس.عضو مجموعه است(ک، "visitors:3"، "رضا")

    سرچاپ "رضا حذف شد:"، ردیس.حذف از مجموعه(ک، "visitors:1"، "رضا")
    نام‌ها := ردیس.اعضای مجموعه(ک، "visitors:1")
    مرتب سازی.مرتب(نام‌ها)
    هر نام در نام‌ها:
        سرچاپ "  -"، نام
    پایان
پایان
خروجینخستین بازدید سارا: true نخستین بازدید امید: true سارا دوباره: false بازدیدکنندگان یکتای پیوند ۱: 3 رضا پیوند ۳ را دید: false رضا حذف شد: 1 - امید - سارا

ردیس مجموعه را به هیچ ترتیبی نگه نمی‌دارد، پس خروجی اعضای مجموعه را پیش از نمایش مرتب کنید. برای مجموعه‌ای با میلیون‌ها عضو، به جای آن SSCAN را با دستور به کار ببرید.

۷. انقضا

به هر کلیدی می‌شود عمر داد. تنظیم با انقضا رشته و عمرش را در یک دستور نگه می‌دارد؛ انقضا به کلیدی که از قبل هست عمر می‌دهد. زمان باقیمانده ثانیه‌های مانده را برمی‌گرداند: ۱- برای کلیدی که هرگز منقضی نمی‌شود و ۲- برای کلیدی که نیست. وقت که تمام شود ردیس خودش کلید را پاک می‌کند.

db-redis-expire.salam
واردسازی دیتابیس.ردیس
واردسازی زمان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    ردیس.تنظیم با انقضا(ک، "preview:3"، "<b>سلام در گیت‌هاب</b>"، 600)
    سرچاپ "مهلت پیش‌نمایش:"، ردیس.زمان باقیمانده(ک، "preview:3")
    سرچاپ "مهلت پیوند:"، ردیس.زمان باقیمانده(ک، "link:3")
    سرچاپ "مهلت کلید ناموجود:"، ردیس.زمان باقیمانده(ک، "link:99")

    ردیس.تنظیم(ک، "link:3:promo"، "نیم‌بها")
    سرچاپ "انقضای تخفیف تنظیم شد:"، ردیس.انقضا(ک، "link:3:promo"، 1)
    سرچاپ "تخفیف اکنون:"، ردیس.دریافت(ک، "link:3:promo")
    زمان.خواب(1500)
    سرچاپ "تخفیف بعدا: [" + ردیس.دریافت(ک، "link:3:promo") + "]"، ردیس.وجود دارد(ک، "link:3:promo")
    سرچاپ "انقضای کلید ناموجود:"، ردیس.انقضا(ک، "link:3:promo"، 10)

    ردیس.تنظیم(ک، "preview:3"، "<b>پیش‌نمایش تازه</b>")
    سرچاپ "مهلت پس از تنظیم:"، ردیس.زمان باقیمانده(ک، "preview:3")
پایان
خروجیمهلت پیش‌نمایش: 600 مهلت پیوند: -1 مهلت کلید ناموجود: -2 انقضای تخفیف تنظیم شد: true تخفیف اکنون: نیم‌بها تخفیف بعدا: [] false انقضای کلید ناموجود: false مهلت پس از تنظیم: -1

به خط آخر دقت کنید: تنظیم ساده عمر کلید را برمی‌دارد. وقتی مقداری را که باید منقضی شود جایگزین می‌کنید، دوباره تنظیم با انقضا را به کار ببرید.

۸. هر دستوری: جدول برترین‌ها

ردیس حدود دویست دستور دارد و این بسته برای پرکاربردترین‌ها تابع دارد. دستور هر کدام را می‌فرستد: نام دستور و آرگومان‌هایش را در یک وکتور<رشته> بگذارید. پاسخی که برمی‌گردد نوعی دارد (پاسخ_رشته، پاسخ_صحیح، پاسخ_آرایه، پاسخ_خالی، پاسخ_وضعیت یا پاسخ_خطا) و آن را با پاسخ رشته، پاسخ صحیح، طول آرایه پاسخ و عنصر آرایه پاسخ می‌خوانید. این گام با یک مجموعه‌ی مرتب، که تابع جداگانه‌ای ندارد، پیوندها را بر پایه‌ی کلیک رتبه‌بندی می‌کند.

db-redis-command.salam
واردسازی دیتابیس.ردیس
واردسازی تبدیل

تابع بفرست(ک: ردیس.کلاینت، واژه‌ها: رشته[]): ردیس.پاسخ:
    ناپایا آرگ‌ها := وکتور {} برگردان وکتور<رشته>
    هر واژه در واژه‌ها:
        آرگ‌ها.بیفزا(واژه)
    پایان
    برگشت ردیس.دستور(ک، آرگ‌ها)
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    تکرار 3 در ش:
        شناسه := تبدیل.قالب عدد((ش + 1) برگردان صحیح۶۴)
        پ := بفرست(ک، ["ZADD"، "links:top"، ردیس.دریافت(ک، "clicks:" + شناسه)، شناسه])
        ردیس.آزادسازی پاسخ(پ)
    پایان

    برترین‌ها := بفرست(ک، ["ZREVRANGE"، "links:top"، "0"، "-1"، "WITHSCORES"])
    اگر ردیس.نوع پاسخ(برترین‌ها) برابر ردیس.پاسخ_آرایه:
        ناپایا ش := 0
        تا ش کوچکتر ردیس.طول آرایه پاسخ(برترین‌ها):
            شناسه := ردیس.پاسخ رشته(ردیس.عنصر آرایه پاسخ(برترین‌ها، ش))
            امتیاز := ردیس.پاسخ رشته(ردیس.عنصر آرایه پاسخ(برترین‌ها، ش + 1))
            سرچاپ امتیاز، "کلیک:"، ردیس.دریافت فیلد هش(ک، "link:" + شناسه، "عنوان")
            ش += 2
        پایان
    پایان
    ردیس.آزادسازی پاسخ(برترین‌ها)

    رتبه := بفرست(ک، ["ZREVRANK"، "links:top"، "1"])
    سرچاپ "رتبه‌ی پیوند ۱:"، ردیس.پاسخ صحیح(رتبه) + 1، "پاسخ عددی:"، ردیس.نوع پاسخ(رتبه) برابر ردیس.پاسخ_صحیح
    ردیس.آزادسازی پاسخ(رتبه)

    چند فیلد := بفرست(ک، ["HMGET"، "link:1"، "عنوان"، "مالک"، "رنگ"])
    تکرار ردیس.طول آرایه پاسخ(چند فیلد) در ش:
        عنصر := ردیس.عنصر آرایه پاسخ(چند فیلد، ش)
        سرچاپ "  فیلد"، ش، "[" + ردیس.پاسخ رشته(عنصر) + "]"، "تهی:"، ردیس.پاسخ خالی است(عنصر)
    پایان
    ردیس.آزادسازی پاسخ(چند فیلد)
پایان
خروجی38 کلیک: دوره‌ی سلام 3 کلیک: خانه‌ی سلام 1 کلیک: سلام در گیت‌هاب رتبه‌ی پیوند ۱: 2 پاسخ عددی: true فیلد 0 [خانه‌ی سلام] تهی: false فیلد 1 [سارا] تهی: false فیلد 2 [] تهی: true

هر پاسخ دستور را با آزادسازی پاسخ آزاد کنید. عنصرهایی که عنصر آرایه پاسخ می‌دهد مال آرایه‌شان‌اند و همراه آن آزاد می‌شوند، پس هرگز جداگانه آزادشان نکنید. فیلدی که نیست به شکل عنصر تهی برمی‌گردد، مثل رنگ در بالا.

۹. تراکنش‌ها

MULTI تراکنش را آغاز می‌کند: دستورهای پس از آن پاسخ QUEUED می‌دهند و EXEC همه را یک‌جا اجرا می‌کند، بی آن‌که دستوری از کلاینت‌های دیگر در میانشان بیاید. DISCARD صف را دور می‌ریزد. ردیس بازگردانی ندارد: اگر یکی از دستورهای صف شکست بخورد بقیه باز هم اجرا می‌شوند، پس هر جا مهم است همه‌ی عنصرهای پاسخ EXEC را بررسی کنید.

db-redis-tx.salam
واردسازی دیتابیس.ردیس
واردسازی تبدیل

تابع بفرست(ک: ردیس.کلاینت، واژه‌ها: رشته[]): رشته:
    ناپایا آرگ‌ها := وکتور {} برگردان وکتور<رشته>
    هر واژه در واژه‌ها:
        آرگ‌ها.بیفزا(واژه)
    پایان
    پ := ردیس.دستور(ک، آرگ‌ها)
    ناپایا خروجی := ردیس.پاسخ رشته(پ)
    اگر ردیس.نوع پاسخ(پ) برابر ردیس.پاسخ_آرایه:
        خروجی = "آرایه‌ای با " + تبدیل.قالب عدد(ردیس.طول آرایه پاسخ(پ) برگردان صحیح۶۴) + " عنصر"
    وگرنه اگر ردیس.پاسخ خالی است(پ):
        خروجی = "تهی"
    وگرنه اگر ردیس.نوع پاسخ(پ) برابر ردیس.پاسخ_صحیح:
        خروجی = تبدیل.قالب عدد(ردیس.پاسخ صحیح(پ))
    پایان
    ردیس.آزادسازی پاسخ(پ)
    برگشت خروجی
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    سرچاپ بفرست(ک، ["MULTI"])
    سرچاپ بفرست(ک، ["INCR"، "links:next"])
    سرچاپ بفرست(ک، ["HSET"، "link:4"، "نشانی"، "https://salamlang.ir/std/"، "عنوان"، "کتابخانه‌های سلام"، "مالک"، "امید"])
    سرچاپ بفرست(ک، ["LPUSH"، "links:recent"، "4"])
    سرچاپ بفرست(ک، ["EXEC"])
    سرچاپ "پیوند ۴:"، ردیس.دریافت فیلد هش(ک، "link:4"، "عنوان")، "شناسه‌ی بعدی:"، ردیس.دریافت(ک، "links:next")

    دیگری := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(دیگری)
    ردیس.احراز هویت(دیگری، "s3cret")

    سرچاپ بفرست(ک، ["WATCH"، "link:4"])
    عنوان := ردیس.دریافت فیلد هش(ک، "link:4"، "عنوان")
    ردیس.تنظیم فیلد هش(دیگری، "link:4"، "عنوان"، "کتابخانه‌ی استاندارد سلام")
    سرچاپ بفرست(ک، ["MULTI"])
    سرچاپ بفرست(ک، ["HSET"، "link:4"، "عنوان"، عنوان + " (بازبینی‌شده)"])
    سرچاپ "EXEC پس از تغییر:"، بفرست(ک، ["EXEC"])
    سرچاپ "عنوان ماند:"، ردیس.دریافت فیلد هش(ک، "link:4"، "عنوان")

    سرچاپ بفرست(ک، ["MULTI"])
    سرچاپ بفرست(ک، ["INCR"، "clicks:4"])
    سرچاپ بفرست(ک، ["DISCARD"])
    سرچاپ "clicks:4 هست:"، ردیس.وجود دارد(ک، "clicks:4")
پایان
خروجیOK QUEUED QUEUED QUEUED آرایه‌ای با 3 عنصر پیوند ۴: کتابخانه‌های سلام شناسه‌ی بعدی: 4 OK OK QUEUED EXEC پس از تغییر: تهی عنوان ماند: کتابخانه‌ی استاندارد سلام OK QUEUED OK clicks:4 هست: false

WATCH قفل خوش‌بینانه می‌افزاید. اگر کلاینت دیگری پیش از EXEC کلید زیر نظر را تغییر دهد، تراکنش اجرا نمی‌شود و EXEC پاسخ تهی می‌دهد؛ کلید را دوباره بخوانید و از نو بکوشید. کلاینت دوم این‌جا نقش همان کاربر دیگر را بازی می‌کند. تراکنش به اتصالش بسته است، پس از MULTI تا EXEC روی یک کلاینت و یک نخ بمانید.

۱۰. خطاها

دو جور شکست داریم. سرور ممکن است دستوری را به خاطر نوع نادرست یا آرگومان بد نپذیرد؛ اتصال سالم می‌ماند و پاسخ از نوع پاسخ_خطا است و پیامش در پاسخ رشته. تابع‌های میان‌بر این پیام را نشان نمی‌دهند: دریافت روی هش رشته‌ی خالی و افزایش روی متن صفر برمی‌گرداند. هر جا لازم است بدانید، دستور را با دستور بفرستید. جور دیگر قطع شدن اتصال است که این گام آن را عمدا با CLIENT KILL از یک کلاینت دوم پدید می‌آورد.

db-redis-errors.salam
واردسازی دیتابیس.ردیس

تابع بفرست(ک: ردیس.کلاینت، واژه‌ها: رشته[]): رشته:
    ناپایا آرگ‌ها := وکتور {} برگردان وکتور<رشته>
    هر واژه در واژه‌ها:
        آرگ‌ها.بیفزا(واژه)
    پایان
    پ := ردیس.دستور(ک، آرگ‌ها)
    ناپایا خروجی := "درست"
    اگر وارونه ردیس.پاسخ معتبر(پ):
        خروجی = "پاسخی نیامد: " + ردیس.خطا(ک)
    وگرنه اگر ردیس.پاسخ خطا است(پ):
        خروجی = "خطای سرور: " + ردیس.پاسخ رشته(پ)
    پایان
    ردیس.آزادسازی پاسخ(پ)
    برگشت خروجی
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    سرچاپ "دریافت روی هش: [" + ردیس.دریافت(ک، "link:1") + "]"
    سرچاپ "افزایش روی متن:"، ردیس.افزایش(ک، "site:name")
    سرچاپ بفرست(ک، ["GET"، "link:1"])
    سرچاپ بفرست(ک، ["INCR"، "site:name"])
    سرچاپ بفرست(ک، ["HGET"، "link:1"])
    سرچاپ "اتصال هنوز سالم:"، ردیس.پینگ(ک)، "[" + ردیس.خطا(ک) + "]"

    مدیر := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(مدیر)
    ردیس.احراز هویت(مدیر، "s3cret")
    سرچاپ بفرست(مدیر، ["CLIENT"، "KILL"، "TYPE"، "normal"، "SKIPME"، "yes"])

    سرچاپ "پینگ پس از قطع:"، ردیس.پینگ(ک)
    سرچاپ "معتبر:"، ردیس.معتبر(ک)، "خطا:"، ردیس.خطا(ک)
    سرچاپ بفرست(ک، ["PING"])
پایان
خروجیدریافت روی هش: [] افزایش روی متن: 0 خطای سرور: WRONGTYPE Operation against a key holding the wrong kind of value خطای سرور: ERR value is not an integer or out of range خطای سرور: ERR wrong number of arguments for 'hget' command اتصال هنوز سالم: true [] درست پینگ پس از قطع: false معتبر: true خطا: Server closed the connection پاسخی نیامد: Server closed the connection

پس از قطع اتصال، معتبر هنوز درست می‌گوید، چون فقط نشان می‌دهد اتصال موفق بود یا نه. حالا خطا علت را نگه می‌دارد، هر فراخوانی مقدار خالی‌اش را برمی‌گرداند و دستور پاسخی می‌دهد که پاسخ معتبر نیست. کلاینت خودش دوباره وصل نمی‌شود: آن را ببندید و دوباره اتصال را صدا بزنید.

۱۱. چند نخ

هر کلاینت یک اتصال با یک بافر خواندن است، پس دو نخ هرگز نباید هم‌زمان یک کلاینت را به کار ببرند. به هر نخ کلاینت خودش را بدهید، مانند زیر. استخر اتصال آماده‌ای وجود ندارد؛ برای سروری که درخواست‌های زیادی را پاسخ می‌دهد، برای هر نخ کارگر یک کلاینت باز کنید و تا پایان عمر نخ نگهش دارید. شمارنده دقیق درمی‌آید چون ردیس هر INCR را تنها اجرا می‌کند.

db-redis-threads.salam
واردسازی دیتابیس.ردیس

پایا کارگرها := 4
پایا کلیک‌ها := 250

تابع کارگر():
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")
    تکرار کلیک‌ها:
        ردیس.افزایش(ک، "clicks:4")
        ردیس.افزودن به مجموعه(ک، "visitors:4"، "ربات")
    پایان
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")
    ردیس.حذف(ک، "clicks:4")

    ناپایا نخ‌ها := وکتور {} برگردان وکتور<صحیح۶۴>
    تکرار کارگرها:
        نخ‌ها.بیفزا(نخ‌ساز(کارگر))
    پایان
    هر ن در نخ‌ها:
        نخ‌پیوند(ن)
    پایان

    سرچاپ "کلیک‌های پیوند ۴:"، ردیس.دریافت(ک، "clicks:4")، "مورد انتظار"، کارگرها * کلیک‌ها
    سرچاپ "بازدیدکنندگان یکتا:"، ردیس.اندازه مجموعه(ک، "visitors:4")
پایان
خروجیکلیک‌های پیوند ۴: 1000 مورد انتظار 1000 بازدیدکنندگان یکتا: 1

۱۲. نگاهی به کلیدها و پاک‌سازی

کلیدها کلیدهایی را که با یک الگو جورند فهرست می‌کند و نوع می‌گوید هر کدام چه چیزی نگه می‌دارد. کلیدها کل پایگاه را یک‌جا می‌پیماید و در این مدت سرور را معطل می‌کند؛ این‌جا اشکالی ندارد ولی روی سرور واقعی با میلیون‌ها کلید دردسر است. SCAN با یک نشانگر صفحه به صفحه پیش می‌رود؛ حلقه‌ی زیر آن را با دستور اجرا می‌کند. پاک‌سازی پایگاه داده همه‌ی کلیدهای پایگاه جاری را حذف می‌کند.

db-redis-cleanup.salam
واردسازی دیتابیس.ردیس
واردسازی مرتب سازی

تابع پیمایش(ک: ردیس.کلاینت، الگو: رشته): وکتور<رشته>:
    ناپایا یافته‌ها := وکتور {} برگردان وکتور<رشته>
    ناپایا نشانگر := "0"
    تا درست:
        ناپایا آرگ‌ها := وکتور {} برگردان وکتور<رشته>
        آرگ‌ها.بیفزا("SCAN")
        آرگ‌ها.بیفزا(نشانگر)
        آرگ‌ها.بیفزا("MATCH")
        آرگ‌ها.بیفزا(الگو)
        آرگ‌ها.بیفزا("COUNT")
        آرگ‌ها.بیفزا("100")
        پ := ردیس.دستور(ک، آرگ‌ها)
        نشانگر = ردیس.پاسخ رشته(ردیس.عنصر آرایه پاسخ(پ، 0))
        دسته := ردیس.عنصر آرایه پاسخ(پ، 1)
        تکرار ردیس.طول آرایه پاسخ(دسته) در ش:
            یافته‌ها.بیفزا(ردیس.پاسخ رشته(ردیس.عنصر آرایه پاسخ(دسته، ش)))
        پایان
        ردیس.آزادسازی پاسخ(پ)
        اگر نشانگر برابر "0":
            بشکن
        پایان
    پایان
    مرتب سازی.مرتب(یافته‌ها)
    برگشت یافته‌ها
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    کلیدها := ردیس.کلیدها(ک، "*")
    مرتب سازی.مرتب(کلیدها)
    هر کلید در کلیدها:
        سرچاپ کلید، ردیس.نوع(ک، کلید)
    پایان

    کهنه‌ها := پیمایش(ک، "visitors:*")
    هر کلید در کهنه‌ها:
        ردیس.حذف(ک، کلید)
    پایان
    سرچاپ کهنه‌ها.طول()، "مجموعه‌ی بازدید حذف شد، مانده:"، پیمایش(ک، "visitors:*").طول()

    سرچاپ "پاک‌سازی:"، ردیس.پاک‌سازی پایگاه داده(ک)، "کلیدهای مانده:"، ردیس.کلیدها(ک، "*").طول()
پایان
خروجیclicks:1 string clicks:2 string clicks:3 string clicks:4 string link:1 hash link:2 hash link:3 hash link:4 hash links:next string links:recent list links:top zset preview:3 string site:motto string site:name string visitors:1 set visitors:3 set visitors:4 set 3 مجموعه‌ی بازدید حذف شد، مانده: 0 پاک‌سازی: true کلیدهای مانده: 0

بیشتر

  • انتشار پیامی را به همه‌ی کلاینت‌هایی که در یک کانال مشترک شده‌اند می‌فرستد و شمار گیرندگان را برمی‌گرداند. این بسته می‌تواند منتشر کند ولی نمی‌تواند مشترک شود: دستور برای هر دستور یک پاسخ می‌خواند، و مشترک باید منتظر پیام‌هایی بماند که خودشان از راه می‌رسند. برای کاری که نباید گم شود، یک لیست را صف کنید (پایین را ببینید).
  • برای کاربر ACL نام‌دار، AUTH name password را با دستور بفرستید؛ احراز هویت فقط گذرواژه را می‌فرستد.
  • دستورهایی مثل HINCRBY، SETNX، MGET، LTRIM، ZADD و XADD همه مثل گام ۸ با دستور فرستاده می‌شوند.
  • اتصال هر قدر سرور طول بدهد صبر می‌کند. دستورهایی که عمدا منتظر می‌مانند، مثل BLPOP، مهلت خودشان را به عنوان آرگومان می‌گیرند.

راهنما: کش کردن یک صفحه‌ی کند

رایج‌ترین کاربرد ردیس کشی جلوی یک چیز کند است. اول کلید را بجویید؛ اگر نبود، مقدار را بسازید و با تنظیم با انقضا نگه دارید تا نسخه‌ی کهنه خودش از میان برود. وقتی منبع تغییر کرد کلید را حذف کنید تا درخواست بعدی دوباره بسازدش. تصمیم «در کش هست» را وجود دارد می‌گیرد نه یک دریافت خالی، تا صفحه‌ی خالی هم کش شود.

db-redis-cache.salam
واردسازی دیتابیس.ردیس

ناپایا شمار ساخت := 0

تابع بساز(شناسه: رشته): رشته:
    شمار ساخت += 1
    برگشت "<h1>یادداشت " + شناسه + "</h1>"
پایان

تابع برگه(ک: ردیس.کلاینت، شناسه: رشته): رشته:
    کلید := "cache:note:" + شناسه
    اگر ردیس.وجود دارد(ک، کلید):
        برگشت ردیس.دریافت(ک، کلید)
    پایان
    اچ‌تی‌ام‌ال := بساز(شناسه)
    ردیس.تنظیم با انقضا(ک، کلید، اچ‌تی‌ام‌ال، 60)
    برگشت اچ‌تی‌ام‌ال
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    سرچاپ برگه(ک، "42")
    سرچاپ برگه(ک، "42")
    سرچاپ برگه(ک، "7")
    سرچاپ "ساخته شد"، شمار ساخت، "بار برای ۳ درخواست"
    سرچاپ "ثانیه‌های مانده:"، ردیس.زمان باقیمانده(ک، "cache:note:42")

    ردیس.حذف(ک، "cache:note:42")
    سرچاپ برگه(ک، "42")
    سرچاپ "ساخته شد"، شمار ساخت، "بار پس از ویرایش"
    ردیس.حذف(ک، "cache:note:42")
    ردیس.حذف(ک، "cache:note:7")
پایان
خروجی<h1>یادداشت 42</h1> <h1>یادداشت 42</h1> <h1>یادداشت 7</h1> ساخته شد 2 بار برای ۳ درخواست ثانیه‌های مانده: 60 <h1>یادداشت 42</h1> ساخته شد 3 بار پس از ویرایش

راهنما: محدود کردن درخواست هر کاربر

محدودکننده‌ی نرخ با پنجره‌ی ثابت برای هر کاربر یک شمارنده می‌خواهد. افزایش شمار را برمی‌گرداند و نخستین درخواست هر پنجره عمر کلید را تعیین می‌کند، پس شمارنده در پایان پنجره خودش صفر می‌شود. چون افزایش اتمی است، سقف حتی وقتی چند فرایند سرور یک کاربر را می‌سنجند هم رعایت می‌شود.

db-redis-ratelimit.salam
واردسازی دیتابیس.ردیس

تابع مجاز(ک: ردیس.کلاینت، کاربر: رشته، سقف: صحیح۶۴، ثانیه‌ها: صحیح): منطقی:
    کلید := "rate:" + کاربر
    شمار := ردیس.افزایش(ک، کلید)
    اگر شمار برابر 1:
        ردیس.انقضا(ک، کلید، ثانیه‌ها)
    پایان
    برگشت شمار کوچکتربرابر سقف
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    تکرار 5 در ش:
        سرچاپ "درخواست"، ش + 1، "سارا مجاز:"، مجاز(ک، "سارا"، 3، 60)
    پایان
    سرچاپ "درخواست 1 امید مجاز:"، مجاز(ک، "امید"، 3، 60)
    سرچاپ "پنجره‌ی سارا تا"، ردیس.زمان باقیمانده(ک، "rate:سارا")، "ثانیه‌ی دیگر"
    ردیس.حذف(ک، "rate:سارا")
    ردیس.حذف(ک، "rate:امید")
پایان
خروجیدرخواست 1 سارا مجاز: true درخواست 2 سارا مجاز: true درخواست 3 سارا مجاز: true درخواست 4 سارا مجاز: false درخواست 5 سارا مجاز: false درخواست 1 امید مجاز: true پنجره‌ی سارا تا 60 ثانیه‌ی دیگر

راهنما: صف کار با یک کارگر

لیست یک صف کار ساده می‌سازد: تولیدکننده‌ها کارها را با افزودن به انتهای لیست می‌گذارند و کارگر از جلو برمی‌دارد. برداشتن از ابتدای لیست بی‌درنگ برمی‌گردد، پس کارگری که مدام آن را صدا بزند وقت تلف می‌کند. BLPOP، که با دستور فرستاده می‌شود، تا رسیدن یک کار یا تمام شدن مهلت به ثانیه صبر می‌کند و در پایان مهلت پاسخ تهی می‌دهد. کارگر، همان‌طور که گام ۱۱ می‌خواهد، در نخ خودش با کلاینت خودش کار می‌کند.

db-redis-queue.salam
واردسازی دیتابیس.ردیس

تابع بردار(ک: ردیس.کلاینت، صف: رشته، ثانیه‌ها: رشته): رشته:
    ناپایا آرگ‌ها := وکتور {} برگردان وکتور<رشته>
    آرگ‌ها.بیفزا("BLPOP")
    آرگ‌ها.بیفزا(صف)
    آرگ‌ها.بیفزا(ثانیه‌ها)
    پ := ردیس.دستور(ک، آرگ‌ها)
    ناپایا کار := ""
    اگر ردیس.نوع پاسخ(پ) برابر ردیس.پاسخ_آرایه:
        کار = ردیس.پاسخ رشته(ردیس.عنصر آرایه پاسخ(پ، 1))
    پایان
    ردیس.آزادسازی پاسخ(پ)
    برگشت کار
پایان

تابع کارگر():
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")
    ناپایا کار := بردار(ک، "queue:email"، "1")
    تا کار.طول() بزرگتر 0:
        ردیس.افزودن به انتهای لیست(ک، "done:email"، "فرستاده شد " + کار)
        کار = بردار(ک، "queue:email"، "1")
    پایان
پایان

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، 6379)
    دیرکن ردیس.بستن(ک)
    ردیس.احراز هویت(ک، "s3cret")

    ن := نخ‌ساز(کارگر)
    ردیس.افزودن به انتهای لیست(ک، "queue:email"، "خوشامد:سارا")
    ردیس.افزودن به انتهای لیست(ک، "queue:email"، "خوشامد:امید")
    ردیس.افزودن به انتهای لیست(ک، "queue:email"، "خلاصه:همه")
    سرچاپ "۳ کار در صف گذاشته شد"
    نخ‌پیوند(ن)

    هر خط در ردیس.بازه لیست(ک، "done:email"، 0، -1):
        سرچاپ خط
    پایان
    سرچاپ "مانده در صف:"، ردیس.طول لیست(ک، "queue:email")
    ردیس.حذف(ک، "done:email")
پایان
خروجی۳ کار در صف گذاشته شد فرستاده شد خوشامد:سارا فرستاده شد خوشامد:امید فرستاده شد خلاصه:همه مانده در صف: 0

کاری که کارگر برداشته و سپس از کار افتاده گم می‌شود. هر جا این مهم است، هر کار را با LMOVE به یک لیست «در حال انجام» ببرید و فقط پس از پایان کار حذفش کنید.

کدام تابع برای کدام کار

کارابزار
کش کردن یک مقدار برای مدتیتنظیم با انقضا، سپس دریافت یا وجود دارد
شمردن بازدید، دادن شناسهافزایش، افزایش با مقدار، کاهش
نگه داشتن یک رکورد یا نشستتنظیم فیلد هش، دریافت همه هش، سپس انقضا
موردهای تازه، صف کارافزودن به ابتدای لیست، بازه لیست، افزودن به انتهای لیست، BLPOP با دستور
بازدیدکننده‌ی یکتا، برچسب، کاربران آنلاینافزودن به مجموعه، اندازه مجموعه، عضو مجموعه است
رتبه‌بندی، امتیازZADD، ZREVRANGE، ZINCRBY با دستور
چند نوشتن با همMULTI و EXEC با دستور
خبر دادن به سرویسی دیگرانتشار
یافتن کلیدها روی سرور بزرگSCAN با دستور، نه کلیدها

گونه‌ها

کلاینت Client

ساختار کلاینت
اتصال به ردیس.
نامانگلیسیگونهتوضیح
دستهhandleتهی*اشاره‌گر اتصال؛ اگر اتصال شکست بخورد تهی است.
db-redis-Client.salam
واردسازی دیتابیس.ردیس

تابع ریشه:
    ک := ردیس.اتصال("127.0.0.1"، ۶۳۷۹)
    اگر وارونه ردیس.معتبر(ک):
        سرچاپ ردیس.خطا(ک)
        برگشت
    پایان
    _ := ردیس.احراز هویت(ک، "s3cret")
    _ := ردیس.انتخاب پایگاه داده(ک، ۱)
    سرچاپ ردیس.پینگ(ک)

    _ := ردیس.تنظیم(ک، "greeting"، "سلام")
    _ := ردیس.تنظیم با انقضا(ک، "session:42"، "token"، ۳۶۰۰)
    سرچاپ ردیس.دریافت(ک، "greeting")، ردیس.وجود دارد(ک، "greeting")، ردیس.زمان باقیمانده(ک، "session:42")
    سرچاپ ردیس.افزایش(ک، "visits")، ردیس.افزایش با مقدار(ک، "visits"، ۱۰)، ردیس.کاهش(ک، "visits")
    سرچاپ ردیس.پیوست(ک، "greeting"، "!")، ردیس.طول رشته(ک، "greeting")، ردیس.نوع(ک، "greeting")
    _ := ردیس.انقضا(ک، "greeting"، ۶۰)
    سرچاپ ردیس.کلیدها(ک، "session:*").طول()
    _ := ردیس.حذف(ک، "greeting")

    _ := ردیس.تنظیم فیلد هش(ک، "user:1"، "name"، "مریم")
    _ := ردیس.تنظیم فیلد هش(ک، "user:1"، "city"، "تهران")
    سرچاپ ردیس.دریافت فیلد هش(ک، "user:1"، "name")، ردیس.فیلد هش وجود دارد(ک، "user:1"، "age")، ردیس.تعداد فیلدهای هش(ک، "user:1")
    همه := ردیس.دریافت همه هش(ک، "user:1")
    سرچاپ همه.اندازه()
    _ := ردیس.حذف فیلد هش(ک، "user:1"، "city")

    _ := ردیس.افزودن به انتهای لیست(ک، "jobs"، "a")
    _ := ردیس.افزودن به ابتدای لیست(ک، "jobs"، "b")
    سرچاپ ردیس.طول لیست(ک، "jobs")، ردیس.بازه لیست(ک، "jobs"، ۰، -۱).طول()
    سرچاپ ردیس.برداشتن از ابتدای لیست(ک، "jobs")، ردیس.برداشتن از انتهای لیست(ک، "jobs")

    _ := ردیس.افزودن به مجموعه(ک، "tags"، "go")
    _ := ردیس.افزودن به مجموعه(ک، "tags"، "salam")
    سرچاپ ردیس.عضو مجموعه است(ک، "tags"، "salam")، ردیس.اندازه مجموعه(ک، "tags")، ردیس.اعضای مجموعه(ک، "tags").طول()
    _ := ردیس.حذف از مجموعه(ک، "tags"، "go")
    سرچاپ ردیس.انتشار(ک، "news"، "خبر تازه")

    ناپایا آرگ := وکتور {} برگردان وکتور<رشته>
    آرگ.افزودن("GET")
    آرگ.افزودن("visits")
    پ := ردیس.دستور(ک، آرگ)
    اگر ردیس.پاسخ معتبر(پ) و وارونه ردیس.پاسخ خطا است(پ) و وارونه ردیس.پاسخ خالی است(پ):
        سرچاپ ردیس.نوع پاسخ(پ) == ردیس.پاسخ_رشته، ردیس.پاسخ رشته(پ)
    پایان
    ردیس.آزادسازی پاسخ(پ)
    ناپایا آرگ۲ := وکتور {} برگردان وکتور<رشته>
    آرگ۲.افزودن("LRANGE")
    آرگ۲.افزودن("jobs")
    آرگ۲.افزودن("0")
    آرگ۲.افزودن("-1")
    پ۲ := ردیس.دستور(ک، آرگ۲)
    اگر ردیس.نوع پاسخ(پ۲) == ردیس.پاسخ_آرایه:
        تکرار ردیس.طول آرایه پاسخ(پ۲) در ش:
            سرچاپ ردیس.پاسخ رشته(ردیس.عنصر آرایه پاسخ(پ۲، ش))
        پایان
    پایان
    سرچاپ ردیس.پاسخ صحیح(پ۲)، ردیس.پاسخ_صحیح، ردیس.پاسخ_خالی، ردیس.پاسخ_وضعیت، ردیس.پاسخ_خطا، ردیس.پاسخ_اعشار
    ردیس.آزادسازی پاسخ(پ۲)
    _ := ردیس.پاک‌سازی پایگاه داده(ک)
    ردیس.بستن(ک)
پایان

پاسخ Reply

ساختار پاسخ
پاسخ یک دستور.
نامانگلیسیگونهتوضیح
دستهhandleتهی*اشاره‌گر پاسخ.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پایاها و متغیرها

پاسخ_رشته REPLY_STRING

پایا پاسخ_رشته: صحیح۳۲ = 1
نوع پاسخ: رشته.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ_آرایه REPLY_ARRAY

پایا پاسخ_آرایه: صحیح۳۲ = 2
نوع پاسخ: آرایه.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ_صحیح REPLY_INTEGER

پایا پاسخ_صحیح: صحیح۳۲ = 3
نوع پاسخ: عدد صحیح.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ_خالی REPLY_NIL

پایا پاسخ_خالی: صحیح۳۲ = 4
نوع پاسخ: تهی، مثلاً کلیدی که نیست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ_وضعیت REPLY_STATUS

پایا پاسخ_وضعیت: صحیح۳۲ = 5
نوع پاسخ: وضعیت، مثل OK.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ_خطا REPLY_ERROR

پایا پاسخ_خطا: صحیح۳۲ = 6
نوع پاسخ: خطا.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ_اعشار REPLY_DOUBLE

پایا پاسخ_اعشار: صحیح۳۲ = 7
نوع پاسخ: اعشاری، که با پاسخ رشته خوانده می‌شود. فقط سروری که به RESP3 رفته آن را می‌فرستد؛ در پروتکل پیش‌فرض اعشاری‌ها به شکل رشته می‌آیند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

تابع‌ها

اتصال Connect

تابع اتصال(host: رشته، port: صحیح): کلاینت
به سرور ردیس در میزبان و درگاه داده‌شده وصل می‌شود؛ نتیجه را با معتبر بسنجید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

معتبر Ok

تابع معتبر(c: کلاینت): منطقی
اتصال موفق بود. اگر اتصال بعدا قطع شود باز هم درست می‌ماند؛ خطا یا پینگ این را نشان می‌دهند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

خطا Error

تابع خطا(c: کلاینت): رشته
علت شکست اتصال: no connection وقتی اتصال شکست خورد، یا پیامی مثل Server closed the connection پس از قطع شدن؛ تا وقتی کار می‌کند خالی است. خطایی که سرور برای یک دستور برمی‌گرداند این‌جا نگه داشته نمی‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

بستن Close

تابع بستن(c: کلاینت)
اتصال را می‌بندد و کلاینت را آزاد می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پینگ Ping

تابع پینگ(c: کلاینت): منطقی
سرور پاسخ داد؛ اگر اتصال قطع باشد یا هنوز گذرواژه بخواهد نادرست است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

انتخاب پایگاه داده Select

تابع انتخاب پایگاه داده(c: کلاینت، index: صحیح): منطقی
پایگاه داده‌ی شماره‌دار را برمی‌گزیند، روی سرور پیش‌فرض از ۰ تا ۱۵.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

احراز هویت Auth

تابع احراز هویت(c: کلاینت، password: رشته): منطقی
با گذرواژه‌ی سرور وارد می‌شود. برای کاربر ACL نام‌دار، AUTH name password را با دستور بفرستید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاک‌سازی پایگاه داده FlushDB

تابع پاک‌سازی پایگاه داده(c: کلاینت): منطقی
همه‌ی کلیدهای پایگاه داده‌ی جاری را پاک می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

تنظیم فیلد هش HSet

تابع تنظیم فیلد هش(c: کلاینت، key: رشته، field: رشته، val: رشته): منطقی
فیلدی از هش را تنظیم می‌کند. وقتی پاسخی نیاید یا سرور دستور را نپذیرد، مثلا روی کلیدی که هش نیست، نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

دریافت فیلد هش HGet

تابع دریافت فیلد هش(c: کلاینت، key: رشته، field: رشته): رشته
فیلدی از هش؛ اگر نباشد رشته‌ی خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

حذف فیلد هش HDel

تابع حذف فیلد هش(c: کلاینت، key: رشته، field: رشته): منطقی
فیلدی را حذف می‌کند؛ اگر بود درست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

فیلد هش وجود دارد HExists

تابع فیلد هش وجود دارد(c: کلاینت، key: رشته، field: رشته): منطقی
فیلد هست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

تعداد فیلدهای هش HLen

تابع تعداد فیلدهای هش(c: کلاینت، key: رشته): صحیح۶۴
شمار فیلدها.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

دریافت همه هش HGetAll

تابع دریافت همه هش(c: کلاینت، key: رشته): نگاشت<رشته، رشته>
همه‌ی فیلدها به شکل نگاشت؛ برای کلید ناموجود نگاشت خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

تنظیم Set

تابع تنظیم(c: کلاینت، key: رشته، val: رشته): منطقی
مقدار کلید را تنظیم می‌کند و مقدار و انقضای پیشین را برمی‌دارد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

تنظیم با انقضا SetEx

تابع تنظیم با انقضا(c: کلاینت، key: رشته، val: رشته، seconds: صحیح): منطقی
با انقضا بر حسب ثانیه.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

دریافت Get

تابع دریافت(c: کلاینت، key: رشته): رشته
مقدار کلید؛ اگر نباشد یا رشته نباشد، رشته‌ی خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

وجود دارد Exists

تابع وجود دارد(c: کلاینت، key: رشته): منطقی
کلید هست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

حذف Del

تابع حذف(c: کلاینت، key: رشته): منطقی
کلید را حذف می‌کند؛ اگر بود درست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

انقضا Expire

تابع انقضا(c: کلاینت، key: رشته، seconds: صحیح): منطقی
به کلید عمری بر حسب ثانیه می‌دهد؛ اگر کلید نباشد نادرست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

زمان باقیمانده TTL

تابع زمان باقیمانده(c: کلاینت، key: رشته): صحیح۶۴
ثانیه‌های باقی‌مانده تا انقضا؛ ۱- بی‌انقضا و ۲- نبودن کلید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

افزایش Incr

تابع افزایش(c: کلاینت، key: رشته): صحیح۶۴
عدد کلید را یکی بالا می‌برد و مقدار تازه را برمی‌گرداند؛ کلید ناموجود صفر حساب می‌شود. اگر مقدار عدد نباشد صفر برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

افزایش با مقدار IncrBy

تابع افزایش با مقدار(c: کلاینت، key: رشته، delta: صحیح۶۴): صحیح۶۴
به اندازه‌ی داده‌شده بالا می‌برد؛ مقدار منفی هم پذیرفته است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

کاهش Decr

تابع کاهش(c: کلاینت، key: رشته): صحیح۶۴
یکی پایین می‌آورد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پیوست Append

تابع پیوست(c: کلاینت، key: رشته، val: رشته): صحیح۶۴
متن را به مقدار می‌افزاید و طول تازه را برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

طول رشته StrLen

تابع طول رشته(c: کلاینت، key: رشته): صحیح۶۴
طول مقدار.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

نوع Type

تابع نوع(c: کلاینت، key: رشته): رشته
نوع مقدار کلید، مثل string یا hash؛ برای کلید ناموجود none.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

کلیدها Keys

تابع کلیدها(c: کلاینت، pattern: رشته): وکتور<رشته>
کلیدهایی که با الگویی مثل user:* جورند. در این مدت کل کلیدها را می‌پیماید و سرور را معطل می‌کند؛ روی پایگاه بزرگ SCAN را با دستور به کار ببرید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

افزودن به مجموعه SAdd

تابع افزودن به مجموعه(c: کلاینت، key: رشته، member: رشته): صحیح۶۴
عضوی به مجموعه می‌افزاید؛ برای عضو تازه ۱ و برای عضو تکراری ۰ برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

حذف از مجموعه SRem

تابع حذف از مجموعه(c: کلاینت، key: رشته، member: رشته): صحیح۶۴
عضوی را حذف می‌کند؛ اگر بود ۱ برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

عضو مجموعه است SIsMember

تابع عضو مجموعه است(c: کلاینت، key: رشته، member: رشته): منطقی
عضو هست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

اندازه مجموعه SCard

تابع اندازه مجموعه(c: کلاینت، key: رشته): صحیح۶۴
شمار اعضا.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

اعضای مجموعه SMembers

تابع اعضای مجموعه(c: کلاینت، key: رشته): وکتور<رشته>
همه‌ی اعضا، بی ترتیب مشخص.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

انتشار Publish

تابع انتشار(c: کلاینت، channel: رشته، message: رشته): صحیح۶۴
پیامی را در کانال منتشر می‌کند و شمار گیرندگان را برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

دستور Command

تابع دستور(c: کلاینت، args: وکتور<رشته>): پاسخ
هر دستوری را با آرگومان‌هایش، هر کدام درست همان‌طور که هست، می‌فرستد و پاسخ خام را برمی‌گرداند. پاسخ را با آزادسازی پاسخ آزاد کنید؛ وقتی اتصال قطع است پاسخ پاسخ معتبر نیست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ معتبر ReplyOk

تابع پاسخ معتبر(r: پاسخ): منطقی
پاسخی آمد؛ اگر اتصال قطع باشد یا هرگز برقرار نشده باشد نادرست است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

نوع پاسخ ReplyType

تابع نوع پاسخ(r: پاسخ): صحیح
نوع پاسخ.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ خطا است ReplyIsError

تابع پاسخ خطا است(r: پاسخ): منطقی
سرور دستور را نپذیرفت؛ پیامش در پاسخ رشته است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ خالی است ReplyIsNil

تابع پاسخ خالی است(r: پاسخ): منطقی
پاسخ تهی است، مثل GET روی کلیدی که نیست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ صحیح ReplyInt

تابع پاسخ صحیح(r: پاسخ): صحیح۶۴
پاسخ به شکل عدد، برای پاسخ عددی؛ برای نوع‌های دیگر صفر.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

پاسخ رشته ReplyStr

تابع پاسخ رشته(r: پاسخ): رشته
پاسخ به شکل متن، برای پاسخ رشته، وضعیت، خطا یا اعشاری؛ برای تهی، عدد و آرایه خالی است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

طول آرایه پاسخ ReplyArrayLen

تابع طول آرایه پاسخ(r: پاسخ): صحیح
شمار عنصرهای پاسخ آرایه‌ای.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

عنصر آرایه پاسخ ReplyArrayGet

تابع عنصر آرایه پاسخ(r: پاسخ، i: صحیح): پاسخ
عنصری از پاسخ آرایه‌ای، با شمارش از صفر. مال همان آرایه است: فقط پاسخ بیرونی را آزاد کنید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

آزادسازی پاسخ FreeReply

تابع آزادسازی پاسخ(r: پاسخ)
پاسخ دستور را با همه‌ی عنصرهایش آزاد می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

افزودن به ابتدای لیست LPush

تابع افزودن به ابتدای لیست(c: کلاینت، key: رشته، val: رشته): صحیح۶۴
به ابتدای لیست می‌افزاید و طول تازه را برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

افزودن به انتهای لیست RPush

تابع افزودن به انتهای لیست(c: کلاینت، key: رشته، val: رشته): صحیح۶۴
به انتهای لیست می‌افزاید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

برداشتن از ابتدای لیست LPop

تابع برداشتن از ابتدای لیست(c: کلاینت، key: رشته): رشته
از ابتدای لیست یکی برمی‌دارد؛ اگر لیست خالی باشد رشته‌ی خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

برداشتن از انتهای لیست RPop

تابع برداشتن از انتهای لیست(c: کلاینت، key: رشته): رشته
از انتها یکی برمی‌دارد؛ اگر لیست خالی باشد رشته‌ی خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

طول لیست LLen

تابع طول لیست(c: کلاینت، key: رشته): صحیح۶۴
طول لیست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam

بازه لیست LRange

تابع بازه لیست(c: کلاینت، key: رشته، start: صحیح، stop: صحیح): وکتور<رشته>
عنصرها از start تا stop، هر دو شامل. جایگاه منفی از انتها شمرده می‌شود، پس 0، -1 کل لیست است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: db-redis-Client.salam