基于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,set及zset(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的服务在运行了,如下图所示。
安装好Redis后,还有一个Redis伴侣Redis Desktop Manager需要安装,这样可以实时查看Redis缓存里面有哪些数据,具体地址如下:http://redisdesktop.com/download
下载属于自己平台的版本即可
下载安装后,打开运行界面,如果我们往里面添加键值的数据,那么可以看到里面的数据了。
2、Redis的C#使用
Redis目前提供四种数据类型:string,list,set及zset(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", );
在使用前,我们需要清空所有的键值存储,使用FushAll方法即可,如下所示
//Redis FlushAll 命令用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。
client.FlushAll();
根据上面的驱动,可以为不同类型的处理编写一些演示代码,下面代码是摘录网上的案例进行介绍。
#region string类型的测试代码 client.Add<string>("StringValueTime", "带有有效期的字符串", DateTime.Now.AddMilliseconds()); while (true)
{
if (client.ContainsKey("StringValueTime"))
{
Console.WriteLine("String.键:StringValue, 值:{0} {1}", client.Get<string>("StringValueTime"), DateTime.Now);
Thread.Sleep();
}
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 = "", 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", "");
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", ));
for (int i = ; 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 = ; 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("");
if (phoneFive == null)
{
Thread.Sleep();
phoneFive = new Phone
{
Id = ,
Manufacturer = "Apple",
Model = "xxxxx",
Owner = new Person
{
Id = ,
Age = ,
Name = "伍华聪",
Profession = "计算机",
Surname = "wuhuacong"
}
}; phones.SetEntry(phoneFive.Id.ToString(), phoneFive);
} client.Store<Phone>(
new Phone
{
Id = ,
Manufacturer = "LG",
Model = "test-xxx",
Owner = new Person
{
Id = ,
Age = ,
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数据库的完美衔接,可以整合一起做的更好,为相关的后台提供更高效的数据处理操作,毕竟在互联网的大环境下,性能是非常重要的。
基于C#的MongoDB数据库开发应用(4)--Redis的安装及使用的更多相关文章
- 基于C#的MongoDB数据库开发应用(2)--MongoDB数据库的C#开发
在上篇博客<基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用>里面,我总结了MongoDB数据库的一些基础信息,并在最后面部分简单介绍了数据库C#驱动的 ...
- 基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用
在花了不少时间研究学习了MongoDB数据库的相关知识,以及利用C#对MongoDB数据库的封装.测试应用后,决定花一些时间来总结一下最近的研究心得,把这个数据库的应用单独作为一个系列来介绍,希望从各 ...
- 基于C#的MongoDB数据库开发应用(3)--MongoDB数据库的C#开发之异步接口
在前面的系列博客中,我曾经介绍过,MongoDB数据库的C#驱动已经全面支持异步的处理接口,并且接口的定义几乎是重写了.本篇主要介绍MongoDB数据库的C#驱动的最新接口使用,介绍基于新接口如何实现 ...
- EOS主网搭建教程--&&--搭建节点--&&--搭建mongodb数据库
EOS主网搭建教程: 1.git clone https://github.com/EOS-Mainnet/eos.git --recursive 2.cd eos 3.git tag (查看有哪些分 ...
- 连接MongoDb数据库 -- Python
1.安装完mongoDb数据库后,如果需要我们的Python程序和MongoDb数据库进行交互,需要安装pymongo模块: 安装方式:采用pip install pymongo的方式 Microso ...
- 三、redis环境安装
三.redis环境安装 3.1.下载和安装 下载地址:https://github.com/tporadowski/redis/releases 使用以下命令启动redis服务端 redis-se ...
- Python学习笔记(五)之Python操作Redis、mysql、mongodb数据库
操作数据库 一.数据库 数据库类型主要有关系型数据库和菲关系型数据库. 数据库:用来存储和管理数的仓库,数据库是通过依据“数据结构”将数据格式化,以记录->表->库的关系存储.因此数据查询 ...
- Redis/Mysql/SQLite/MongoDB 数据库对比
一.Redis: redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(so ...
- 基于 Vue + Koa2 + MongoDB + Redis 实现一个完整的登录注册
项目地址:https://github.com/caochangkui/vue-element-responsive-demo/tree/login-register 通过 vue-cli3.0 + ...
随机推荐
- .NET Core中合并Expression<Func<T,bool>>的正确姿势
这是在昨天的 .NET Core 迁移中遇到的问题,之前在 .NET Framework 中是这样合并 Expression<Func<T,bool>> 的: public s ...
- io.js入门(二)—— 所支持的ES6(上)
io.js的官网上有专门介绍其所支持的ES6特性的页面(点我查看),上面介绍到,相比nodeJS,io.js已从根本上支持了新版V8引擎上所支持的ES6特性,无需再添加任何运行时标志(如 --harm ...
- 【性能为王】从PHP源码剖析array_keys和array_unique
之前在[译]更快的方式实现PHP数组去重这篇文章里讨论了使用array_flip后再调用array_keys函数替换直接调用array_unique函数实现数组去重性能较好.由于原文没有给出源码分析和 ...
- 一小时学会C# 6
c# 6已经出来有一段时间了,今天我们就详细地看一下这些新的特性. 一.字符串插值 (String Interpolation) C# 6之前我们拼接字符串时需要这样 var Name = " ...
- 你所不知道的JavaScript数组
相信每一个 javascript 学习者,都会去了解 JS 的各种基本数据类型,数组就是数据的组合,这是一个很基本也十分简单的概念,他的内容没多少,学好它也不是件难事情.但是本文着重要介绍的并不是我们 ...
- sleep和wait区别
1. sleep和wait都是用来进行线程控制,他们最大本质的区别是: sleep()不释放同步锁,wait()释放同步锁. sleep(milliseconds)可以用时 ...
- fir.im Weekly - 让 iOS 应用更加安全
攻易防难,关于 iOS 应用安全看起来有些神秘.iOS Security , 源于@吴发伟_则平博客翻译的关于iOS安全的一系列文章,现在站点已经系统收集了大量关于 iOS 逆向.安全.反编译.静动态 ...
- 【hbase0.96】基于hadoop搭建hbase的心得
hbase是基于hadoop的hdfs框架做的分布式表格存储系统,所谓表格系统就是在k/v系统的基础上,对value部分支持column family和column,并支持多版本读写. hbase的工 ...
- 用Mindjet MindManager 15 打开文件后停止响应的解决方法
这个是因为文件里面有很多规格不统一的注释(那个像小本子的图标[里面就是注释部分]),默认编码是utf-8的,如果不一样的话就会出现这个问题.网上大多数都是让咱们删掉注释再打开 弱弱的问一下,如果我都把 ...
- LINQ系列:Linq to Object联接操作符
联接是指将一个数据源对象与另一个数据源对象进行关联或联合的操作.这两个数据源对象通过一个共同的值或属性进行关联. LINQ的联接操作符将包含可匹配(或相同)关键字的两个或多个数据源中的值进行匹配. L ...