按照C#的MongoDB数据库开发应用(4)–Redis的设置及利用

在面前介绍了三篇关于MongoDB数据库的支付应用小说,严酷来讲那一个无法归类于MongoDB数据库开发,然则Redis又具有和MongoDB数据库格外细心的涉嫌,它们两者很相近,Redis重即使内存中的NoSQL数据库,用来升高性能的;MongoDB数据库则是文本中的NoSQL数据库,做多少系列号存储使用的,它们两者关系密切又有所不一致。本篇主要介绍Redis的装置及使用,为前面Redis和MongoDB数据库的一头使用先铺下基础。

1、Redis基础及安装

Redis是一个开源的利用ANSI
C语言编写、接济网络、可依照内存亦可持久化的日志型、Key-Value数据库,和Memcached类似,它协助存储的value类型相对更多,包含string(字符串)、list(链表)、set(集合)、zset(sorted
set
–有序集合)和hash(哈希类型)。在此基础上,redis辅助各样分裂方法的排序。与memcached一样,为了保障作用,数据都是缓存在内存中。区其他是redis会周期性的把创新的多寡写入磁盘或者把修改操作写入追加的笔录文件,并且在此基础上贯彻了master-slave(主从)同步。

Redis的代码遵守ANSI-C编写,可以在具备POSIX系统(如Linux, *BSD, Mac OS
X,
Solaris等)上安装运行。而且Redis并不依靠任何非标准库,也一向不编译参数必需添加。

1)Redis辅助二种持久化形式:

 
 (1):snapshotting(快照)也是默许形式.(把数量做一个备份,将数据存储到文件)

   (2)Append-only file(缩写aof)的方式 

 
 快照是默许的持久化格局,那种办法是将内存中数据以快照的点子写到二进制文件中,默许的文件名称为dump.rdb.可以经过配备安装自动做快照持久化的法门。大家可以安顿redis在n秒内假若当先m个key键修改就自动做快照.

 
 aof格局:由于快照格局是在听其自然间隔时间做四回的,所以假诺Redis意外down掉的话,就会丢掉最终四次快照后的保有修改。aof比快照情势有更好的持久化性,是出于在选取aof时,redis会将每一个接收的写命令都经过write函数追加到文件中,当redis重启时会通过重复履行文书中保存的写命令来在内存中重建总体数据库的情节。 

2)Redis数据结构

Redis 的小编antirez曾称其为一个数据结构服务器(data structures
server
),那是一个至极纯粹的表明,Redis的具备成效就是将数据以其固有的两种结构保留,并提必要用户操作那两种结构的接口。大家得以想象大家在各个语言中的那几个固有数据类型及其操作。

Redis近日提供四种数据类型:string,list,setzset(sorted
set)和Hash

  • string是最简易的花色,你可以精晓成与Memcached一模一个的档次,一个key对应一个value,其上协理的操作与Memcached的操作看似。但它的功用更丰裕。
  • list是一个链表结构,首要成效是push、pop、获取一个限制的所有值等等。操作中key精通为链表的名字。
  • set是集结,和我们数学中的集合概念一般,对聚集的操作有增加删除元素,有对多少个集合求交并差等操作。操作中key精通为汇聚的名字。
  • zset是set的一个晋级版本,他在set的底蕴上增加了一个一一属性,这一性质在抬高修改元素的时候可以指定,每回指定后,zset会自行重新按新的值调整顺序。可以领略了有两列的mysql表,一列存value,一列存顺序。操作中key领悟为zset的名字。
  • Hash数据类型允许用户用Redis存储对象类型,Hash数据类型的一个最主要亮点是,当你存储的多寡对象只有很少多少个key值时,数据存储的内存消耗会很小.越来越多关于Hash数据类型的认证请见: http://code.google.com/p/redis/wiki/Hashes

3)Redis数据存储

Redis的蕴藏分为内存存储、磁盘存储和log文件三有的,配置文件中有四个参数对其展开配置。

save seconds
updates
save布署,提议在多久内,有多少次立异操作,就将数据同步到数据文件。那几个可以多少个规范万分,比如默许配置文件中的设置,就安装了七个原则。

appendonly
yes
/no appendonly配备,提议是不是在每趟换代操作后展开日志记录,借使不打开,可能会在断电时造成一段时间内的多少丢失。因为redis本身同步数据文件是按上边的save条件来一同的,所以部分数据会在一段时间内只设有于内存中。

appendfsync
no
/always/everysec appendfsync配置,no表示等操作系统举行多少缓存同步到磁盘,always表示每一回换代操作后手动调用fsync()将数据写到磁盘,everysec代表每秒同步一遍。

 

4)Redis的安装

Redis可以在差其他平台运行,然则自己第一根据Windows举办支付工作,所以下边首若是根据Windows平台举行介绍。

Redis可以安装以DOS窗口启动的,也得以设置为Windows服务的,一般为了便利,大家更愿意把它安装为Windows服务,那样可以比较方便管理。下载地址:https://github.com/MSOpenTech/redis/releases下载,安装为Windows服务即可。

