码迷,mamicode.com
首页 > 其他好文 > 详细

Redis学习指南

时间:2019-08-02 14:40:57      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:line   ==   out   tar   argv   mat   passing   ext   分布   

Redis学习指南

一、数据结构

  • string(字符串)

  • list(列表)

  • set(集合)

  • hash(散列)

  • zset(有序集合)

二、命令列表

2.1 Redis Strings

> set mykey somevalue
OK
> get mykey
"somevalue"
> set counter 100
OK
> incr counter
(integer) 101
> incr counter
(integer) 102
> incrby counter 50
(integer) 152
> mset a 10 b 20 c 30
OK
> mget a b c
1) "10"
2) "20"
3) "30"
> set mykey hello
OK
> exists mykey
(integer) 1
> del mykey
(integer) 1
> exists mykey
(integer) 0
> set mykey x
OK
> type mykey
string
> del mykey
(integer) 1
> type mykey
none
> set key some-value
OK
> expire key 5
(integer) 1
> get key (immediately)
"some-value"
> get key (after some time)
(nil)
> set key 100 ex 10
OK
> 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 -1
1) "first"
2) "A"
3) "B"
> rpush mylist 1 2 3 4 5 "foo bar"
(integer) 9
> lrange mylist 0 -1
1) "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 2
OK
> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
> brpop tasks 5
1) "tasks"
2) "do_something"

2.3 Redis Hashes

> hmset user:1000 username antirez birthyear 1977 verified 1
OK
> hget user:1000 username
"antirez"
> hget user:1000 birthyear
"1977"
> hgetall user:1000
1) "username"
2) "antirez"
3) "birthyear"
4) "1977"
5) "verified"
6) "1"
> hmget user:1000 username birthyear no-such-field
1) "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 myset
1. 3
2. 1
3. 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 -1
1) "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();
      }
  }
}
?

 

Redis学习指南

标签:line   ==   out   tar   argv   mat   passing   ext   分布   

原文地址:https://www.cnblogs.com/xsddxz/p/11288242.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!