Redis
 sql >> Baza danych >  >> NoSQL >> Redis

Pierwsze kroki z interfejsami API klienta Redis

Poniżej znajduje się prosty przykład, który pokazuje, jak łatwo można korzystać z niektórych zaawansowanych struktur danych Redis — w tym przypadku Redis Lists:Pełny kod źródłowy tego przykładu można wyświetlić online

using var redisClient = new RedisClient();
//Create a 'strongly-typed' API that makes all Redis Value operations to apply against Shippers
IRedisTypedClient<Shipper> redis = redisClient.As<Shipper>();

//Redis lists implement IList<T> while Redis sets implement ICollection<T>
var currentShippers = redis.Lists["urn:shippers:current"];
var prospectiveShippers = redis.Lists["urn:shippers:prospective"];

currentShippers.Add(
    new Shipper {
        Id = redis.GetNextSequence(),
        CompanyName = "Trains R Us",
        DateCreated = DateTime.UtcNow,
        ShipperType = ShipperType.Trains,
        UniqueRef = Guid.NewGuid()
    });

currentShippers.Add(
    new Shipper {
        Id = redis.GetNextSequence(),
        CompanyName = "Planes R Us",
        DateCreated = DateTime.UtcNow,
        ShipperType = ShipperType.Planes,
        UniqueRef = Guid.NewGuid()
    });

var lameShipper = new Shipper {
    Id = redis.GetNextSequence(),
    CompanyName = "We do everything!",
    DateCreated = DateTime.UtcNow,
    ShipperType = ShipperType.All,
    UniqueRef = Guid.NewGuid()
};

currentShippers.Add(lameShipper);

Dump("ADDED 3 SHIPPERS:", currentShippers);

currentShippers.Remove(lameShipper);

Dump("REMOVED 1:", currentShippers);

prospectiveShippers.Add(
    new Shipper {
        Id = redis.GetNextSequence(),
        CompanyName = "Trucks R Us",
        DateCreated = DateTime.UtcNow,
        ShipperType = ShipperType.Automobiles,
        UniqueRef = Guid.NewGuid()
    });

Dump("ADDED A PROSPECTIVE SHIPPER:", prospectiveShippers);

redis.PopAndPushBetweenLists(prospectiveShippers, currentShippers);

Dump("CURRENT SHIPPERS AFTER POP n' PUSH:", currentShippers);
Dump("PROSPECTIVE SHIPPERS AFTER POP n' PUSH:", prospectiveShippers);

var poppedShipper = redis.PopFromList(currentShippers);
Dump("POPPED a SHIPPER:", poppedShipper);
Dump("CURRENT SHIPPERS AFTER POP:", currentShippers);

//reset sequence and delete all lists
redis.SetSequence(0);
redis.Remove(currentShippers, prospectiveShippers);
Dump("DELETING CURRENT AND PROSPECTIVE SHIPPERS:", currentShippers);

PRZYKŁADOWE WYJŚCIE:

ADDED 3 SHIPPERS:
Id:1,CompanyName:Trains R Us,ShipperType:Trains,DateCreated:2010-01-31T11:53:37.7169323Z,UniqueRef:d17c5db0415b44b2ac5da7b6ebd780f5
Id:2,CompanyName:Planes R Us,ShipperType:Planes,DateCreated:2010-01-31T11:53:37.799937Z,UniqueRef:e02a73191f4b4e7a9c44eef5b5965d06
Id:3,CompanyName:We do everything!,ShipperType:All,DateCreated:2010-01-31T11:53:37.8009371Z,UniqueRef:d0c249bbbaf84da39fc4afde1b34e332

REMOVED 1:
Id:1,CompanyName:Trains R Us,ShipperType:Trains,DateCreated:2010-01-31T11:53:37.7169323Z,UniqueRef:d17c5db0415b44b2ac5da7b6ebd780f5
Id:2,CompanyName:Planes R Us,ShipperType:Planes,DateCreated:2010-01-31T11:53:37.799937Z,UniqueRef:e02a73191f4b4e7a9c44eef5b5965d06

ADDED A PROSPECTIVE SHIPPER:
Id:4,CompanyName:Trucks R Us,ShipperType:Automobiles,DateCreated:2010-01-31T11:53:37.8539401Z,UniqueRef:67d7d4947ebc4b0ba5c4d42f5d903bec

CURRENT SHIPPERS AFTER POP n' PUSH:
Id:4,CompanyName:Trucks R Us,ShipperType:Automobiles,DateCreated:2010-01-31T11:53:37.8539401Z,UniqueRef:67d7d4947ebc4b0ba5c4d42f5d903bec
Id:1,CompanyName:Trains R Us,ShipperType:Trains,DateCreated:2010-01-31T11:53:37.7169323Z,UniqueRef:d17c5db0415b44b2ac5da7b6ebd780f5
Id:2,CompanyName:Planes R Us,ShipperType:Planes,DateCreated:2010-01-31T11:53:37.799937Z,UniqueRef:e02a73191f4b4e7a9c44eef5b5965d06

