redis--ServiceStack

using System;

namespace MyRedis
{
    class Program
    {
        static void Main(string[] args)
        {
            //大量数据的读写,硬盘的速度满足不了,所以产生NoSQL
            //特点:基于内存;
            //      没有严格的数据格式,没有行列的概念

            //redis: Remote Dictionary Server   远程字典服务器
            //       基于内存管理,实现了5中数据结构(string,List,Set,ZSet,Hash),对应不同的需求
            //       单线程模型的应用程序(单进程单线程),对外提供插入--查询--固化--集群功能

            //redis--SqlServer
            //redis-cli========SqlClient
            //redis支持的命令========sql语句
            //RDM========可视化的SqlClient
            //ServiceStack(1小时3600次,可破解)---Ado.net
            //StackExchange 免费 ---Ado.net
            //其实Ado.net不准确,更像ORM,封装了链接和命令

            //redis 可以固化数据,VitualMemory,把一些不经常访问的数据存在硬盘,存储策略可以配置,两种方式
            //RDM:snapshot的方式把数据保存到硬盘,但再保存间隙down掉数据就丢失了
            //AOF:数据变化有日志记录,但是性能比较低,用的比较少
            //redis不是数据库,只能用来提升性能,不能作为数据的最终依据

            //多线程模型:可以更好的发挥硬件的性能;但是也有线程冲突和线程调度的成本
            //单线程模型:比如nodejs就是单线程,整个进程就只有一个线程,线程就是执行流
            //            单线程都是事件驱动,而且线程不做等待,如果任务A要等,就把任务A放到队列,线程就做下个任务了
            //单线程多进程的模式来提供集群服务

            //单线程最大的好处就是原子性操作
            //redis的每个命令都是原子性(因为是单线程),不用考虑并发

            //五大结构理解
            //String:key-value的缓存,支持过期,value最小512byte,最大不超过512M
            //Hase:hashId对应多个key-value节约空间(zipmap的存储模式),读取方便
            //Set:一个key对应多个value,就是数据集合,无序(虽然添加获取都排序了,但是不敢保证),去重
            //Zset:每个value多了个score权重的概念
            //List:链表,最多2的32次方-1个数据
            //  队列:把所有任务都放到队列中去,异步来处理这个队列中的任务
            //        1.实现流量削峰,降低数据库压力  
            //        2.可以控制从队列取任务执行的速度,如果多线程的话,可以控制并发数降低数据库压力  
            //        3.以前必须要立即处理完,现在可以放到一个时间段来处理  
            //        4.任务执行失败重新加入队列,实现失败重试 
            //        5.可扩展,放入队列的程序和取队列数据的程序都可以扩展 
            //        缺陷:不能立即处理返回结果,事务问题 

            //  分页
            //  生产者--消费者:多个程序写,多个程序消费,但是一个数据只能被消费一次
            //                 失败了把数据再放回来
            //  发布--订阅

            //redis只是用来提升性能的,不是用来存储数据的,无法代替数据库
            //缓存预热,重启缓存后,缓存没有了,需要初始化数据
            //缓存击穿/缓存穿透
            ServiceStackTest.Show();
            //OverSellTest.Show();
            //UserInfoTest.Show();
            //FriendManagerTest.Show();
            //RankManagerTest.Show();
            //BlogPageListTest.Show();
        }
    }
}
using RedisLibrary.Service;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyRedis
{
    public class ServiceStackTest
    {
        public static void Show()
        {
            {
                //Console.WriteLine("*****************String*****************");
                //using (RedisStringService service = new RedisStringService())
                //{
                //    service.Set("strudent1", "小王");
                //    Console.WriteLine(service.Get("strudent1"));

                //    service.Append("strudent1", "今年18岁");
                //    Console.WriteLine(service.Get("strudent1"));

                //    Console.WriteLine(service.GetAndSetValue("strudent1", "小高今年16岁"));
                //    Console.WriteLine(service.Get("strudent1"));

                //    service.Set("strudent2", "三三", DateTime.Now.AddSeconds(5));
                //    Thread.Sleep(4100);
                //    Console.WriteLine(service.Get("strudent2"));
                //    Thread.Sleep(1000);
                //    Console.WriteLine(service.Get("strudent2"));

                //    service.Set("Age", 20);
                //    Console.WriteLine(service.Get("Age"));
                //    Console.WriteLine(service.Incr("Age"));
                //    Console.WriteLine(service.IncrBy("Age", 5));
                //    Console.WriteLine(service.Decr("Age"));
                //    Console.WriteLine(service.DecrBy("Age", 7));
                //}
            }

            {
                //Console.WriteLine("*****************Hash*****************");
                //using (RedisHashService service = new RedisHashService())
                //{
                //    service.FlushAll();
                //    service.SetEntryInHash("strudent", "Id", "124");
                //    service.SetEntryInHash("strudent", "Account", "12345");
                //    service.SetEntryInHash("strudent", "Name", "小王");
                //    service.SetEntryInHash("strudent", "Age", "18");

                //    List<string> keys = service.GetHashKeys("student");
                //    List<string> values = service.GetHashKeys("student");
                //    Dictionary<string, string> keyValues = service.GetAllEntriesFromHash("student");
                //    Console.WriteLine(service.GetValueFromHash("strudent1", "Name"));

                //    service.SetEntryInHashIfNotExists("strudent", "Name", "小高");
                //    service.SetEntryInHashIfNotExists("strudent", "Habitation", "西安");
                //    service.SetEntryInHashIfNotExists("strudent1", "Habitation", "西安");

                //    Console.WriteLine(service.GetValueFromHash("strudent", "Name"));
                //    Console.WriteLine(service.GetValueFromHash("strudent", "Habitation"));
                //    service.RemoveEntryFromHash("strudent", "Habitation");
                //    Console.WriteLine(service.GetValueFromHash("strudent", "Habitation"));

                //    //不是数字加的话会报异常
                //    //service.IncrementValueInHash("strudent", "Name", 1);
                //    //Console.WriteLine(service.GetValueFromHash("strudent", "Name"));

                //    service.IncrementValueInHash("strudent", "Age", 1);
                //    Console.WriteLine(service.GetValueFromHash("strudent", "Age"));
                //}
            }

            {
                //Console.WriteLine("*****************Set*****************");
                //using (RedisSetService service = new RedisSetService())
                //{
                //    service.FlushAll();
                //    service.AddItemToSet("student", "124");
                //    service.AddItemToSet("student", "126");
                //    service.AddItemToSet("student", "126");
                //    service.AddItemToSet("student", "129");
                //    service.AddItemToSet("student", "129");
                //    service.AddItemToSet("student", "12");
                //    service.AddItemToSet("student", "129");

                //    HashSet<string> hashSet = service.GetAllItemsFromSet("student");
                //}
            }

            //{
            //    Console.WriteLine("*****************ZSet*****************");
            //    using (RedisZSetService service = new RedisZSetService())
            //    {
            //        service.FlushAll();
            //        service.AddItemToSortedSet("student", "1");
            //        service.AddItemToSortedSet("student", "2");
            //        service.AddItemToSortedSet("student", "3");
            //        service.AddItemToSortedSet("student", "6");
            //        service.AddItemToSortedSet("student", "5");
            //        service.AddItemToSortedSet("student", "4");

            //        service.AddItemToSortedSet("SortByScore", "1", 10);
            //        service.AddItemToSortedSet("SortByScore", "2", 120);
            //        service.AddItemToSortedSet("SortByScore", "3", 103);
            //        service.AddItemToSortedSet("SortByScore", "6", 1099);
            //        service.AddItemToSortedSet("SortByScore", "5", 1044);
            //        service.AddItemToSortedSet("SortByScore", "4", 1033);

            //        service.IncrementItemInSortedSet("SortByScore", "1", 10);
            //        service.IncrementItemInSortedSet("SortByScore", "111", 10);
            //        service.IncrementItemInSortedSet("SortByScore_111", "111", 10);
            //        //相同分数 数值是按照大小, 汉字无序
            //        List<string> list = new List<string>() { "13", "12", "11" };
            //        service.AddItemToSortedSet("SortByScore", list, 1076);

            //        List<string> list2 = new List<string>() { "小王", "中王", "大王" };
            //        service.AddItemToSortedSet("SortByScore", list2, 1076);

            //        List<string> rstList = service.GetAllItemsFromSortedSet("SortByScore");
            //        long indexValue = service.GetItemIndexInSortedSet("SortByScore", "4");
            //    }
            //}

            {
                Console.WriteLine("*****************List*****************");
                using (RedisListService service = new RedisListService())
                {
                    //service.FlushAll();
                    //service.Add("student", "1");
                    //service.Add("student", "2");
                    //service.Add("student", "3");
                    //service.Add("student", "6");
                    //service.Add("student", "5");
                    //service.Add("student", "4");

                    //var rst0 = service.GetAllItemsFromList("student");
                    按索引获取,这样就可以分页了
                    //var rst1 = service.GetAllItemsFromList("student", 0, 3);

                    //service.FlushAll();
                    //service.RPush("student", "1");
                    //service.RPush("student", "2");
                    //service.RPush("student", "3");
                    //service.RPush("student", "6");
                    //service.RPush("student", "5");
                    //service.RPush("student", "4");

                    //var rst2 = service.GetAllItemsFromList("student");
                    //Console.WriteLine("&&&&&&&&&&&&&&&&&&栈&&&&&&&&&&&&&&&&&&");
                    栈--先进后出:Add和pop配合实现效果
                    //service.FlushAll();
                    //service.Add("student", "1");
                    //service.Add("student", "2");
                    //service.Add("student", "3");
                    //service.Add("student", "6");
                    //service.Add("student", "5");
                    //service.Add("student", "4");
                    //for (int i = 0; i < 6; i++)
                    //{
                    //    Console.WriteLine(service.PopItemFromList("student"));
                    //}
                    //var rst3 = service.GetAllItemsFromList("student");
                    //Console.WriteLine("&&&&&&&&&&&&&&&&&&队列&&&&&&&&&&&&&&&&&&");
                    队列--先进先出:RPush和pop配合实现效果
                    队列实现生产者消费者模型
                    分布式缓存,多个服务器都可以访问,多个生产者,多个消费者,任何产品都只能被消费一次
                    //service.FlushAll();
                    //service.RPush("student", "1");
                    //service.RPush("student", "2");
                    //service.RPush("student", "3");
                    //service.RPush("student", "6");
                    //service.RPush("student", "5");
                    //service.RPush("student", "4");
                    //for (int i = 0; i < 6; i++)
                    //{
                    //    Console.WriteLine(service.PopItemFromList("student"));
                    //}
                    //var rst4 = service.GetAllItemsFromList("student");
                    #region 生产者消费者模式:多个生产者,多个消费者
                    //Console.WriteLine("*****************生产者消费者模型*****************");
                    //{
                    //    service.FlushAll();
                    //    service.Add("test", "这是一个学生Add1");
                    //    service.Add("test", "这是一个学生Add2");
                    //    service.Add("test", "这是一个学生Add3");

                    //    service.LPush("test", "这是一个学生LPush1");
                    //    service.LPush("test", "这是一个学生LPush2");
                    //    service.LPush("test", "这是一个学生LPush3");
                    //    service.LPush("test", "这是一个学生LPush4");
                    //    service.LPush("test", "这是一个学生LPush5");
                    //    service.LPush("test", "这是一个学生LPush6");

                    //    service.RPush("test", "这是一个学生RPush1");
                    //    service.RPush("test", "这是一个学生RPush2");
                    //    service.RPush("test", "这是一个学生RPush3");
                    //    service.RPush("test", "这是一个学生RPush4");
                    //    service.RPush("test", "这是一个学生RPush5");
                    //    service.RPush("test", "这是一个学生RPush6");

                    //    List<string> strList = new List<string>();
                    //    for (int i = 0; i < 10; i++)
                    //    {
                    //        strList.Add($"放入任务{i}");
                    //    }
                    //    service.Add("task", strList);
                    //    Console.WriteLine(service.GetListCount("test"));
                    //    Console.WriteLine(service.GetListCount("task"));

                    //    var list = service.GetAllItemsFromList("test");
                    //    var list2 = service.GetAllItemsFromList("task", 2, 4);

                    //    Task.WaitAll(Task.Run(() =>
                    //    {
                    //        while (true)
                    //        {
                    //            Console.WriteLine("************请输入数据*************");
                    //            string testTask = Console.ReadLine();
                    //            service.LPush("test", testTask);
                    //        }
                    //    }));
                    //}
                    #endregion

                    #region 发布订阅:观察者,一个数据源;多个接收者,只要订阅就能收到,能被多个数据源共享
                    //就是个观察者模式
                    //应用:群聊天,微信订阅号
                    //一些消息队列中间件:MSMQ,RabbitMQ,ZeroMQ
                    Console.WriteLine("*****************发布订阅*****************");
                    {
                        service.FlushAll();
                        Task.Run(() =>
                        {
                            using (RedisListService service = new RedisListService())
                            {
                                service.Subscrible("小王", (c, message, iRedisSubcriotion) =>
                                {
                                    if (message.Equals("exit"))
                                    {
                                        iRedisSubcriotion.UnSubscribeFromChannels("小王");
                                    }
                                    else
                                        Console.WriteLine($"注册1{c}:{message},Dosomething else");
                                });
                            }
                        });

                        Task.Run(() =>
                        {
                            using (RedisListService service = new RedisListService())
                            {
                                service.Subscrible("小王", (c, message, iRedisSubcriotion) =>
                                {
                                    if (message.Equals("exit"))
                                    {
                                        iRedisSubcriotion.UnSubscribeFromChannels("小王");
                                    }
                                    else
                                        Console.WriteLine($"注册2{c}:{message},Dosomething else");
                                });
                            }
                        });

                        Task.Run(() =>
                        {
                            using (RedisListService service = new RedisListService())
                            {
                                service.Subscrible("小高", (c, message, iRedisSubcriotion) =>
                                {
                                    if (message.Equals("exit"))
                                    {
                                        iRedisSubcriotion.UnSubscribeFromChannels("小高");
                                    }
                                    else
                                        Console.WriteLine($"注册3{c}:{message},Dosomething else");

                                });
                            }
                        });

                        Thread.Sleep(1000);
                        service.Publish("小王", "小王123");
                        service.Publish("小王", "小王456");
                        service.Publish("小王", "小王789");
                        service.Publish("小王", "小王000");

                        service.Publish("小高", "小高123");
                        service.Publish("小高", "小高456");
                        service.Publish("小高", "小高789");
                        service.Publish("小高", "小高000");
                        Console.WriteLine("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");

                        service.Publish("小王", "exit");//取消订阅是需要时间的
                        service.Publish("小王", "123456");
                        service.Publish("小王", "444444");
                        service.Publish("小王", "666666");
                        service.Publish("小王", "677777");

                        service.Publish("小高", "exit");
                        service.Publish("小高", "000000");
                        service.Publish("小高", "999999");
                        service.Publish("小高", "888888");
                        Console.ReadLine();
                    }
                    #endregion
                }
            }
        }
    }
}

