Introdução
Redis Sets são uma implementação de um conjunto matemático. E tem as seguintes características:
- Eles são desordenados.
- Eles não permitem duplicação, portanto não há membros repetidos.
- Eles podem ser combinados para criar novos conjuntos.
Redis Sets na prática
Imaginemos que estejamos criando um MMORPG e temos esses 5 conjuntos de usuários
- ActiveUsers
- InactiveUsers
- OnlineUsers
- OfflineUsers
- AllUsers
Agora vamos preencher nossos conjuntos de usuários ativos, inativos e offline. Para fazer isso, usaremos o método SetAddAsync
. Este método é variável, então podemos fazer isso em um comando para cada conjunto.
var activeUsers = new string[] { "User:1", "User:2" };
var inactiveUsers = new string[] { "User:3", "User:4" };
var offlineUsers = new string[] { "User:5", "User:6", "User:7" };
await database.SetAddAsync(activeUsersKey, activeUsers.Select(u => (RedisValue)u).ToArray());
await database.SetAddAsync(inactiveUsersKey, inactiveUsers.Select(u => (RedisValue)u).ToArray());
await database.SetAddAsync(offlineUsersKey, offlineUsers.Select(u => (RedisValue)u).ToArray());
Combinando conjuntos para obter todos os usuários
Não preenchemos nosso conjunto allUsersKey
. Se considerarmos active, inactive, offline, podemos usar as operações de combinação de conjuntos para obter um conjunto com todos os nossos usuários.
await database.SetCombineAndStoreAsync(SetOperation.Union, allUsersKey, new RedisKey[] { activeUsersKey, inactiveUsersKey, offlineUsersKey });
Verificar associação
Os conjuntos não permitem a duplicação, mas permitem verificações de associação O(1) muito rápidas. Portanto, se quiséssemos verificar se User:6 está offline, poderíamos fazê-lo facilmente:
var user6Offline = await database.SetContainsAsync(offlineUsersKey, "User:6");
Console.WriteLine($"User:6 offline: {user6Offline}");
// output
User:6 offline: True
Enumerar Conjunto
Quando você deseja enumerar os membros de um conjunto, tem duas opções: pode enumerar todos de uma vez ou pode examinar o conjunto e enumerar tudo.
Enumerar todo o conjunto
Se você quiser garantir que está enumerando todo o conjunto em uma viagem de ida e volta, poderá fazê-lo usando o método SetMembersAsync
. Isso usará o comando SMEMBERS
no Redis. Se o seu conjunto for relativamente compacto (abaixo de 1.000 membros), essa é uma maneira perfeitamente válida de retirar todos os membros do conjunto.
Console.WriteLine($"All Users In one shot: {string.Join(", ", await database.SetMembersAsync(allUsersKey))}");
// output
All Users In one shot: User:3, User:1, User:4, User:6, User:7, User:2, User:5
Enumerar Conjunto em Blocos
A maneira alternativa de enumerar um conjunto é enumerar com SetScanAsync
, que criará um Set Enumerator e usará o comando SSCAN
para varrer todo o conjunto até que o conjunto se esgote.
Console.Write("All Users with scan: ");
await foreach (var user in database.SetScanAsync(allUsersKey))
{
Console.Write($"{user}, ");
}
// output
All Users with scan: User:1, User:2, User:3, User:6, User:7, User:5, User:4,
Mover elementos entre conjuntos
ma operação muito normal que você pode precisar executar com conjuntos é mover elementos entre eles. Por exemplo, se User:1 fosse mover offline, você pode usar SetMoveAsync
para movê-los do conjunto de usuários ativos para o conjunto de usuários offline.
Console.WriteLine($"Moving User:1 from active to offline");
var moved = await database.SetMoveAsync(activeUsersKey, offlineUsersKey, "User:1");
Console.WriteLine($"Move successful: {moved}");
// output
Move successful: True
Conclusão
O Redis Sets é uma implementação de um conjunto matemático com recursos avançados. Eles são desordenados, não permitem duplicação e permitem a combinação de conjuntos para criar novos conjuntos. A combinação de conjuntos é uma funcionalidade que permite a criação de novos conjuntos por meio da união, interseção ou diferença entre conjuntos. Os conjuntos Redis são particularmente úteis para operações que exigem associação O(1), como verificar se um elemento pertence a um conjunto, e também para a manipulação de membros de conjuntos comuns, como adicionar ou remover um membro. O Redis Sets fornece muitas outras operações úteis, como enumerar conjuntos em blocos e mover elementos entre conjuntos. Em resumo, o Redis Sets é uma ferramenta poderosa e flexível para lidar com conjuntos de dados e é amplamente utilizado em muitas aplicações.
Código completo
using StackExchange.Redis;
using System.Diagnostics;
var options = new ConfigurationOptions
{
EndPoints = new EndPointCollection { "localhost:6379" }
};
var conn = ConnectionMultiplexer.Connect(options);
var database = conn.GetDatabase();
var allUsersKey = "users";
var activeUsersKey = "users:state:active";
var inactiveUsersKey = "users:state:inactive";
var offlineUsersKey = "users:state:offline";
await database.KeyDeleteAsync(new RedisKey[] { allUsersKey, activeUsersKey, inactiveUsersKey, offlineUsersKey });
var activeUsers = new string[] { "User:1", "User:2" };
var inactiveUsers = new string[] { "User:3", "User:4" };
var offlineUsers = new string[] { "User:5", "User:6", "User:7" };
await database.SetAddAsync(activeUsersKey, activeUsers.Select(u => (RedisValue)u).ToArray());
await database.SetAddAsync(inactiveUsersKey, inactiveUsers.Select(u => (RedisValue)u).ToArray());
await database.SetAddAsync(offlineUsersKey, offlineUsers.Select(u => (RedisValue)u).ToArray());
await database.SetCombineAndStoreAsync(SetOperation.Union, allUsersKey, new RedisKey[] { activeUsersKey, inactiveUsersKey, offlineUsersKey });
var user6Offline = await database.SetContainsAsync(offlineUsersKey, "User:6");
Console.WriteLine($"User:6 offline: {user6Offline}");
Console.WriteLine($"All Users In one shot: {string.Join(", ", await database.SetMembersAsync(allUsersKey))}");
Console.Write("All Users with scan: ");
await foreach (var user in database.SetScanAsync(allUsersKey))
{
Console.Write($"{user}, ");
}
Console.WriteLine($"Moving User:1 from active to offline");
var moved = await database.SetMoveAsync(activeUsersKey, offlineUsersKey, "User:1");
Console.WriteLine($"Move successful: {moved}");
Latest comments (0)