Redis学习指南

Posted xsddxz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis学习指南相关的知识,希望对你有一定的参考价值。

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学习指南的主要内容,如果未能解决你的问题,请参考以下文章

Redis学习四(运维指南).

Redis学习笔记

Redis学习指南

Redis学习笔记jedis(JedisCluster)操作Redis集群 redis-cluster

Redis学习笔记Redis安装和启动

redis学习基础概念摘抄