using RedisLibrary.Service;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace MyRedis
{
    //redis避免超卖
    public class OverSellTest
    {
        private static bool isGoOn = true;//秒杀是否开始

        public static void Show()
        {
            try
            {
                using (RedisStringService service = new RedisStringService())
                {
                    service.Set("Stock", 10);//库存10
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            for (int i = 0; i < 2000; i++)
            {
                int k = i;
                Task.Run(() =>
                {
                    using (RedisStringService service = new RedisStringService())
                    {
                        if (isGoOn)
                        {
                            long index = service.Decr("Stock");
                            if (index >= 0)
                            {
                                Console.WriteLine($"{k}秒杀成功,秒杀商品索引为{index}");//可以分队列,去数据库操作
                            }
                            else
                            {
                                if (isGoOn)
                                {
                                    isGoOn = false;
                                }
                                Console.WriteLine($"{k}秒杀失败,秒杀商品索引为{index}");
                            }
                        }
                        else
                        {
                            Console.WriteLine($"{k}秒杀已结束");
                        }
                    }
                });
            }
            Console.ReadKey();//让子线程能跑完
        }
    }
}
using Newtonsoft.Json;
using RedisLibrary.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyRedis
{
    public class UserInfoTest
    {
        public static void Show()
        {
            UserInfo user = new UserInfo()
            {
                Id = 123,
                Account = "123456",
                Name = "小王",
                Age = 18
            };

            using (RedisStringService service = new RedisStringService())
            {
                //在redis存对象有几种方式
                //第一种会存在引号问题,非常麻烦
                service.Set($"UserInfo_{user.Id}", JsonConvert.SerializeObject(user));
                string rst = service.Get($"UserInfo_{user.Id}");

                //第二种用String的泛型,修改比较麻烦,得先拿出来改再写回去,效率低
                service.Set<UserInfo>($"UserInfo_{user.Id}", user);
                UserInfo rst1 = service.Get<UserInfo>(new List<string> { $"UserInfo_{user.Id}" }).FirstOrDefault();
                rst1.Name = "大王";
                service.Set<UserInfo>($"UserInfo_{user.Id}", user);
                Console.WriteLine(service.Get($"UserInfo_{user.Id}"));

                //第三种一个对象存多个key-value。这样比较浪费空间
                //一个value值最小512byte
                service.Set($"UserInfo_{user.Id}_Name", user.Name);
                service.Set($"UserInfo_{user.Id}_Age", user.Age);
            };

            //第四种  用hash存储,zipmap的方式存储(存储策略可以配置),内存是紧密排列的
            //节约空间,更新方便
            using (RedisHashService service = new RedisHashService())
            {
                service.FlushAll();
                service.SetEntryInHash("strudent", "Id", "124");
                service.SetEntryInHash("strudent", "Account", "12345");
                service.SetEntryInHash("strudent", "Name", "小王");
                service.SetEntryInHash("strudent", "Age", "18");
                //直接修改
                service.SetEntryInHash("strudent", "Age", "19");

                //也可以这样直接实体存储和获取,但是要求实体必须有Id字段
                service.StoreAsHash<UserInfo>(user);
                UserInfo rst = service.GetFromHash<UserInfo>(user.Id);
            }
        }

    }

    public class UserInfo
    {
        public int Id { set; get; }
        public string Account { set; get; }
        public string Name { set; get; }
        public int Age { set; get; }
    }
}
using RedisLibrary.Service;
using System;
using System.Collections.Generic;
using System.Text;

namespace MyRedis
{
    public class FriendManagerTest
    {
        //去重作用:IP统计,IP投票,点赞,好友申请,
        public static void Show()
        {
            using (RedisSetService service = new RedisSetService())
            {
                service.FlushAll();
                service.AddItemToSet("小王", "张三");
                service.AddItemToSet("小王", "李四");
                service.AddItemToSet("小王", "王五");
                service.AddItemToSet("小王", "赵六");
                service.AddItemToSet("小王", "刘七");

                service.AddItemToSet("小高", "王五");
                service.AddItemToSet("小高", "赵六");
                service.AddItemToSet("小高", "刘七");
                service.AddItemToSet("小高", "陈八");
                service.AddItemToSet("小高", "杨九");

                var rst0 = service.GetIntersectFromSets("小王", "小高");//交
                var rst1 = service.GetDifferencesFromSet("小王", "小高");//差
                var rst2 = service.GetDifferencesFromSet("小高", "小王");
                var rst3 = service.GetUnionFromSets("小王", "小高");//并

                Console.WriteLine(service.PopItemFromSet("小王"));
                service.RemoveItemFromSet("小王", "刘七");
                service.RemoveItemFromSet("小王", "sansan");//key集合中没有的话不会报错

                //要移除的集合没有这个value,不影响要添加的添加
                service.MoveBetweenSets("小王", "小高", "刘七");
                var rst4 = service.GetAllItemsFromSet("小王");
                var rst5 = service.GetAllItemsFromSet("小高");
            }

        }
    }
}
using RedisLibrary.Service;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyRedis
{
    public class RankManagerTest
    {
        private static List<string> Users = new List<string>()
        {
            "苹果","梨","柿饼","麻花","青豆"
        };

        /// <summary>
        /// redis另外两个类库ServiceStack.Common,还有个ServiceStack.Text序列化用的
        /// 实时排行榜的应用
        /// 统计的维度很多:全平台/房间/主播/日/周/年
        /// 小王给小高刷个礼物,每个统计的维度都要统计,更新
        /// 方案:redis--IncrementItemInSortedSet
        /// 实时排行榜用redis实现,数据库只存流水
        /// 刷礼物是增加分数
        /// 把所有维度封装下,一个维度就是一个集合
        /// </summary>
        public static void Show()
        {
            using (RedisZSetService service = new RedisZSetService())
            {
                service.FlushAll();
                Task.Run(() =>
                {
                    while (true)
                    {
                        foreach (var item in Users)
                        {
                            Thread.Sleep(10);
                            using (RedisZSetService service = new RedisZSetService())
                            {
                                service.IncrementItemInSortedSet("小高", item, new Random().Next(1, 100));
                            }
                        }
                        Thread.Sleep(5 * 1000);
                    }
                });

                Task.Run(() =>
                {
                    while (true)
                    {
                        Thread.Sleep(4 * 1000);
                        using (RedisZSetService service = new RedisZSetService())
                        {
                            IDictionary<string, double> keyValuePairs = service.GetAllWithScoresFromSortedSet("小高");
                            foreach (var item in keyValuePairs)
                            {
                                Console.WriteLine($"{item.Key}--{item.Value}");
                            }
                        }
                        //int i = 0;
                        //foreach (var item in service.GetAllItemsFromSortedSetDesc("小高"))
                        //{
                        //    Console.WriteLine($"{i++}名:{item}");
                        //}
                    }
                });                
            }
            Console.ReadLine();
        }
    }
}
using RedisLibrary.Service;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyRedis
{
    public class BlogPageListTest
    {
        /// <summary>
        /// 一个ask项目(在线问答),需要把最新的放到首页,但是数据量有很大,更新很频繁
        /// 每次写入数据库的时候,把Id也存入list,如果分表也把表名存进去
        /// TrimList 让list保证定长,内存不至于太大
        /// 前几页直接从redis取
        /// 
        /// 博客数据分页
        /// 列出最新的博客--数据库分页
        /// 把最新的直接放入list,最新数据的Id,TrimList
        /// 
        /// 解决数据量大,变化频繁数据的分页
        /// </summary>
        public static void Show()
        {
            using (RedisListService service = new RedisListService())
            {
                service.FlushAll();
                service.RPush("newBlog", "101_1");
                service.RPush("newBlog", "101_2");
                service.RPush("newBlog", "101_3");
                service.RPush("newBlog", "101_4");
                service.RPush("newBlog", "101_5");
                service.RPush("newBlog", "101_6");

                service.TrimList("newBlog", 0, 200);
                var rst = service.GetAllItemsFromList("newBlog", 0, 9);//第一页10条
            }
        }
    }
}
using System;

namespace MyRedis.BackService
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //模拟消费者
                ServiceStackProcessor.Show();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                Console.Read();
            }
        }
    }
}
using RedisLibrary.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyRedis.BackService
{
    class ServiceStackProcessor
    {
        //消费者,从队列中取
        public static void Show()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;
            string tag = path.Split('/', '\\').Last(s => !string.IsNullOrEmpty(s));
            Console.WriteLine($"这里是{tag}启动了");
            using (RedisListService service = new RedisListService())
            {
                Task.WaitAll(Task.Run(() =>
                {
                    while (true)
                    {
                        var rst = service.BlockingPopItemFromLists(new string[] { "test", "task" }, TimeSpan.FromHours(3));
                        Thread.Sleep(100);
                        Console.WriteLine($"这里是{tag}的队列消息{rst.Id}--{rst.Item}");
                    }
                }));
            }

        }
    }
}