眼下可以下载到新型的Windows安装版本为3.0,安装后作为Windows服务运作,安装后可以在系统的劳动内部看到Redis的服务在运行了,如下图所示。

图片 1

设置好Redis后,还有一个Redis伴侣Redis Desktop
Manager须求安装,那样可以实时查看Redis缓存里面有怎么着数据,具体地址如下:http://redisdesktop.com/download

下载属于自己平台的版本即可

图片 2

下载安装后,打开运行界面,如若大家往里面添加键值的数额,那么可以看来里面的多少了。

图片 3

 

2、Redis的C#使用

Redis如今提供四种数据类型:string,list,setzset(sorted
set)和Hash。因而它在C#里头也有相应的包裹处理,而且有成百上千人对她展开了打包,提供了成百上千的响应开发包,具体可以访问http://redis.io/clients#c
举行询问。一般提议用瑟维斯(Service)(Service)Stack.Redis的包装驱动比较好,具体的采纳可以参考https://github.com/ServiceStack/ServiceStack.Redis

我们开发C#代码的时候,可以在NuGet程序包下边举行添加对应的Service(Service)Stack.Redis引用,如下所示。

图片 4

 

在弹出的NuGet程序包里面,输入瑟维斯(Service)Stack.Redis进行搜寻,并加上上边的驱动引用即可。

图片 5

这么会在项目引用里面添加了多少个照应的程序集,如下所示。

图片 6

在C#其间使用Redis,首先需求实例化一个Redis的客户端类,如下所示。

        //创建一个Redis的客户端类
        RedisClient client = new RedisClient("127.0.0.1", 6379);

在行使前,大家要求清空所有的键值存储,使用FushAll方法即可,如下所示

            //Redis FlushAll 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。 
            client.FlushAll();

依据地点的驱动,可以为分化门类的拍卖编写一些演示代码,下边代码是摘录网上的案例举行介绍。

            #region string类型的测试代码

            client.Add<string>("StringValueTime", "带有有效期的字符串", DateTime.Now.AddMilliseconds(10000));

            while (true)
            {
                if (client.ContainsKey("StringValueTime"))
                {
                    Console.WriteLine("String.键:StringValue, 值:{0} {1}", client.Get<string>("StringValueTime"), DateTime.Now);
                    Thread.Sleep(10000);
                }
                else
                {
                    Console.WriteLine("键:StringValue, 值:已过期 {0}", DateTime.Now);
                    break;
                }
            }

            client.Add<string>("StringValue", " String和Memcached操作方法差不多");
            Console.WriteLine("数据类型为:String.键:StringValue, 值:{0}", client.Get<string>("StringValue"));

            Student stud = new Student() { id = "1001", name = "李四" };
            client.Add<Student>("StringEntity", stud);
            Student Get_stud = client.Get<Student>("StringEntity");
            Console.WriteLine("数据类型为:String.键:StringEntity, 值:{0} {1}", Get_stud.id, Get_stud.name);
            #endregion

            #region Hash类型的测试代码

            client.SetEntryInHash("HashID", "Name", "张三");
            client.SetEntryInHash("HashID", "Age", "24");
            client.SetEntryInHash("HashID", "Sex", "男");
            client.SetEntryInHash("HashID", "Address", "上海市XX号XX室");

            List<string> HaskKey = client.GetHashKeys("HashID");
            foreach (string key in HaskKey)
            {
                Console.WriteLine("HashID--Key:{0}", key);
            }

            List<string> HaskValue = client.GetHashValues("HashID");
            foreach (string value in HaskValue)
            {
                Console.WriteLine("HashID--Value:{0}", value);
            }

            List<string> AllKey = client.GetAllKeys(); //获取所有的key。
            foreach (string Key in AllKey)
            {
                Console.WriteLine("AllKey--Key:{0}", Key);
            }
            #endregion

            #region List类型的测试代码
            /*
             * list是一个链表结构,主要功能是push,pop,获取一个范围的所有的值等,操作中key理解为链表名字。 
             * Redis的list类型其实就是一个每个子元素都是string类型的双向链表。我们可以通过push,pop操作从链表的头部或者尾部添加删除元素,
             * 这样list既可以作为栈,又可以作为队列。Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,
             * Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构 
             */
            client.EnqueueItemOnList("QueueListId", "1.张三");  //入队
            client.EnqueueItemOnList("QueueListId", "2.张四");
            client.EnqueueItemOnList("QueueListId", "3.王五");
            client.EnqueueItemOnList("QueueListId", "4.王麻子");
            long q = client.GetListCount("QueueListId");

            Console.WriteLine(client.GetItemFromList("QueueListId", 0));
            for (int i = 0; i < q; i++)
            {
                Console.WriteLine("QueueListId出队值:{0}", client.DequeueItemFromList("QueueListId"));   //出队(队列先进先出)
            }

            q = client.GetListCount("QueueListId");
            Console.WriteLine(q);

            client.PushItemToList("StackListId", "1.张三");  //入栈
            client.PushItemToList("StackListId", "2.张四");
            client.PushItemToList("StackListId", "3.王五");
            client.PushItemToList("StackListId", "4.王麻子");
            long p = client.GetListCount("StackListId");
            for (int i = 0; i < p; i++)
            {
                Console.WriteLine("StackListId出栈值:{0}", client.PopItemFromList("StackListId"));   //出栈(栈先进后出)
            }
            q = client.GetListCount("StackListId");
            Console.WriteLine(q);

            #endregion

            #region Set无序集合的测试代码
            /*
             它是string类型的无序集合。set是通过hash table实现的,添加,删除和查找,对集合我们可以取并集,交集,差集
             */
            client.AddItemToSet("Set1001", "小A");
            client.AddItemToSet("Set1001", "小B");
            client.AddItemToSet("Set1001", "小C");
            client.AddItemToSet("Set1001", "小D");
            HashSet<string> hastsetA = client.GetAllItemsFromSet("Set1001");
            foreach (string item in hastsetA)
            {
                Console.WriteLine("Set无序集合ValueA:{0}", item); //出来的结果是无须的
            }

            client.AddItemToSet("Set1002", "小K");
            client.AddItemToSet("Set1002", "小C");
            client.AddItemToSet("Set1002", "小A");
            client.AddItemToSet("Set1002", "小J");
            HashSet<string> hastsetB = client.GetAllItemsFromSet("Set1002");
            foreach (string item in hastsetB)
            {
                Console.WriteLine("Set无序集合ValueB:{0}", item); //出来的结果是无须的
            }

            HashSet<string> hashUnion = client.GetUnionFromSets(new string[] { "Set1001", "Set1002" });
            foreach (string item in hashUnion)
            {
                Console.WriteLine("求Set1001和Set1002的并集:{0}", item); //并集
            }

            HashSet<string> hashG = client.GetIntersectFromSets(new string[] { "Set1001", "Set1002" });
            foreach (string item in hashG)
            {
                Console.WriteLine("求Set1001和Set1002的交集:{0}", item);  //交集
            }

            HashSet<string> hashD = client.GetDifferencesFromSet("Set1001", new string[] { "Set1002" });  //[返回存在于第一个集合,但是不存在于其他集合的数据。差集]
            foreach (string item in hashD)
            {
                Console.WriteLine("求Set1001和Set1002的差集:{0}", item);  //差集
            }

            #endregion

            #region  SetSorted 有序集合的测试代码
            /*
             sorted set 是set的一个升级版本,它在set的基础上增加了一个顺序的属性,这一属性在添加修改.元素的时候可以指定,
             * 每次指定后,zset(表示有序集合)会自动重新按新的值调整顺序。可以理解为有列的表,一列存 value,一列存顺序。操作中key理解为zset的名字.
             */
            client.AddItemToSortedSet("SetSorted1001", "1.刘仔");
            client.AddItemToSortedSet("SetSorted1001", "2.星仔");
            client.AddItemToSortedSet("SetSorted1001", "3.猪仔");
            List<string> listSetSorted = client.GetAllItemsFromSortedSet("SetSorted1001");
            foreach (string item in listSetSorted)
            {
                Console.WriteLine("SetSorted有序集合{0}", item);
            }
            #endregion

