Едно от нещата, които често объркват потребителите, които са запознати с други бази данни, когато изпробват Redis, е липсата на видимост в базата данни:Няма набор от таблици или колекции за вижте, просто едно обикновено, плоско ключово пространство, което (потенциално) може да има милиони ключове. Възможността за евтина итерация в това ключово пространство става много важна за запознаване със съдържанието на базата данни.
Итерацията по ключовото пространство Redis има и други важни случаи на употреба, някои от които идват на ум са:
- събиране на боклук или почистване на ключове, които съответстват на определен модел
- движение на данни и промени в схемата или преместване на определен набор ключове към друга структура от данни
- отстраняване на грешки, вземане на проби от данни, корекции на данни или намиране и коригиране на всички ключове, които са били объркани от скорошна промяна
В тази публикация ще се задълбочим в различни ключови опции за итерация на пространство, налични в Redis.
O(N) Итератори:KEYS
Командата Redis KEYS връща всички ключове в базата данни, които съответстват на шаблон (или всички ключове в ключовото пространство). Подобни команди за извличане на всички полета, съхранени в хеш е HGETALL и за всички извличане на членовете на SMEMBERS. Самите ключове в Redis се съхраняват в речник (известен още като хеш таблица). Командата KEYS работи, като преглежда този речник и изпраща всичко, което съответства на шаблона, като единичен отговор на масива. Другите команди работят по подобен начин.
Изпълнението на такава операция зависи от размера на колекцията, т.е. O(N). По този начин използването на KEYS е силно обезкуражено в производствени среди с голям брой ключове. Redis, тъй като е еднонишков, се блокира по време на тази итерация, като по този начин блокира други операции. По този начин KEYS трябва да се използва само за отстраняване на грешки и други специални случаи, когато производителността не е проблем (като когато базата данни е изведена офлайн, за да се приложи корекция на данни). Другото важно нещо, което трябва да запомните за този алгоритъм, е, че той изпраща всички съвпадащи ключове заедно като един отговор. Това може да е изключително удобно, когато ключовото пространство е малко, но ще създаде множество проблеми в голямо ключово пространство. KEYS обаче е любима команда сред разработчиците в техните собствени среди за разработка.
КЛЮЧОВЕ в действие:
127.0.0.1:6379[1]> MSET едно 1 две 2 три 3 четири 4OK# Всички ключове127.0.0.1:6379[1]> клавиши *1) "четири"2) "три"3) " два"4) "един"# клавиша, които започват с буквата 't'127.0.0.1:6379[1]> ключове t*1) "три"2) "два"# клавиша, които имат 'ee' в тях127. 0.0.1:6379[1]> клавиши *ee*1) "три"
Базирани на курсор итератори:СКАНИРАНЕ
SCAN и неговите сестрински команди, SSCAN (за набори), HSCAN (за хешове) и ZSCAN (за сортирани набори) осигуряват базирания на курсора подход за итериране върху структури от данни на Redis. Те са налични в Redis от 2.8.0.
Ключовете се връщат на постепенни итерации с гаранция за постоянно време за всяка итерация. Курсор (този случай е цяло число) се връща, когато итерациите се инициализират и се връща актуализиран курсор и всяка итерация. Цикълът на итерация започва, когато курсорът е зададен на 0 в заявката SCAN и завършва, когато курсорът, върнат от сървъра, е 0. Поради нюансите на архитектурата на Redis и реализацията на алгоритъма на курсора ето някои особености на този подход:
- Пълната итерация винаги извлича всички елементи, които са присъствали в колекцията от началото до края на пълната итерация.
- Пълната итерация никога не връща елемент, който НЕ е присъствал в колекцията от началото до края на пълната итерация.
- Даден елемент може да бъде върнат няколко пъти. Приложението трябва да се справи със случая на дублирани елементи
- Елементи, които не присъстваха постоянно в колекцията по време на пълна итерация, могат да бъдат върнати или не:не е дефинирано.
- Няма от елементите, върнати по време на всяко броене, варират и също могат да бъдат 0. Итерацията обаче не е завършена, докато сървърът не върне стойността на курсора 0.
- COUNT опцията може да се използва за ограничаване на броя на елементите, върнати във всяка итерация. Стойността по подразбиране е 10. Въпреки това, тя се счита само за предложение и не се прилага във всички случаи. Стойността на COUNT може да бъде променена по време на всяко итерационно извикване.
- МАЧЕТО опцията позволява посочване на шаблони, както позволява командата KEYS.
- Внедряването на курсора е напълно без състояние от страна на сървъра. Това позволява (потенциално) безкрайни итерации да започват паралелно. Освен това няма изисквания да се гарантира, че една итерация продължава до края и може да бъде спряна по всяко време.
Въпреки своите особености, SCAN е много полезна команда и правилната команда за избор за ключови итерации на пространството за повечето случаи на употреба.
SCAN е много полезна команда и правилната команда за избор за ключови итерации на пространство в #RedisClick To TweetСКАНИРАНЕ в действие
127.0.0.1:6379[1]> flushdbOK127.0.0.1:6379[1]> ключове *(празен списък или набор)127.0.0.1:6379[1]> отстраняване на грешки попълване 33OK127.0.0.1:6379[1:6379] 1]> сканиране 0 COUNT 51) "4"2) 1) "ключ:1" 2) "ключ:9" 3) "ключ:13" 4) "ключ:29" 5) "ключ:23" 127.0. 0.1:6379[1]> сканиране 4 1) "42"2) 1) "ключ:24" 2) "ключ:28" 3) "ключ:18" 4) "ключ:16" 5) "ключ:12 " 6) "ключ:2" 7) "ключ:6" 8) "ключ:31" 9) "ключ:27" 10) "ключ:19"127.0.0.1:6379[1]> сканиране 421) "9 "2) 1) "ключ:3" 2) "ключ:4" 3) "ключ:20" 4) "ключ:8" 5) "ключ:32" 6) "ключ:5" 7) "ключ:26" 8) "ключ:10" 9) "ключ:21" 10) "ключ:14"127.0.0.1:6379[1]> сканиране 9 COUNT 1001) "0"2) 1) "ключ:25" 2 ) "ключ:30" 3) "ключ:22" 4) "ключ:17" 5) "ключ:15" 6) "ключ:0" 7) "ключ:11" 8) "ключ:7"предварително>Под капака
Алгоритъмът, който SCAN (и неговите сестрински команди) използват за сканиране, е интригуващ и води до някои от характеристиките на командата, която описахме по-горе. Antirez го описа на високо ниво в публикацията си в блога и е обяснено (малко по-добре) в коментарите над реализацията (функция dictScan). Подробното описание ще направи тази публикация твърде дълга, така че ще дам достатъчно описание, за да станат очевидни последиците от нея.
- Повечето структури от данни на Redis са вътрешно представени като речници (поне частично в случая на сортирани набори). Те са реализирани като хеш таблици с мощност на два размера с верижно свързване за сблъсъци. Предизвикателството при писането на базиран на курсора итеративен алгоритъм тук е да можете да се справите с нарастването и свиването на хеша, без да жертвате принципите на Redis за простота (на API) и скорост.
- SCAN основно сканира куп хеш кофи на всяка итерация и връща елементите, съответстващи на шаблона в тях. Тъй като разглежда само фиксиран списък с сегменти, някои времеви итерации може да не върнат никакви стойности.
- Върнатият курсор е основно отместване в хеш таблицата, която се повтаря. Той се занимава с нарастването и свиването на хеш таблиците (т.е. повторно хеширане) чрез умна манипулация на битове от по-високо ниво на отместването, като същевременно увеличава отместването заедно със свойствата на хеш таблицата. Последствията от този подход са, че нови елементи, добавени по време на итерацията, могат или не могат да бъдат върнати. Въпреки това самият курсор няма да е необходимо да се рестартира при промяна в размера на хеш таблицата.
- Дадена кофа трябва да бъде посетена само веднъж и всички нейни ключове трябва да бъдат върнати наведнъж. Това отново е за да се гарантира, че преоразмеряването на хеша (т.е. повторното хеширане) не усложнява напредъка на итерацията. Това обаче води до това, че аргументът COUNT не е строго приложим.
- Тъй като горният подход е напълно без състояние от страна на сървъра, това по същество означава, че итерациите могат да бъдат спрени или огромен брой итерации могат да бъдат стартирани паралелно, без да се увеличава използването на паметта.
Резюме
На високо ниво са налични два варианта за повторение на ключовото пространство на Redis са:
- Използвайте KEYS, когато производителността не е проблем или когато ключовото пространство е разумно оразмерено.
- По всяко друго време използвайте СКАНИРАНЕ.
Знаехте ли, че вече поддържаме хостинг за Redis™*? Получете напълно управляван хостинг за Redis™ в безопасността на собствения си акаунт в облак и използвайте AWS/Azure кредити за внедряванията си на Redis™.