RedisLibrary--redis的操作类库

using System;
using System.Collections.Generic;
using System.Text;

namespace RedisLibrary.Init
{
    /// <summary>
    /// redis配置信息,可以放到文件配置
    /// </summary>
    public sealed class RedisConfigInfo
    {
        /// <summary>
        /// 可写的redis链接地址
        /// formal:ip1,1p2
        /// 默认端口:6379
        /// </summary>
        public string WriteServiceList = "127.0.0.1:6379";

        /// <summary>
        /// 可读的redis链接地址
        /// </summary>
        public string ReadServiceList = "127.0.0.1:6379";

        /// <summary>
        /// 最大写连接数
        /// </summary>
        public int MaxWritePoolSize = 60;

        /// <summary>
        /// 最大读连接数
        /// </summary>
        public int MaxReadPoolSize = 60;

        /// <summary>
        /// 本地缓存到期时间(s)
        /// </summary>
        public int LocalCacheTime = 180;

        /// <summary>
        /// 自动重启开
        /// </summary>
        public bool AutoStart = true;

        /// <summary>
        /// 是否记录日志,该设置仅用来排查redis运行时出现的问题
        /// 如redis运行正常,请关闭该项
        /// </summary>
        public bool RecordLog = false;
    }
}
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Text;

namespace RedisLibrary.Init
{
    public class RedisManager
    {
        /// <summary>
        /// redis配置信息
        /// </summary>
        private static RedisConfigInfo RedisConfigInfo = new RedisConfigInfo();

