Redis学习指南
一、数据结构
- string(字符串)
- list(列表)
- set(集合)
- hash(散列)
- zset(有序集合)
二、命令列表
2.1 Redis Strings
> set mykey somevalueOK> get mykey"somevalue"
> set counter 100OK> incr counter(integer) 101> incr counter(integer) 102> incrby counter 50(integer) 152
> mset a 10 b 20 c 30OK> mget a b c1) "10"2) "20"3) "30"
> set mykey helloOK> exists mykey(integer) 1> del mykey(integer) 1> exists mykey(integer) 0
> set mykey xOK> type mykeystring> del mykey(integer) 1> type mykeynone
> set key some-valueOK> expire key 5(integer) 1> get key (immediately)"some-value"> get key (after some time)(nil)
> set key 100 ex 10OK> ttl key(integer) 9
2.2 Redis Lists
> rpush mylist A(integer) 1> rpush mylist B(integer) 2> lpush mylist first(integer) 3> lrange mylist 0 -11) "first"2) "A"3) "B"
> rpush mylist 1 2 3 4 5 "foo bar"(integer) 9> lrange mylist 0 -11) "first"2) "A"3) "B"4) "1"5) "2"6) "3"7) "4"8) "5"9) "foo bar"
> rpush mylist a b c(integer) 3> rpop mylist"c"> rpop mylist"b"> rpop mylist"a"
> rpush mylist 1 2 3 4 5(integer) 5> ltrim mylist 0 2OK> lrange mylist 0 -11) "1"2) "2"3) "3"
> brpop tasks 51) "tasks"2) "do_something"
2.3 Redis Hashes
> hmset user:1000 username antirez birthyear 1977 verified 1OK> hget user:1000 username"antirez"> hget user:1000 birthyear"1977"> hgetall user:10001) "username"2) "antirez"3) "birthyear"4) "1977"5) "verified"6) "1"
> hmget user:1000 username birthyear no-such-field1) "antirez"2) "1977"3) (nil)
> hincrby user:1000 birthyear 10(integer) 1987> hincrby user:1000 birthyear 10(integer) 1997
2.4 Redis Sets
> sadd myset 1 2 3(integer) 3> smembers myset1. 32. 13. 2
2.5 Redis Sorted Sets
> zadd hackers 1940 "Alan Kay"(integer) 1> zadd hackers 1957 "Sophie Wilson"(integer) 1> zadd hackers 1953 "Richard Stallman"(integer) 1> zadd hackers 1949 "Anita Borg"(integer) 1> zadd hackers 1965 "Yukihiro Matsumoto"(integer) 1> zadd hackers 1914 "Hedy Lamarr"(integer) 1> zadd hackers 1916 "Claude Shannon"(integer) 1> zadd hackers 1969 "Linus Torvalds"(integer) 1> zadd hackers 1912 "Alan Turing"(integer) 1?> zrange hackers 0 -11) "Alan Turing"2) "Hedy Lamarr"3) "Claude Shannon"4) "Alan Kay"5) "Anita Borg"6) "Richard Stallman"7) "Sophie Wilson"8) "Yukihiro Matsumoto"9) "Linus Torvalds"
三、应用示例
3.1 分布式锁
需要安装nuget包:StackExchange.Redis。
using StackExchange.Redis;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;?namespace Redlock.CSharp{ public class Lock {? public Lock(RedisKey resource, RedisValue val, TimeSpan validity) { this.resource = resource; this.val = val ; this.validity_time = validity; }? private RedisKey resource;? private RedisValue val;? private TimeSpan validity_time;? public RedisKey Resource { get { return resource; } }? public RedisValue Value { get { return val; } }? public TimeSpan Validity { get { return validity_time; } } }}?
using StackExchange.Redis;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;?namespace Redlock.CSharp{ public class Redlock {? public Redlock(params ConnectionMultiplexer[] list) { foreach(var item in list) this.redisMasterDictionary.Add(item.GetEndPoints().First().ToString(),item); }? const int DefaultRetryCount = 3; readonly TimeSpan DefaultRetryDelay = new TimeSpan(0, 0, 0, 0, 200); const double ClockDriveFactor = 0.01;? protected int Quorum { get { return (redisMasterDictionary.Count / 2) + 1; } }? /// <summary> /// String containing the Lua unlock script. /// </summary> const String UnlockScript = @" if redis.call(""get"",KEYS[1]) == ARGV[1] then return redis.call(""del"",KEYS[1]) else return 0 end";?? protected static byte[] CreateUniqueLockId() { return Guid.NewGuid().ToByteArray(); }?? protected Dictionary<String,ConnectionMultiplexer> redisMasterDictionary = new Dictionary<string,ConnectionMultiplexer>();? //TODO: Refactor passing a ConnectionMultiplexer protected bool LockInstance(string redisServer, string resource, byte[] val, TimeSpan ttl) { bool succeeded; try { var redis = this.redisMasterDictionary[redisServer]; succeeded = redis.GetDatabase().StringSet(resource, val, ttl, When.NotExists); } catch (Exception) { succeeded = false; } return succeeded; }? //TODO: Refactor passing a ConnectionMultiplexer protected void UnlockInstance(string redisServer, string resource, byte[] val) { RedisKey[] key = { resource }; RedisValue[] values = { val }; var redis = redisMasterDictionary[redisServer]; redis.GetDatabase().ScriptEvaluate( UnlockScript, key, values ); }? public bool Lock(RedisKey resource, TimeSpan ttl, out Lock lockObject) { var val = CreateUniqueLockId(); Lock innerLock = null; bool successfull = retry(DefaultRetryCount, DefaultRetryDelay, () => { try { int n = 0; var startTime = DateTime.Now;? // Use keys for_each_redis_registered( redis => { if (LockInstance(redis, resource, val, ttl)) n += 1; } );? /* * Add 2 milliseconds to the drift to account for Redis expires * precision, which is 1 millisecond, plus 1 millisecond min drift * for small TTLs. */ var drift = Convert.ToInt32((ttl.TotalMilliseconds * ClockDriveFactor) + 2); var validity_time = ttl - (DateTime.Now - startTime) - new TimeSpan(0, 0, 0, 0, drift);? if (n >= Quorum && validity_time.TotalMilliseconds > 0) { innerLock = new Lock(resource, val, validity_time); return true; } else { for_each_redis_registered( redis => { UnlockInstance(redis, resource, val); } ); return false; } } catch (Exception) { return false; } });? lockObject = innerLock; return successfull; }? protected void for_each_redis_registered(Action<ConnectionMultiplexer> action) { foreach (var item in redisMasterDictionary) { action(item.Value); } }? protected void for_each_redis_registered(Action<String> action) { foreach (var item in redisMasterDictionary) { action(item.Key); } }? protected bool retry(int retryCount, TimeSpan retryDelay, Func<bool> action) { int maxRetryDelay = (int)retryDelay.TotalMilliseconds; Random rnd = new Random(); int currentRetry = 0;? while (currentRetry++ < retryCount) { if (action()) return true; Thread.Sleep(rnd.Next(maxRetryDelay)); } return false; }? public void Unlock(Lock lockObject) { for_each_redis_registered(redis => { UnlockInstance(redis, lockObject.Resource, lockObject.Value); }); }? public override string ToString() { StringBuilder sb = new StringBuilder(); sb.AppendLine(this.GetType().FullName);? sb.AppendLine("Registered Connections:"); foreach(var item in redisMasterDictionary) { sb.AppendLine(item.Value.GetEndPoints().First().ToString()); }? return sb.ToString(); } }}?
原文地址:https://www.cnblogs.com/xsddxz/p/11288242.html
时间: 2024-10-10 09:21:24