Explorar a API de cliente para interagir com a Redis
Como mencionado anteriormente, o Redis é um banco de dados NoSQL na memória, que pode ser replicado em vários servidores. É frequentemente usado como um cache, mas pode ser usado como um banco de dados formal ou até mesmo como um agente de mensagens.
O Redis pode armazenar vários tipos de dados e estruturas. Ele suporta vários comandos que você pode emitir para recuperar dados armazenados em cache ou para consultar informações sobre o próprio cache. Os dados com que trabalha são sempre armazenados como pares chave/Valor.
Executar comandos no cache Redis
Geralmente, a aplicação cliente utiliza uma biblioteca de cliente para criar pedidos e executar comandos numa cache de Redis. Pode obter uma lista de bibliotecas de cliente diretamente na página de clientes do Redis. Um cliente de Redis popular de desempenho elevado para a plataforma .NET é o StackExchange.Redis. O pacote está disponível através do NuGet, e você pode adicioná-lo ao seu código .NET usando a linha de comando ou IDE.
Conecte-se ao cache Redis com StackExchange.Redis
Lembre-se de que utilizamos o endereço do anfitrião, o número de porta e uma chave de acesso para ligar a um servidor Redis. O Azure também oferece uma cadeia de conexão para alguns clientes Redis, que agrupa esses dados em uma única cadeia de caracteres.
O que é uma cadeia de ligação?
Uma cadeia de ligação é uma linha de texto que inclui todas as informações necessárias para ligar e autenticar uma cache de Redis no Azure. É semelhante ao seguinte (com os campos cache-name and password-here preenchidos com valores reais):
[cache-name].redis.cache.windows.net:6380,password=[password-here],ssl=True,abortConnect=False
Gorjeta
A cadeia de ligação deve estar protegida na sua aplicação. Se a aplicação estiver alojada no Azure, pondere utilizar um cofre do Azure Key Vault para armazenar o valor.
Você pode passar essa cadeia de caracteres para StackExchange.Redis para criar uma conexão com o servidor.
Observe que há mais dois parâmetros no final:
- SSL: Garante que a comunicação é criptografada
- abortConnection: permite que uma conexão seja criada mesmo que o servidor esteja indisponível naquele momento
Pode anexar vários outros parâmetros opcionais à cadeia para configurar a biblioteca de cliente.
Criar uma ligação
O objeto de cadeia principal em StackExchange.Redis é a classe StackExchange.Redis.ConnectionMultiplexer
. Este objeto abstrai o processo de ligação a um servidor Redis (ou a um grupo de servidores). Está otimizado para gerir as ligações de forma eficiente e deve permanecer por perto enquanto precisa de acesso à cache.
Para criar uma instância ConnectionMultiplexer
, vai utilizar o ConnectionMultiplexer.Connect
estático ou o método ConnectionMultiplexer.ConnectAsync
e transmitir uma cadeia de ligação ou um objeto ConfigurationOptions
.
Eis um exemplo simples:
using StackExchange.Redis;
...
var connectionString = "[cache-name].redis.cache.windows.net:6380,password=[password-here],ssl=True,abortConnect=False";
var redisConnection = ConnectionMultiplexer.Connect(connectionString);
// ^^^ store and re-use this!!!
Depois de ter um ConnectionMultiplexer
, há três coisas principais que você pode querer fazer:
- Aceda a uma Base de Dados Redis (o foco deste módulo).
- Faça uso dos recursos de editor/subscrito do Redis (fora do escopo deste módulo).
- Aceder a um servidor individual para fins de manutenção ou monitorização.
Aceder a uma base de dados Redis
A base de dados do Redis é representada pelo tipo IDatabase
. Pode obter uma com o método GetDatabase()
:
IDatabase db = redisConnection.GetDatabase();
Gorjeta
O objeto retornado é GetDatabase
um objeto leve e não precisa ser armazenado. Só é necessário manter o objeto ConnectionMultiplexer
ativo.
Quando tiver um objeto IDatabase
, pode executar métodos para interagir com a cache. Todos os métodos têm versões síncronas e assíncronas, que retornam Task
objetos para torná-los compatíveis com as async
palavras-chave e await
.
Aqui está um exemplo de armazenamento de uma chave/valor no cache:
bool wasSet = db.StringSet("favorite:flavor", "i-love-rocky-road");
O método StringSet
devolve um bool
, que indica se o valor foi definido (true
) ou não (false
). Depois, podemos obter o valor com o método StringGet
:
string value = db.StringGet("favorite:flavor");
Console.WriteLine(value); // displays: ""i-love-rocky-road""
Obter e definir valores binários
Lembre-se de que as chaves e os valores de Redis são binary safe. Você pode usar esses mesmos métodos para armazenar dados binários. Existem operadores de conversão implícitos que funcionam com os tipos byte[]
, para que possa trabalhar com os dados naturalmente:
byte[] key = ...;
byte[] value = ...;
db.StringSet(key, value);
byte[] key = ...;
byte[] value = db.StringGet(key);
Gorjeta
StackExchange.Redis utiliza o tipo RedisKey
para representar chaves. Esta classe tem conversões implícitas para e de string
e byte[]
, permitindo a utilização de texto e chaves binárias sem qualquer complicação. Os valores são representados pelo tipo RedisValue
. Tal como com o tipo RedisKey
, existem conversões implícitas que lhe permitem transmitir string
ou byte[]
.
Outras operações comuns
A interface IDatabase
inclui vários outros métodos para trabalhar com a cache de Redis. Há métodos para trabalhar com hashes, listas, conjuntos e conjuntos ordenados.
Aqui estão algumas das operações mais comuns que funcionam com chaves únicas; Você pode ler o código-fonte da interface para ver a lista completa.
Método | Description |
---|---|
CreateBatch |
Cria um grupo de operações que será enviado para o servidor como uma única unidade, mas não processado como tal necessariamente. |
CreateTransaction |
Cria um grupo de operações que será enviado para o servidor como uma única unidade e processado como tal. |
KeyDelete |
Exclui a chave/valor. |
KeyExists |
Devolve se a chave específica existe na cache. |
KeyExpire |
Define uma expiração de time-to-live (TTL) numa chave. |
KeyRename |
Muda o nome de uma chave. |
KeyTimeToLive |
Devolve o TTL de uma chave. |
KeyType |
Devolve a representação da cadeia do tipo do valor armazenado na chave. Os diferentes tipos que podem ser retornados são: string, list, set, zset e hash. |
Executar outros comandos
O IDatabase
objeto tem um Execute
método and ExecuteAsync
, que pode ser usado para passar comandos textuais para o servidor Redis. Por exemplo:
var result = db.Execute("ping");
Console.WriteLine(result.ToString()); // displays: "PONG"
Os Execute
métodos e ExecuteAsync
retornam um RedisResult
objeto, que é um titular de dados que inclui duas propriedades:
Type
, que retorna umastring
indicação do tipo do resultado - "STRING", "INTEGER", etc.IsNull
, um valor verdadeiro/falso para detetar quando o resultado énull
.
Pode utilizar ToString()
em RedisResult
para obter o valor de retorno real.
Você pode usar Execute
para executar quaisquer comandos suportados. Por exemplo, podemos conectar todos os clientes ao cache ("LISTA DE CLIENTES"):
var result = await db.ExecuteAsync("client", "list");
Console.WriteLine($"Type = {result.Type}\r\nResult = {result}");
Os comandos anteriores produzem todos os clientes conectados:
Type = BulkString
Result = id=9469 addr=16.183.122.154:54961 fd=18 name=DESKTOP-AAAAAA age=0 idle=0 flags=N db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 ow=0 owmem=0 events=r cmd=subscribe numops=5
id=9470 addr=16.183.122.155:54967 fd=13 name=DESKTOP-BBBBBB age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 ow=0 owmem=0 events=r cmd=client numops=17
Armazene valores mais complexos
O Redis é orientado em torno de cadeias binárias seguras, mas você pode armazenar em cache gráficos de objetos serializando-os para um formato textual; normalmente XML ou JSON. Por exemplo, talvez para as nossas estatísticas, temos um GameStat
objeto, que se parece com:
public class GameStat
{
public string Id { get; set; }
public string Sport { get; set; }
public DateTimeOffset DatePlayed { get; set; }
public string Game { get; set; }
public IReadOnlyList<string> Teams { get; set; }
public IReadOnlyList<(string team, int score)> Results { get; set; }
public GameStat(string sport, DateTimeOffset datePlayed, string game, string[] teams, IEnumerable<(string team, int score)> results)
{
Id = Guid.NewGuid().ToString();
Sport = sport;
DatePlayed = datePlayed;
Game = game;
Teams = teams.ToList();
Results = results.ToList();
}
public override string ToString()
{
return $"{Sport} {Game} played on {DatePlayed.Date.ToShortDateString()} - " +
$"{String.Join(',', Teams)}\r\n\t" +
$"{String.Join('\t', Results.Select(r => $"{r.team } - {r.score}\r\n"))}";
}
}
Podemos utilizar a biblioteca Newtonsoft.Json para transformar uma instância deste objeto numa cadeia:
var stat = new GameStat("Soccer", new DateTime(1950, 7, 16), "FIFA World Cup",
new[] { "Uruguay", "Brazil" },
new[] { ("Uruguay", 2), ("Brazil", 1) });
string serializedValue = Newtonsoft.Json.JsonConvert.SerializeObject(stat);
bool added = db.StringSet("event:1950-world-cup", serializedValue);
Podemos utilizar o processo inverso e obtê-la e transformá-la de novo num objeto.
var result = db.StringGet("event:1950-world-cup");
var stat = Newtonsoft.Json.JsonConvert.DeserializeObject<GameStat>(result.ToString());
Console.WriteLine(stat.Sport); // displays "Soccer"
Limpar a ligação
Depois de concluir a conexão Redis, você pode descartar o ConnectionMultiplexer
arquivo . Este comando fecha todas as conexões e desliga a comunicação com o servidor:
redisConnection.Dispose();
redisConnection = null;
Vamos criar um aplicativo e fazer algum trabalho com nosso cache Redis.
Como mencionado anteriormente, o Redis é um banco de dados NoSQL na memória, que pode ser replicado em vários servidores. Muitas vezes é usado como um cache, mas pode ser usado como um banco de dados formal ou até mesmo um agente de mensagens.
O Redis pode armazenar vários tipos de dados e estruturas. Ele suporta vários comandos que você pode emitir para recuperar dados armazenados em cache ou consultar informações sobre o próprio cache. Os dados com que trabalha são sempre armazenados como pares chave/Valor.
Executar comandos no cache Redis
Geralmente, a aplicação cliente utiliza uma biblioteca de cliente para criar pedidos e executar comandos numa cache de Redis. Pode obter uma lista de bibliotecas de cliente diretamente na página de clientes do Redis. Um cliente do Redis popular para JavaScript é o pacote redis, que pode adicionar a um projeto com o comando npm install redis
.
Conecte-se ao cache Redis com o pacote redis
A interação com uma cache de Redis é obtida com a classe RedisClient
. Na maioria dos cenários, o seguinte código de texto automático é a melhor maneira de criar uma classe RedisClient
com ligação a uma cache de Redis no Azure:
const client = redis.createClient(
port, // the port number, 6380 by default
hostname, // <resourceName>.redis.cache.windows.net
{
password: accessKey, // the primary or secondary access key
tls: { servername: hostname }
}
);
Na maioria dos casos, deve evitar criar múltiplas classes RedisClient
. Uma única instância da classe RedisClient
pode ser passada e utilizada em qualquer parte do seu código em que a Redis seja necessária.
Trabalhar com um banco de dados Redis
Os comandos Redis são representados como métodos com RedisClient
os nomes como os próprios comandos. Eis um exemplo de como armazenar um novo valor na cache:
client.set("myKey", "myValue"); // executes "set myKey myValue" on the cache
Todos os métodos de comandos na classe RedisClient
são assíncronos e suportam um argumento de chamada de retorno opcional que fornece o resultado. O redis
pacote não suporta Promessas (e, portanto,await
async
/ou encadeamento com.then()
) fora da caixa. A forma mais fácil de utilizar os comandos async
/await
ou .then()
com a classe RedisClient
é adicionar suporte para Promessas a todo o cliente ao mesmo tempo com a função promisifyAll
do pacote bluebird
:
var redis = require("redis");
var Promise = require("bluebird");
Promise.promsifyAll(redis);
A promisifyAll
função adicionará XXXAsync
versões de todos os métodos de comando às RedisClient
instâncias, permitindo que você use métodos assíncronos como no exemplo a seguir:
var result = await client.setAsync("myKey", "myValue");
Executar comandos dinamicamente
Você pode enviar comandos dinamicamente usando sendCommand()
(ou sendCommandAsync()
com bluebird) para enviar qualquer string como um comando para o cache. Por exemplo, seu aplicativo pode apresentar um prompt para enviar comandos diretamente para o cache ou o Redis pode introduzir novos comandos que o redis
pacote não suporta. Os argumentos de comandos têm de ser enviados como uma matriz.
// Add a key/value pair
var result = await client.sendCommandAsync("set", ["myKey", "myValue"]);
Limpar a ligação
Depois de terminar a conexão Redis, você deve fechá-la com quit()
(ou quitAsync()
ao usar o bluebird):
await client.quitAsync();
Vamos criar um aplicativo e fazer algum trabalho com nosso cache Redis.