        /// <summary>
        /// redis客户端池化管理
        /// </summary>
        private static PooledRedisClientManager prcManager;

        static RedisManager()
        {
            CreateManager();
        }

        /// <summary>
        /// 创建连接池管理对象,固定写法
        /// </summary>
        private static void CreateManager()
        {
            string[] WriteServiceConStr = RedisConfigInfo.WriteServiceList.Split(',');
            string[] ReadServiceConStr = RedisConfigInfo.ReadServiceList.Split(',');
            prcManager = new PooledRedisClientManager(ReadServiceConStr, WriteServiceConStr, new RedisClientManagerConfig
            {
                MaxReadPoolSize = RedisConfigInfo.MaxReadPoolSize,
                MaxWritePoolSize = RedisConfigInfo.MaxWritePoolSize,
                AutoStart = RedisConfigInfo.AutoStart
            });
        }

        /// <summary>
        /// 客户端缓存操作对象,从池子里获取一个链接
        /// </summary>
        /// <returns></returns>
        public static IRedisClient GetClient()
        {
            return prcManager.GetClient();
        }
    }
}
using RedisLibrary.Init;
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Text;

namespace RedisLibrary.Interface
{
    //抽象基类
    //实现IDisposable 可以用using
    public abstract class RedisBase : IDisposable
    {
        public IRedisClient iClient { get; private set; }

        public RedisBase()
        {
            iClient = RedisManager.GetClient();
        }

        private bool _disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    iClient.Dispose();
                    iClient = null;
                }
            }
            _disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 事务的列子
        /// </summary>
        public void Transaction()
        {
            using (IRedisTransaction irt = this.iClient.CreateTransaction())
            {
                try
                {
                    irt.QueueCommand(r => r.Set("key", 20));
                    irt.QueueCommand(r => r.Increment("key", 1));
                    irt.Commit();
                }
                catch (Exception ex)
                {
                    irt.Rollback();
                    throw ex;
                }

            }
        }

        /// <summary>
        /// 清除所有数据--小心使用
        /// </summary>
        public virtual void FlushAll()
        {
            iClient.FlushAll();
        }

        /// <summary>
        /// 保存数据到硬盘
        /// </summary>
        public void Save()
        {
            iClient.Save();//阻塞时Save
            //iClient.SaveAsync();
        }

        /// <summary>
        /// 异步保存数据到硬盘,启动另外一个进程保存
        /// </summary>
        public void SaveAsync()
        {
            iClient.SaveAsync();
        }
    }
}
using RedisLibrary.Interface;
using System;
using System.Collections.Generic;
using System.Text;

namespace RedisLibrary.Service
{
    public class RedisStringService : RedisBase
    {
        #region 赋值

