当前位置: 首页 > news >正文

基于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 updatessave配置,指出在多长时间内,有多少次更新操作,就将数据同步到数据文件。这个可以多个条件配合,比如默认配置文件中的设置,就设置了三个条件。

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的服务在运行了,如下图所示。

安装好Redis后,还有一个Redis伴侣Redis Desktop Manager需要安装,这样可以实时查看Redis缓存里面有哪些数据,具体地址如下:http://redisdesktop.com/download

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

下载安装后,打开运行界面,如果我们往里面添加键值的数据,那么可以看到里面的数据了。

 

2、Redis的C#使用

Redis目前提供四种数据类型:string,list,setzset(sorted set)和Hash。因此它在C#里面也有对应的封装处理,而且有很多人对他进行了封装,提供了很多的响应开发包,具体可以访问http://redis.io/clients#c 进行了解。一般建议用ServiceStack.Redis的封装驱动比较好,具体的使用可以参考https://github.com/ServiceStack/ServiceStack.Redis。

我们开发C#代码的时候,可以在NuGet程序包上面进行添加对应的ServiceStack.Redis引用,如下所示。

 

在弹出的NuGet程序包里面,输入ServiceStack.Redis进行搜索,并添加下面的驱动引用即可。

这样会在项目引用里面添加了几个对应的程序集,如下所示。

在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(

相关文章:

  • jz2440上内核和文件系统移植
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 事务隔离(二):基于加锁方式的事务隔离原理
  • mybatis随笔一之SqlSessionFactoryBuilder
  • 公司招聘
  • 在linux服务器上装svn版本管理,自动同步代码到项目根目录
  • web服务器配置及nginx和mysql部署
  • 2017.02.15
  • linux中的awk用法入门详解(二)
  • javascript事件失效l
  • 【Spark Summit East 2017】Spark,类型函数式编程的引诱者
  • linux命令大全之watch命令详解(监测命令运行结果)
  • Elasticsearch之更新(全部更新和局部更新)
  • mysql查看表结构
  • 使用Hilo.JS快速开发Flappy Bird
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • ES2017异步函数现已正式可用
  • fetch 从初识到应用
  • IDEA常用插件整理
  • Java精华积累:初学者都应该搞懂的问题
  • Meteor的表单提交:Form
  • pdf文件如何在线转换为jpg图片
  • Python爬虫--- 1.3 BS4库的解析器
  • Redis学习笔记 - pipline(流水线、管道)
  • 聚类分析——Kmeans
  • 力扣(LeetCode)21
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 前端临床手札——文件上传
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 函数计算新功能-----支持C#函数
  • ​渐进式Web应用PWA的未来
  • ​学习一下,什么是预包装食品?​
  • #pragma pack(1)
  • (C++20) consteval立即函数
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (转)iOS字体
  • ***测试-HTTP方法
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .net 无限分类
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .net下简单快捷的数值高低位切换
  • @Autowired @Resource @Qualifier的区别
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [2016.7.Test1] T1 三进制异或
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息
  • [Assignment] C++1
  • [BJDCTF2020]The mystery of ip1
  • [BZOJ 4034][HAOI2015]T2 [树链剖分]
  • [C#]手把手教你打造Socket的TCP通讯连接(一)
  • [CUDA手搓]从零开始用C++ CUDA搭建一个卷积神经网络(LeNet),了解神经网络各个层背后算法原理
  • [C语言][PTA基础C基础题目集] strtok 函数的理解与应用