PROSPECTIVE SHIPPERS AFTER POP n' PUSH:

POPPED a SHIPPER:
Id:2,CompanyName:Planes R Us,ShipperType:Planes,DateCreated:2010-01-31T11:53:37.799937Z,UniqueRef:e02a73191f4b4e7a9c44eef5b5965d06

CURRENT SHIPPERS AFTER POP:
Id:4,CompanyName:Trucks R Us,ShipperType:Automobiles,DateCreated:2010-01-31T11:53:37.8539401Z,UniqueRef:67d7d4947ebc4b0ba5c4d42f5d903bec
Id:1,CompanyName:Trains R Us,ShipperType:Trains,DateCreated:2010-01-31T11:53:37.7169323Z,UniqueRef:d17c5db0415b44b2ac5da7b6ebd780f5

DELETING CURRENT AND PROSPECTIVE SHIPPERS:

Więcej przykładów jest dostępnych na [stronie przykładów RedisExamples Redis] oraz w obszernym zestawie testów

Prędkość #

Jedną z najlepszych rzeczy w Redis jest szybkość — jest szybka.

Poniższy przykład przechowuje i pobiera całą bazę danych Northwind (3202 rekordy) w mniej 1,2 s - nigdy nie mieliśmy tego tak szybko!

(Uruchamianie w ramach testu jednostkowego VS.NET/R# na 3-letnim komputerze iMac)

using var client = new RedisClient();

var before = DateTime.Now;
client.StoreAll(NorthwindData.Categories);
client.StoreAll(NorthwindData.Customers);
client.StoreAll(NorthwindData.Employees);
client.StoreAll(NorthwindData.Shippers);
client.StoreAll(NorthwindData.Orders);
client.StoreAll(NorthwindData.Products);
client.StoreAll(NorthwindData.OrderDetails);
client.StoreAll(NorthwindData.CustomerCustomerDemos);
client.StoreAll(NorthwindData.Regions);
client.StoreAll(NorthwindData.Territories);
client.StoreAll(NorthwindData.EmployeeTerritories);

Console.WriteLine("Took {0}ms to store the entire Northwind database ({1} records)",
    (DateTime.Now - before).TotalMilliseconds, totalRecords);

before = DateTime.Now;
var categories = client.GetAll<Category>();
var customers = client.GetAll<Customer>();
var employees = client.GetAll<Employee>();
var shippers = client.GetAll<Shipper>();
var orders = client.GetAll<Order>();
var products = client.GetAll<Product>();
var orderDetails = client.GetAll<OrderDetail>();
var customerCustomerDemos = client.GetAll<CustomerCustomerDemo>();
var regions = client.GetAll<Region>();
var territories = client.GetAll<Territory>();
var employeeTerritories = client.GetAll<EmployeeTerritory>();

Console.WriteLine("Took {0}ms to get the entire Northwind database ({1} records)",
    (DateTime.Now - before).TotalMilliseconds, totalRecords);
/*
== EXAMPLE OUTPUT ==

Took 1020.0583ms to store the entire Northwind database (3202 records)
Took 132.0076ms to get the entire Northwind database (3202 records)
*/

Uwaga:Całkowity czas obejmuje dodatkową operację Redis dla każdego rekordu w celu przechowywania identyfikatora w zestawie Redis dla każdego typu, a także serializację i deserializację każdego rekordu za pomocą TypeSerializera Service Stack.

Operacje Lex #

Dodano nowe operacje na posortowanych zestawach ZRANGEBYLEX, które pozwalają na zapytanie leksykalne dla posortowanego zestawu. Dobra prezentacja tego jest dostępna na autocomplete.redis.io.

Te nowe operacje są dostępne jako mapowanie 1:1 z serwerem redis na IRedisNativeClient :

public interface IRedisNativeClient
{
    ...
    byte[][] ZRangeByLex(string setId, string min, string max, int? skip, int? take);
    long ZLexCount(string setId, string min, string max);
    long ZRemRangeByLex(string setId, string min, string max);
}

I bardziej przyjazne dla użytkownika interfejsy API w IRedisClient :

public interface IRedisClient
{
    ...
    List<string> SearchSortedSet(string setId, string start=null, string end=null);
    long SearchSortedSetCount(string setId, string start=null, string end=null);
    long RemoveRangeFromSortedSetBySearch(string setId, string start=null, string end=null);
}

Podobnie jak dopasowujące wersje NuGet, Redis używa [ char do wyrażenia inkluzywności i ( char dla wyłączności. Ponieważ IRedisClient Interfejsy API są domyślnie wyszukiwane łącznie, te dwa interfejsy API są takie same:

Redis.SearchSortedSetCount("zset", "a", "c")
Redis.SearchSortedSetCount("zset", "[a", "[c")

Alternatywnie możesz określić jedno lub oba ograniczenia jako wyłączne, używając ( prefiks, np.:

Redis.SearchSortedSetCount("zset", "a", "(c")
Redis.SearchSortedSetCount("zset", "(a", "(c")

Więcej przykładów API jest dostępnych w LexTests.cs.

HyperLog API #

Gałąź rozwojowa serwera Redis (dostępna po wydaniu v3.0) zawiera pomysłowy algorytm przybliżający unikalne elementy w zestawie z maksymalną wydajnością przestrzenną i czasową. Aby uzyskać szczegółowe informacje o tym, jak to działa, zobacz blog twórcy Redis, Salvatore, który wyjaśnia to bardzo szczegółowo. Zasadniczo pozwala utrzymać skuteczny sposób liczenia i łączenia unikalnych elementów w zestawie bez konieczności przechowywania jego elementów. Prosty przykład w działaniu:

redis.AddToHyperLog("set1", "a", "b", "c");
redis.AddToHyperLog("set1", "c", "d");
var count = redis.CountHyperLog("set1"); //4

redis.AddToHyperLog("set2", "c", "d", "e", "f");

redis.MergeHyperLogs("mergedset", "set1", "set2");

var mergeCount = redis.CountHyperLog("mergedset"); //6

Skanuj interfejsy API #

W Redis v2.8 wprowadzono nową, piękną operację SCAN, która zapewnia optymalną strategię przechodzenia przez cały zestaw kluczy instancji Redis w porcjach o możliwej do zarządzania wielkością, wykorzystując tylko kursor po stronie klienta i bez wprowadzania żadnego stanu serwera. Jest to alternatywa o wyższej wydajności i powinna być używana zamiast KEYS w kodzie aplikacji. SKANOWANIE i powiązane z nim operacje dotyczące przechodzenia przez członków zestawów, posortowanych zestawów i skrótów są teraz dostępne w kliencie Redis w następujących interfejsach API:

public interface IRedisClient
{
    ...
    IEnumerable<string> ScanAllKeys(string pattern = null, int pageSize = 1000);
    IEnumerable<string> ScanAllSetItems(string setId, string pattern = null, int pageSize = 1000);
    IEnumerable<KeyValuePair<string, double>> ScanAllSortedSetItems(string setId, string pattern = null, int pageSize = 1000);
    IEnumerable<KeyValuePair<string, string>> ScanAllHashEntries(string hashId, string pattern = null, int pageSize = 1000);    
}

public interface IRedisClientAsync
{
    IAsyncEnumerable<string> ScanAllKeysAsync(string pattern = null, int pageSize, CancellationToken ct);
    IAsyncEnumerable<string> ScanAllSetItemsAsync(string setId, string pattern = null, int pageSize, CancellationToken ct);
    IAsyncEnumerable<KeyValuePair<string, double>> ScanAllSortedSetItemsAsync(string setId, string pattern = null, int pageSize, ct);
    IAsyncEnumerable<KeyValuePair<string, string>> ScanAllHashEntriesAsync(string hashId, string pattern = null, int pageSize, ct);
}

//Low-level API
public interface IRedisNativeClient
{
    ...
    ScanResult Scan(ulong cursor, int count = 10, string match = null);
    ScanResult SScan(string setId, ulong cursor, int count = 10, string match = null);
    ScanResult ZScan(string setId, ulong cursor, int count = 10, string match = null);
    ScanResult HScan(string hashId, ulong cursor, int count = 10, string match = null);
}

public interface IRedisNativeClientAsync 
{
    ValueTask<ScanResult> ScanAsync(ulong cursor, int count = 10, string match = null, CancellationToken ct);
    ValueTask<ScanResult> SScanAsync(string setId, ulong cursor, int count = 10, string match = null, CancellationToken ct);
    ValueTask<ScanResult> ZScanAsync(string setId, ulong cursor, int count = 10, string match = null, CancellationToken ct);
    ValueTask<ScanResult> HScanAsync(string hashId, ulong cursor, int count = 10, string match = null, CancellationToken ct);
}

IRedisClient zapewnia interfejs API wyższego poziomu, który oddziela kursor klienta, aby odsłonić leniwą sekwencję Enumerable, aby zapewnić optymalny sposób strumieniowania zeskanowanych wyników, który dobrze integruje się z LINQ, np.:

var scanUsers = Redis.ScanAllKeys("urn:User:*");
var sampleUsers = scanUsers.Take(10000).ToList(); //Stop after retrieving 10000 user keys 

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jak bezpiecznie połączyć się z Heroku Redis za pomocą wiersza poleceń?

  2. Co można zrobić za pomocą asynchronicznych zadań w tle CKAN?

  3. Jedis — kiedy używać metody returnBrokenResource()

  4. Korzystanie z Redis SCAN w NODE

  5. Używanie Redis z Node.js i Socket.IO