        /// <summary>
        /// 设置key的value
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Set<T>(string key, T value)
        {
            return base.iClient.Set<T>(key, value);
        }

        /// <summary>
        /// 设置key的value并设置过期时间
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public bool Set<T>(string key, T value, DateTime dateTime)
        {
            return base.iClient.Set<T>(key, value, dateTime);
        }

        /// <summary>
        /// 设置key的value并设置过期时间
        /// </summary>
        public bool Set<T>(string key, T value, TimeSpan timeSpan)
        {
            return base.iClient.Set<T>(key, value, timeSpan);
        }

        /// <summary>
        /// 设置多个key-value
        /// </summary>
        /// <param name="dic"></param>
        public void Set(Dictionary<string, string> dic)
        {
            base.iClient.SetAll(dic);
        }
        #endregion

        #region 追加
        /// <summary>
        /// 在原有key对应value后追加,没有就新增一项
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public long Append(string key, string value)
        {
            return base.iClient.AppendToValue(key, value);
        }
        #endregion

        #region 取值

        /// <summary>
        /// 取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Get(string key)
        {
            return base.iClient.GetValue(key);
            //return base.iClient.Get<string>(key);//此方式有问题,AppendToValue后获取值没变化
        }

        /// <summary>
        /// 获取多个key的value值
        /// </summary>
        /// <param name="keyList"></param>
        /// <returns></returns>
        public List<string> Get(List<string> keyList)
        {
            return base.iClient.GetValues(keyList);
        }

        /// <summary>
        /// 获取多个key的value值
        /// </summary>
        /// <param name="keyList"></param>
        /// <returns></returns>
        public List<T> Get<T>(List<string> keyList)
        {
            return base.iClient.GetValues<T>(keyList);
        }
        #endregion

        #region 获取旧值并重新赋值
        /// <summary>
        /// 获取旧值并重新赋值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string GetAndSetValue(string key, string value)
        {
            return base.iClient.GetAndSetValue(key, value);
        }
        #endregion

        #region 辅助方法
        /// <summary>
        /// 获取值的长度
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long GetLength(string key)
        {
            return base.iClient.GetStringCount(key);
        }

        /// <summary>
        /// 自增1,返回自增后的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long Incr(string key)
        {
            return base.iClient.IncrementValue(key);
        }

        /// <summary>
        /// 自增count,返回自增后的值
        /// </summary>
        public long IncrBy(string key, int count)
        {
            return base.iClient.IncrementValueBy(key, count);
        }

        /// <summary>
        /// 自减1,返回自减后的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long Decr(string key)
        {
            return base.iClient.DecrementValue(key);
        }

        /// <summary>
        /// 自减count,返回自减后的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long DecrBy(string key, int count)
        {
            return base.iClient.DecrementValueBy(key, count);
        }
        #endregion
    }
}
using RedisLibrary.Interface;
using System;
using System.Collections.Generic;
using System.Text;

namespace RedisLibrary.Service
{
    public class RedisHashService : RedisBase
    {
        #region 添加
        /// <summary>
        /// 向hashId集合中添加key-value
        /// </summary>
        public bool SetEntryInHash(string hashId, string key, string value)
        {
            return base.iClient.SetEntryInHash(hashId, key, value);
        }

        /// <summary>
        /// 如果hashId集合中存在key-value,不添加并返回false
        /// 不存在添加返回true
        /// </summary>
        public bool SetEntryInHashIfNotExists(string hashId, string key, string value)
        {
            return base.iClient.SetEntryInHashIfNotExists(hashId, key, value);
        }

        /// <summary>
        /// 存储对象T t到hash集合中
        /// 需要包含Id,用Id来获取
        /// </summary>
        public void StoreAsHash<T>(T t)
        {
            base.iClient.StoreAsHash<T>(t);
        }
        #endregion

        #region 获取
        /// <summary>
        /// 获取对象T中Id为id的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetFromHash<T>(object id)
        {
            return base.iClient.GetFromHash<T>(id);
        }

        /// <summary>
        /// 获取hashId数据集key的数据
        /// </summary>
        /// <param name="hashId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetValueFromHash(string hashId, string key)
        {
            return base.iClient.GetValueFromHash(hashId, key);
        }

        /// <summary>
        /// 获取hashId数据集所有的key-value集合
        /// </summary>
        /// <param name="hashId"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetAllEntriesFromHash(string hashId)
        {
            return base.iClient.GetAllEntriesFromHash(hashId);
        }

        /// <summary>
        /// 获取hashId数据集的数据总数,key-value个数
        /// </summary>
        /// <param name="hashId"></param>
        /// <returns></returns>
        public long GetHashCount(string hashId)
        {
            return base.iClient.GetHashCount(hashId);
        }

        /// <summary>
        /// 获取hashId数据集的所有key集合
        /// </summary>
        /// <param name="hashId"></param>
        /// <returns></returns>
        public List<string> GetHashKeys(string hashId)
        {
            return base.iClient.GetHashKeys(hashId);
        }

        /// <summary>
        /// 获取hashId数据集的所有value集合
        /// </summary>
        /// <param name="hashId"></param>
        /// <returns></returns>
        public List<string> GetHashValues(string hashId)
        {
            return base.iClient.GetHashValues(hashId);
        }
        #endregion

        #region 删除
        /// <summary>
        /// 删除hashId数据集指定key的key-value
        /// </summary>
        /// <param name="hashId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool RemoveEntryFromHash(string hashId, string key)
        {
            return base.iClient.RemoveEntryFromHash(hashId, key);
        }
        #endregion

        #region 
        /// <summary>
        /// 判断hashId数据集是否包含指定key的key-value
        /// </summary>
        /// <param name="hashId"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool HashContainsEntry(string hashId, string key)
        {
            return base.iClient.HashContainsEntry(hashId, key);
        }

        /// <summary>
        /// 给hashId数据集指定key的value加conutBy,返回相加后的数据
        /// </summary>
        /// <param name="hashId"></param>
        /// <param name="key"></param>
        /// <param name="conutBy"></param>
        /// <returns></returns>
        public double IncrementValueInHash(string hashId, string key, double conutBy)
        {
            return base.iClient.IncrementValueInHash(hashId, key, conutBy);
        }
        #endregion
    }
}
using RedisLibrary.Interface;
using System;
using System.Collections.Generic;
using System.Text;

namespace RedisLibrary.Service
{
    public class RedisSetService : RedisBase
    {
        #region 赋值

        /// <summary>
        /// 向集合增加值
        /// </summary>
        public void AddItemToSet(string key, string value)
        {
            base.iClient.AddItemToSet(key, value);
        }

        /// <summary>
        /// 向集合添加List集合
        /// </summary>
        public void AddRangeToSet(string key, List<string> list)
        {
            base.iClient.AddRangeToSet(key, list);
        }

        #endregion

        #region 取值

        /// <summary>
        /// 随机取key集合中的一个值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetRandomItemFromSet(string key)
        {
            return base.iClient.GetRandomItemFromSet(key);
        }