对此具体品种的类对象,也足以使用As方法开展更换为对应的处理目的开展拍卖,如下所示

IRedisTypedClient<Phone> phones = client.As<Phone>();

实际的测试代码如下所示。

        /// <summary>
        /// Redis对对象类的处理例子
        /// </summary>
        private void btnTypeValue_Click(object sender, EventArgs e)
        {
            IRedisTypedClient<Phone> phones = client.As<Phone>();
            Phone phoneFive = phones.GetValue("5");
            if (phoneFive == null)
            {
                Thread.Sleep(50);
                phoneFive = new Phone
                {
                    Id = 5,
                    Manufacturer = "Apple",
                    Model = "xxxxx",
                    Owner = new Person
                    {
                        Id = 1,
                        Age = 100,
                        Name = "伍华聪",
                        Profession = "计算机",
                        Surname = "wuhuacong"
                    }
                };

                phones.SetEntry(phoneFive.Id.ToString(), phoneFive);
            }

            client.Store<Phone>(
                new Phone
                {
                    Id = 2,
                    Manufacturer = "LG",
                    Model = "test-xxx",
                    Owner = new Person
                    {
                        Id = 2,
                        Age = 40,
                        Name = "test",
                        Profession = "teacher",
                        Surname = "wuhuacong"
                    }
                });

            var message = "Phone model is " + phoneFive.Manufacturer + ",";
            message += "Phone Owner Name is: " + phoneFive.Owner.Name;
            Console.WriteLine(message);
        }

如上就是有关Redis的设置以及简单的事例使用验证,在实际中,大家可以采取Redis的高性能特点,来构建大家的缓存数据,并且可以运用Redis和MongoDB数据库的健全衔接,可以整合一起做的更好,为相关的后台提供更高效的多少处理操作,毕竟在互联网的大环境下,性能是越发首要的。