Główne cechy Redisa:
- napisany w języku C
- niesamowicie szybki
- używany protokół jest telneto-podobny, binarnie bezpieczny
- dane są przechowywane w pamieci
- pojemność bazy jest ograniczona do pojemności RAM maszyny
- replikacja master-slave z automatycznym failoverem
- podstawowa struktura danych to klucz - wartość
- bardzo duża ilość różnych operacji, które można wykonywać na danych
- posiada możliwość zapisywania:
- list (lists)- kolekcja elementów
- zbiorów (sets) - kolekcja unikalnych elementów
- posortowanych zbiorów (sorted sets) - jak wyżej z dodatkowym sortowaniem
- słowników - (hashes) - kolekcja typu klucz - wartość
- posiada transakcje - zapytania są serializowane co powoduje, że pojedyncze operacje są izolowane
- możliwe jest ustawienie czasu po jakim wartość zostanie automatycznie usunięta (TTL)
- pub/sub - implementacja messagingu
- open-sursowy, oparty na licencji BSD
Instalacja bazy danych Redis wiąże się tylko z kilkoma krokami (dobrze jest wykonać testy aby mieć pewność, że wszystko poszło jak należy). Ostatni krok to uruchomienie serwera.
$ wget http://download.redis.io/releases/redis-2.8.17.tar.gz $ tar xzf redis-2.8.17.tar.gz $ cd redis-2.8.17 $ make $ make test $ src/redis-server
Sprawdźmy najpierw użycie niektórych poleceń we wbudowanym kliencie redis-cli:
ela@skyler:~/work/redis-2.8.17$ src/redis-cli 127.0.0.1:6379>
W momencie gdy logujemy się do Redisa, jesteśmy automatycznie zalogowani do bazy danych 0. Zmiana na inną bazę danych powodowana jest przez polecenie 'SELECT ID' (Tutaj znajdziecie wszystkie polecenia).
ela@skyler:~/work/redis-2.8.17$ src/redis-cli 127.0.0.1:6379> select 10 # przełączenie się na index (bazę danych ID=10) OK 127.0.0.1:6379[10]> sadd tokens 0f9661323 # dodanie do zbioru (i tak 1000 razy) (integer) 1 127.0.0.1:6379[10]> keys '*' # wyświetlenie wszystkich kluczy, które pasują do wzorca 1) "tokens" 127.0.0.1:6379[10]> scard tokens # zliczenie memberów (elementów) zbioru (integer) 1000 127.0.0.1:6379[10]> srandmember tokens 10 # wyświetlenie 10 randomowo wybranych elementów zbioru 1) "0f9661323" 2) "aa942ab2b" 3) "0fcbc61ac" 4) "08b255a5d" 5) "96b9bff01" 6) "49182f81e" 7) "8e98d81f8" 8) "23ce18513" 9) "52720e003" 10) "7f6ffaa6b" 127.0.0.1:6379[10]> flushall # usunięcie wszystkich kluczy ze wszystkich baz danych OK 127.0.0.1:6379[10]> keys '*' (empty list or set)
Aby przedstawić choć część działania Redis napisałam system losowania tokenów. Tokeny są trzymane w zbiorze 'tokens'. Gdy użytkownik wysyła request o token, jest on losowo wybierany i usuwany ze zbioru przy pomocy polecenia spop. Wybrany token jest wstawiany do zbioru used. System został napisany w ruby przy użyciu gemów: redis (klient Redis), sinatra (framework web).
Zaczęłam od wygenerowania 1000 tokenów i załadowania ich do redis:
#!/usr/bin/env ruby -w require 'redis' require 'digest/md5' # redis connection REDIS_HOST = '192.168.0.10' REDIS_PORT = 6379 REDIS_DATABASE_ID = 10 TOKENS_COUNT = 1000 REDIS_SET_KEY = 'tokens' redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT, :db => REDIS_DATABASE_ID) redis.flushdb TOKENS_COUNT.times do |i| md5 = Digest::MD5.hexdigest(i.to_s) redis.sadd REDIS_SET_KEY, md5[0..8] endPrzy pomocy gemu sinatra stworzyłam prosty interface webowy do pobierania i wyświetlania informacji o tokenach:
[ela:~/work/ruby ]$ cat get_token_page.rb #!/usr/bin/env ruby -w require 'sinatra' require 'redis' # redis connection REDIS_HOST = '192.168.0.10' REDIS_PORT = 6379 REDIS_DATABASE_ID = 10 REDIS_TOKENS_AVALIABLE_SET_KEY = 'tokens' REDIS_TOKENS_USED_SET_KEY = 'used' redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT, :db => REDIS_DATABASE_ID) get '/' do %(Click <a href="/token">here</a> to get a token) end get '/token' do token = redis.spop REDIS_TOKENS_AVALIABLE_SET_KEY redis.sadd REDIS_TOKENS_USED_SET_KEY, token %(This is your token: #{token}) end get '/tokens-used' do tokens = redis.smembers REDIS_TOKENS_USED_SET_KEY token_list = tokens.map{|t| %(<li>#{t}</li>)} %(<ul>#{token_list.join}</ul>) end get '/stats' do tokens_avaiable_count = redis.scard REDIS_TOKENS_AVALIABLE_SET_KEY tokens_used_count = redis.scard REDIS_TOKENS_USED_SET_KEY %(# Tokens avaliable :#{tokens_avaiable_count} )+ %(# Tokens used :#{tokens_used_count} )+ %(# All Tokens :#{tokens_avaiable_count + tokens_used_count} ) end
Strona wygląda następująco:
Podsumowując, w programie użyłam zbioru aby mieć pewność unikalnych tokenów. Redis dla zbiorów zapewnia funkcję do wybierania losowego elementu i jego usunięcia - polecenie spop. Jest to operacja atomowa, dzięki czemu mam pewność, że każdy token zostanie użyty tylko raz. Inne polecenia:
- sadd - dodanie nowego elementu do zbioru jeśli jeszcze nie istniał
- smembers - pobranie wszystkich elementów zbioru
- scard - pobranie ilości elementów w zbiorze
- flushdb - usunięcie wszystkich kluczy i wartości aktualnie wybranej bazy bez usunięcia samej bazy
Redis posiada także możliwość definiowania transakcji. Gdzie użylibyście jej w moim programie?
Brak komentarzy:
Prześlij komentarz