        /// <summary>
        /// 获取key集合的所有值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public HashSet<string> GetAllItemsFromSet(string key)
        {
            return base.iClient.GetAllItemsFromSet(key);
        }

        /// <summary>
        /// 获取key集合值的数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public long GetSetCount(string key)
        {
            return base.iClient.GetSetCount(key);
        }
        #endregion

        #region 删除
        /// <summary>
        /// key集合中随机删一个值并返回
        /// </summary>
        public string PopItemFromSet(string key)
        {
            return base.iClient.PopItemFromSet(key);
        }

        /// <summary>
        /// 删除key集合中的value
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void RemoveItemFromSet(string key, string value)
        {
            base.iClient.RemoveItemFromSet(key, value);
        }
        #endregion

        #region 其他
        /// <summary>
        /// 从fromkey集合中移除value的值,并把value添加到tokey集合中
        /// </summary>
        public void MoveBetweenSets(string fromKey, string toKey, string value)
        {
            base.iClient.MoveBetweenSets(fromKey, toKey, value);
        }

        /// <summary>
        /// 返回多个key集合中的并集
        /// </summary>
        /// <param name="keys"></param>
        /// <returns></returns>
        public HashSet<string> GetUnionFromSets(params string[] keys)
        {
            return base.iClient.GetUnionFromSets(keys);
        }

        /// <summary>
        /// 把多个key的并集放入newkey集合中
        /// </summary>
        /// <param name="newKey"></param>
        /// <param name="keys"></param>
        public void StoreUnionFromSets(string newKey, params string[] keys)
        {
            base.iClient.StoreUnionFromSets(newKey, keys);
        }

        /// <summary>
        /// 返回多个key集合中的交集
        /// </summary>
        /// <param name="keys"></param>
        public HashSet<string> GetIntersectFromSets(params string[] keys)
        {
            return base.iClient.GetIntersectFromSets(keys);
        }

        /// <summary>
        /// 返回fromkey对其他集合的差集
        /// </summary>
        /// <param name="fromkey">原集合</param>
        /// <param name="keys">其他集合</param>
        /// <returns>原集合有,其他集合没有</returns>
        public HashSet<string> GetDifferencesFromSet(string fromkey, params string[] keys)
        {
            return base.iClient.GetDifferencesFromSet(fromkey, keys);
        }

        /// <summary>
        /// 把fromkey对其他集合的差集放入newkey集合中
        /// </summary>
        public void StoreDifferencesFromSet(string newKey, string fromkey, params string[] keys)
        {
            base.iClient.StoreDifferencesFromSet(newKey, fromkey, keys);
        }
        #endregion

    }
}
using RedisLibrary.Interface;
using System;
using System.Collections.Generic;
using System.Text;

namespace RedisLibrary.Service
{
    public class RedisZSetService : RedisBase
    {
        #region 赋值

        /// <summary>
        /// 向集合key增加值,默认分数1.多*10的9次方,默认以此递增
        /// 但是这个默认自增不是按照添加的时间顺序来的,按照值来的
        /// </summary>
        public bool AddItemToSortedSet(string key, string value)
        {
            return base.iClient.AddItemToSortedSet(key, value);
        }

        /// <summary>
        /// 向集合key增加值,带分数
        /// </summary>
        public bool AddItemToSortedSet(string key, string value, double score)
        {
            return base.iClient.AddItemToSortedSet(key, value, score);
        }

        /// <summary>
        /// 向集合key增加values集合,values集合的每一项分数都是score
        /// 相同分数  数值是按照大小,汉字无序
        /// </summary>
        public bool AddItemToSortedSet(string key, List<string> values, double score)
        {
            return base.iClient.AddRangeToSortedSet(key, values, score);
        }

        /// <summary>
        /// 向集合key增加values集合,values集合的每一项分数都是score
        /// 相同分数  数值是按照大小,汉字无序
        /// </summary>
        public bool AddItemToSortedSet(string key, List<string> values, long score)
        {
            return base.iClient.AddRangeToSortedSet(key, values, score);
        }
        #endregion

        #region 取值

        /// <summary>
        /// 取key集合所有值,按照分数排了序
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public List<string> GetAllItemsFromSortedSet(string key)
        {
            return base.iClient.GetAllItemsFromSortedSet(key);
        }

        /// <summary>
        /// 取key集合所有值,按照分数倒叙
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public List<string> GetAllItemsFromSortedSetDesc(string key)
        {
            return base.iClient.GetAllItemsFromSortedSetDesc(key);
        }

        /// <summary>
        /// 获取key的value-score字典
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public IDictionary<string, double> GetAllWithScoresFromSortedSet(string key)
        {
            return base.iClient.GetAllWithScoresFromSortedSet(key);
        }

        /// <summary>
        /// 获取key集合中值为value的下标
        /// </summary>
        public long GetItemIndexInSortedSet(string key, string value)
        {
            return base.iClient.GetItemIndexInSortedSet(key, value);
        }

        /// <summary>
        /// 倒叙排列后,获取key集合中值为value的下标
        /// </summary>
        public long GetItemIndexInSortedSetDesc(string key, string value)
        {
            return base.iClient.GetItemIndexInSortedSetDesc(key, value);
        }

        /// <summary>
        /// 获取key集合中值为value的分数
        /// </summary>
        public double GetItemScoreInSortedSet(string key, string value)
        {
            return base.iClient.GetItemScoreInSortedSet(key, value);
        }

        /// <summary>
        /// 获取key集合数据总数
        /// </summary>
        public double GetSortedSetCount(string key)
        {
            return base.iClient.GetSortedSetCount(key);
        }

        /// <summary>
        /// 获取key集合指定分数区间数据总数
        /// </summary>
        public double GetSortedSetCount(string key, double fromScore, double toScore)
        {
            return base.iClient.GetSortedSetCount(key, fromScore, toScore);
        }

        /// <summary>
        /// 获取key集合指定分数区间数据,按照从高分到低分排序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="fromScore"></param>
        /// <param name="toScore"></param>
        /// <returns></returns>
        public List<string> GetRangeFromSortedSetByHighestScore(string key, double fromScore, double toScore)
        {
            return base.iClient.GetRangeFromSortedSetByHighestScore(key, fromScore, toScore);
        }

        /// <summary>
        /// 获取key集合指定分数区间数据,按照从低分到高分排序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="fromScore"></param>
        /// <param name="toScore"></param>
        /// <returns></returns>
        public List<string> GetRangeFromSortedSetByLowestScore(string key, double fromScore, double toScore)
        {
            return base.iClient.GetRangeFromSortedSetByLowestScore(key, fromScore, toScore);
        }

        /// <summary>
        /// 获取key集合指定分数区间的value-score字典,按照从低分到高分排序
        /// </summary>
        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByHighestScore(string key, double fromScore, double toScore)
        {
            return base.iClient.GetRangeWithScoresFromSortedSetByHighestScore(key, fromScore, toScore);
        }

        /// <summary>
        /// 获取key集合指定分数区间的value-score字典,按照从低分到高分排序
        /// </summary>
        public IDictionary<string, double> GetRangeWithScoresFromSortedSetByLowestScore(string key, double fromScore, double toScore)
        {
            return base.iClient.GetRangeWithScoresFromSortedSetByLowestScore(key, fromScore, toScore);
        }

        /// <summary>
        /// 获取key集合,下标从fromRank到toRank
        /// </summary>
        public List<string> GetRangeFromSortedSet(string key, int fromRank, int toRank)
        {
            return base.iClient.GetRangeFromSortedSet(key, fromRank, toRank);
        }

        /// <summary>
        /// 获取key集合,倒叙后下标从fromRank到toRank
        /// </summary>
        public List<string> GetRangeFromSortedSetDesc(string key, int fromRank, int toRank)
        {
            return base.iClient.GetRangeFromSortedSetDesc(key, fromRank, toRank);
        }

        /// <summary>
        /// 获取key集合的value-score字典,下标从fromRank到toRank
        /// </summary>
        public IDictionary<string, double> GetRangeWithScoresFromSortedSet(string key, int fromRank, int toRank)
        {
            return base.iClient.GetRangeWithScoresFromSortedSet(key, fromRank, toRank);
        }

        /// <summary>
        /// 获取key集合的value-score字典,倒叙后下标从fromRank到toRank
        /// </summary>
        public IDictionary<string, double> GetRangeWithScoresFromSortedSetDesc(string key, int fromRank, int toRank)
        {
            return base.iClient.GetRangeWithScoresFromSortedSetDesc(key, fromRank, toRank);
        }
        #endregion

        #region 删除
        /// <summary>
        /// 删除key集合中的value
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public bool RemoveItemFromSortedSet(string key, string value)
        {
            return base.iClient.RemoveItemFromSortedSet(key, value);
        }

        /// <summary>
        /// 删除key集合中的数据,下标从minRank到maxRank
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public long RemoveRangeFromSortedSet(string key, int minRank, int maxRank)
        {
            return base.iClient.RemoveRangeFromSortedSet(key, minRank, maxRank);
        }

        /// <summary>
        /// 删除key集合中的数据,分数从fromScore到toScore
        /// </summary>
        public long RemoveRangeFromSortedSetByScore(string key, double fromScore, double toScore)
        {
            return base.iClient.RemoveRangeFromSortedSetByScore(key, fromScore, toScore);
        }

        /// <summary>
        /// 删除key集合中分数最大的数据并返回
        /// </summary>
        public string PopItemWithHighestScoreFromSortedSet(string key)
        {
            return base.iClient.PopItemWithHighestScoreFromSortedSet(key);
        }

        /// <summary>
        /// 删除key集合中分数最小的数据并返回
        /// </summary>
        public string PopItemWithLowestScoreFromSortedSet(string key)
        {
            return base.iClient.PopItemWithLowestScoreFromSortedSet(key);
        }
        #endregion

        #region 其他
        /// <summary>
        /// 查询key集合中是否包含value
        /// </summary>
        public bool SortedSetContainsItem(string key, string value)
        {
            return base.iClient.SortedSetContainsItem(key, value);
        }

        /// <summary>
        /// 为key集合中值为value的数据的分数加上score,返回相加后的分数
        /// </summary>
        public double IncrementItemInSortedSet(string key, string value, double scoreBy)
        {
            return base.iClient.IncrementItemInSortedSet(key, value, scoreBy);
        }

        /// <summary>
        /// 获取keys多个集合的交集,放入新集合newKey中,返回交集数据总数
        /// </summary>
        public long StoreIntersectFromSortedSets(string newKey, params string[] keys)
        {
            return base.iClient.StoreIntersectFromSortedSets(newKey, keys);
        }

        /// <summary>
        /// 获取keys多个集合的并集,放入新集合newKey中,返回交集数据总数
        /// </summary>
        public long StoreUnionFromSortedSets(string newKey, params string[] keys)
        {
            return base.iClient.StoreUnionFromSortedSets(newKey, keys);
        }
        #endregion

    }
}
using RedisLibrary.Interface;
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Text;

namespace RedisLibrary.Service
{
    public class RedisListService : RedisBase
    {
        #region 赋值
        /// <summary>
        /// 从左侧向list中添加值
        /// </summary>
        public void LPush(string key, string value)
        {
            base.iClient.PushItemToList(key, value);
        }

        /// <summary>
        /// 从左侧向list中添加值并设置过期时间
        /// </summary>
        public void LPush(string key, string value, DateTime dateTime)
        {
            base.iClient.PushItemToList(key, value);
            base.iClient.ExpireEntryAt(key, dateTime);
        }

        /// <summary>
        /// 从左侧向list中添加值并设置过期时间
        /// </summary>
        public void LPush(string key, string value, TimeSpan timeSpan)
        {
            base.iClient.PushItemToList(key, value);
            base.iClient.ExpireEntryIn(key, timeSpan);
        }

        /// <summary>
        /// 从右侧向list中添加值
        /// </summary>
        public void RPush(string key, string value)
        {
            base.iClient.PrependItemToList(key, value);
        }

        /// <summary>
        /// 从右侧向list中添加值并设置过期时间
        /// </summary>
        public void RPush(string key, string value, DateTime dateTime)
        {
            base.iClient.PrependItemToList(key, value);
            base.iClient.ExpireEntryAt(key, dateTime);
        }

        /// <summary>
        /// 从右侧向list中添加值并设置过期时间
        /// </summary>
        public void RPush(string key, string value, TimeSpan timeSpan)
        {
            base.iClient.PrependItemToList(key, value);
            base.iClient.ExpireEntryIn(key, timeSpan);
        }

        /// <summary>
        /// 向key列表中添加value
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void Add(string key, string value)
        {
            base.iClient.AddItemToList(key, value);
        }

        /// <summary>
        /// 向key列表中添加value并设置过期时间
        /// </summary>
        public void Add(string key, string value, DateTime dateTime)
        {
            base.iClient.AddItemToList(key, value);
            base.iClient.ExpireEntryAt(key, dateTime);
        }

        /// <summary>
        /// 向key列表中添加value并设置过期时间
        /// </summary>
        public void Add(string key, string value, TimeSpan timeSpan)
        {
            base.iClient.AddItemToList(key, value);
            base.iClient.ExpireEntryIn(key, timeSpan);
        }

        /// <summary>
        /// 向key列表中添加多个值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="list"></param>
        public void Add(string key, List<string> list)
        {
            base.iClient.AddRangeToList(key, list);
        }

        /// <summary>
        /// 向key列表中添加多个值并设置过期时间
        /// </summary>
        public void Add(string key, List<string> list, DateTime dateTime)
        {
            base.iClient.AddRangeToList(key, list);
            base.iClient.ExpireEntryAt(key, dateTime);
        }

        /// <summary>
        /// 向key列表中添加多个值并设置过期时间
        /// </summary>
        public void Add(string key, List<string> list, TimeSpan timeSpan)
        {
            base.iClient.AddRangeToList(key, list);
            base.iClient.ExpireEntryIn(key, timeSpan);
        }
        #endregion

        #region 取值

        /// <summary>
        /// key列表的数据个数
        /// </summary>
        public long GetListCount(string key)
        {
            return base.iClient.GetListCount(key);
        }

        /// <summary>
        /// 取key列表
        /// </summary>
        public List<string> GetAllItemsFromList(string key)
        {
            return base.iClient.GetAllItemsFromList(key);
        }

        /// <summary>
        /// 取key列表下标从start到end
        /// </summary>
        public List<string> GetAllItemsFromList(string key, int start, int end)
        {
            return base.iClient.GetRangeFromList(key, start, end);
        }
        #endregion

        #region 阻塞命令
        /// <summary>
        /// 阻塞命令:从key的list尾部移除一个值并返回,阻塞时间为timeSpan
        /// 一般用在等待其他动作存值
        /// </summary>
        public string BlockingDequeueItemFromList(string key, TimeSpan? timeSpan)
        {
            return base.iClient.BlockingDequeueItemFromList(key, timeSpan);
        }

        /// <summary>
        /// 阻塞命令:从多个list尾部移除一个值并返回ItemRef(key,value),阻塞时间为timeSpan
        /// 一般用在等待其他动作存值
        /// </summary>
        public ItemRef BlockingDequeueItemFromLists(string[] key, TimeSpan? timeSpan)
        {
            return base.iClient.BlockingDequeueItemFromLists(key, timeSpan);
        }

        /// <summary>
        /// 阻塞命令:从key的list尾部移除一个值并返回,阻塞时间为timeSpan
        /// 一般用在等待其他动作存值
        /// </summary>
        public string BlockingPopItemFromList(string key, TimeSpan? timeSpan)
        {
            return base.iClient.BlockingPopItemFromList(key, timeSpan);
        }

        /// <summary>
        /// 阻塞命令:从多个list尾部移除一个值并返回ItemRef(key,value),阻塞时间为timeSpan
        /// 一般用在等待其他动作存值
        /// </summary>
        public ItemRef BlockingPopItemFromLists(string[] key, TimeSpan? timeSpan)
        {
            return base.iClient.BlockingPopItemFromLists(key, timeSpan);
        }

        /// <summary>
        /// 阻塞命令:从key的list头部移除一个值并返回,阻塞时间为timeSpan
        /// 一般用在等待其他动作存值
        /// </summary>
        public string BlockingRemoveStartFromList(string key, TimeSpan? timeSpan)
        {
            return base.iClient.BlockingRemoveStartFromList(key, timeSpan);
        }

        /// <summary>
        /// 阻塞命令:从多个list头部移除一个值并返回ItemRef(key,value),阻塞时间为timeSpan
        /// 一般用在等待其他动作存值
        /// </summary>
        public ItemRef BlockingRemoveStartFromLists(string[] key, TimeSpan? timeSpan)
        {
            return base.iClient.BlockingRemoveStartFromLists(key, timeSpan);
        }

        /// <summary>
        /// 阻塞命令:从fromKey的list尾部移除一个值并添加到toKey的list头部,返回移除的值,阻塞时间为timeSpan
        /// 一般用在等待其他动作存值
        /// </summary>
        public string BlockingRemoveStartFromList(string fromKey, string toKey, TimeSpan? timeSpan)
        {
            return base.iClient.BlockingPopAndPushItemBetweenLists(fromKey, toKey, timeSpan);
        }
        #endregion

        #region 删除
        /// <summary>
        /// 从尾部移除数据并返回
        /// </summary>
        public string PopItemFromList(string key)
        {
            return base.iClient.PopItemFromList(key);
        }

        /// <summary>
        /// 从key列表中移除value,返回移除的数量
        /// </summary>
        public long RemoveItemFromList(string key, string value)
        {
            return base.iClient.RemoveItemFromList(key, value);
        }

        /// <summary>
        /// 从尾部移除数据并返回
        /// </summary>
        public string RemoveEndFromList(string key)
        {
            return base.iClient.RemoveEndFromList(key);
        }

        /// <summary>
        /// 从头部移除数据并返回
        /// </summary>
        public string RemoveStartFromList(string key)
        {
            return base.iClient.RemoveStartFromList(key);
        }
        #endregion

        #region 其他
        /// <summary>
        /// 从fromKey的list尾部移除一个值并添加到toKey的list头部,返回移除的值
        /// </summary>
        public string GetLength(string fromKey, string toKey)
        {
            return base.iClient.PopAndPushItemBetweenLists(fromKey, toKey);
        }

        /// <summary>
        /// 截取List,从start到end
        /// </summary>
        public void TrimList(string key, int start, int end)
        {
            base.iClient.TrimList(key, start, end);
        }
        #endregion

        #region 发布订阅
        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="message"></param>
        public void Publish(string channel,string message)
        {
            base.iClient.PublishMessage(channel, message);
        }

        /// <summary>
        /// 订阅 阻塞的
        /// </summary>
        /// <param name="channel">频道名称</param>
        /// <param name="actionOnMessage"></param>
        public void Subscrible(string channel, Action<string, string, IRedisSubscription> actionOnMessage)
        {
            var subscription = base.iClient.CreateSubscription();
            //订阅
            subscription.OnSubscribe = c =>
            {
                Console.WriteLine($"订阅频道{c}");
                Console.WriteLine();
            };
            //取消订阅
            subscription.OnUnSubscribe = c =>
            {
                Console.WriteLine($"取消订阅{c}");
                Console.WriteLine();
            };

            subscription.OnMessage = (c,s) =>
            {
                actionOnMessage(c, s, subscription);
            };
            Console.WriteLine($"开始自动监听{channel}");
            subscription.SubscribeToChannels(channel);//阻塞的 blocking
        }
        #endregion
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我不是一个可以浏览互联网的程序,也不会进行搜索。但是,我可以为您介绍一下ServiceStack.Redis的常用操作,包括事务和并发锁。 1. 事务 在ServiceStack.Redis中,您可以使用事务来确保多个命令的原子性。以下是一个使用事务的示例: ``` using (var redis = RedisManager.GetClient()) { var tx = redis.CreateTransaction(); tx.QueueCommand(r => r.Set("key1", "value1")); tx.QueueCommand(r => r.Set("key2", "value2")); tx.Commit(); } ``` 在这个例子中,我们使用`redis.CreateTransaction()`来创建一个事务,然后使用`tx.QueueCommand()`方法将多个命令添加到事务中,最后使用`tx.Commit()`方法来提交事务。如果有任何一个命令失败,整个事务将被回滚。 2. 并发锁 在多线程环境下,为了避免数据竞争和并发问题,我们需要使用并发锁来确保同一时间只有一个线程可以修改数据。在ServiceStack.Redis中,您可以使用`IRedisClient.AcquireLock()`方法来获取一个锁,使用`IRedisClient.ReleaseLock()`方法来释放锁。 以下是一个使用并发锁的示例: ``` using (var redis = RedisManager.GetClient()) { using (var lock = redis.AcquireLock("mylock")) { // do some work } } ``` 在这个例子中,我们使用`redis.AcquireLock()`方法来获取一个名为"mylock"的锁,并使用`using`语句来确保锁在使用完后被释放。如果另一个线程已经获取了这个锁,那么当前线程将被阻塞,直到锁被释放。 希望这些信息能对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值