专题二:Redis快速入门

最后更新于:2022-04-02 00:35:41

[TOC] # 一、前言    在前一篇博文介绍了MongoDB基本操作,本来打算这篇博文继续介绍MongoDB的相关内容的,例如索引,主从备份等内容的,但是发现这些内容都可以通过官方文档都可以看到,并且都非常详细,所以这里就不想继续介绍了,需要用到的朋友到官方文档进行查阅:[http://docs.mongodb.org/manual/tutorial/remove-indexes/](http://docs.mongodb.org/manual/tutorial/remove-indexes/)。本专题将介绍另一个NoSQL——Redis的相关内容。 # 二、Redis介绍   关于Redis大家肯定多多少少都有所了解,Redis一般都用来做缓存的,当然也可以作为消息队列。这里就直接网上一段比较好的介绍:   Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。   Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。 **Redis支持两种持久化方式:**    (1):snapshotting(快照)也是默认方式.(把数据做一个备份,将数据存储到文件)    (2)Append-only file(缩写aof)的方式     快照是默认的持久化方式,这种方式是将内存中数据以快照的方式写到二进制文件中,默认的文件名称为dump.rdb.可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key键修改就自动做快照.    aof方式:由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。  # 三、Windows下Redis的安装   Redis官方下载(官方地址:[http://redis.io/download](http://redis.io/download))只能用于Linux环境下,所以要在Windows环境下安装Redis就不能从官方进行下载了。为了能够在Windows平台安装Redis,微软的Microsoft Open Tech团队为我们开发了Windows版本下Redis。下载地址为:[https://github.com/MSOpenTech/redis](https://github.com/MSOpenTech/redis),但是Microsoft Open Tech团队开发的最新版本只能应用于64位操作系统,但是我使用的还是32位操作系统,那是不是我就不能安装Redis了呢?幸好微软之前开发的Redis之前版本还是支持32位系统的,所以我本机只能安装之前的版本了。这里我选择的是2.6版本,下载地址:[https://github.com/MSOpenTech/redis/tree/2.6/bin/release](https://github.com/MSOpenTech/redis/tree/2.6/bin/release)。下载redisbin.zip文件之后直接解压到指定目录就完成了Redis的安装了,解压成功后,你将看到如下几个Dll: * redis-server.exe:服务程序   * redis-check-dump.exe:本地数据库检查  * redis-check-aof.exe:更新日志检查  * redis-benchmark.exe:性能测试,用以模拟同时由N个客户端发送M个 SETs/GETs 查询. * redis-cli.exe: 服务端开启后,我们的客户端就可以输入各种命令测试了    接下来,只需要双击redis-server.exe程序就可以启动Redis服务,在2.6版本中可以不指定config路径,不像网上的Redis介绍文章都需要指定config文件,因为它们下载一般都是更早的版本,如2.4等版本。在2.6版本不需要特别指定config文件就可以启动成功,启动成功的界面如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad7f714ba.png)   服务启动成功后,我们就可以像MongoDB一样,开启redis-cli.exe客户端程序要操作Redis服务器,关于使用redis-cli.exe客户端命令的方式这里就不介绍了,更多可以参考官方文档,因为对我们来说,更常用的是使用C#、Java来操作Redis服务。在第四部分我将介绍使用C#来操作Redis。   一般服务我们都是用Windows Service来启动的,对于最新版本的Redis安装为Windows Service官方有详细的介绍,由于这里我不是用的最新版本,并且还是32位的,所以这里我安装Windows Service是通过sc([http://www.cnblogs.com/jankie/archive/2011/08/03/2126249.html](http://www.cnblogs.com/jankie/archive/2011/08/03/2126249.html))命令来安装的,具体的安装脚本如下所示: ~~~ sc create Redis start= auto DisplayName= Redis binpath= "F:\Study\No-Sql\Redis\redis-windows\RedisService.exe" ~~~   其中RedisService是Redis注册Windows服务的启动程序,具体下载地址为:[http://files.cnblogs.com/files/zhili/RedisService.zip](http://files.cnblogs.com/files/zhili/RedisService.zip)    通过上面的脚本就可以成功安装Redis为Windows Service了,然后每次系统启动的时候,就会自动开启Redis服务,而不需要我们每次去手动运行redis-server.exe命令了。 # 四、C#如何操作Redis    前面我们已经准备成功开启Redis服务,其端口号为6379,接下来我们就看看如何使用C#语言来操作Redis。就如MongoDB一样,要操作Redis服务,自然就需要下载C#的客户端,这里通过Nuget下载了“ServiceStack.Redis”客户端,引入成功之后,就可以使用C#来对Redis服务进行操作了。   由于Redis一般是用来作为缓存的,也就是一般我们把一些不经常改变的数据通过Redis缓存起来,之后用户的请求就不需要再访问数据库,而可以直接从Redis缓存中直接获取,这样就可以减轻数据库服务器的压力以及加快响应速度。既然是用来做缓存的,也就是通过指定key值来把对应Value保存起来,之后再根据key值来获得之前缓存的值。具体的操作代码如下所示,这里就不过多介绍了。 ~~~ class Program { static void Main(string[] args) { //在Redis中存储常用的5种数据类型:String,Hash,List,SetSorted set var client = new RedisClient("127.0.0.1", 6379); //AddString(client); //AddHash(client); //AddList(client); //AddSet(client); AddSetSorted(client); Console.ReadLine(); } private static void AddString(RedisClient client) { var timeOut = new TimeSpan(0,0,0,30); client.Add("Test", "Learninghard", timeOut); while (true) { if (client.ContainsKey("Test")) { Console.WriteLine("String Key: Test -Value: {0}, 当前时间: {1}", client.Get("Test"), DateTime.Now); Thread.Sleep(10000); } else { Console.WriteLine("Value 已经过期了,当前时间:{0}", DateTime.Now); break; } } var person = new Person() {Name = "Learninghard", Age = 26}; client.Add("lh", person); var cachePerson = client.Get("lh"); Console.WriteLine("Person's Name is : {0}, Age: {1}", cachePerson.Name, cachePerson.Age); } private static void AddHash(RedisClient client) { if (client == null) throw new ArgumentNullException("client"); client.SetEntryInHash("HashId", "Name", "Learninghard"); client.SetEntryInHash("HashId", "Age", "26"); client.SetEntryInHash("HashId", "Sex", "男"); var hashKeys = client.GetHashKeys("HashId"); foreach (var key in hashKeys) { Console.WriteLine("HashId--Key:{0}", key); } var haskValues = client.GetHashValues("HashId"); foreach (var value in haskValues) { Console.WriteLine("HashId--Value:{0}", value); } var allKeys = client.GetAllKeys(); //获取所有的key。 foreach (var key in allKeys) { Console.WriteLine("AllKey--Key:{0}", key); } } private static void AddList(RedisClient client) { if (client == null) throw new ArgumentNullException("client"); client.EnqueueItemOnList("QueueListId", "1.Learnghard"); //入队 client.EnqueueItemOnList("QueueListId", "2.张三"); client.EnqueueItemOnList("QueueListId", "3.李四"); client.EnqueueItemOnList("QueueListId", "4.王五"); var queueCount = client.GetListCount("QueueListId"); for (var i = 0; i < queueCount; i++) { Console.WriteLine("QueueListId出队值:{0}", client.DequeueItemFromList("QueueListId")); //出队(队列先进先出) } client.PushItemToList("StackListId", "1.Learninghard"); //入栈 client.PushItemToList("StackListId", "2.张三"); client.PushItemToList("StackListId", "3.李四"); client.PushItemToList("StackListId", "4.王五"); var stackCount = client.GetListCount("StackListId"); for (var i = 0; i < stackCount; i++) { Console.WriteLine("StackListId出栈值:{0}", client.PopItemFromList("StackListId")); //出栈(栈先进后出) } } //它是string类型的无序集合。set是通过hash table实现的,添加,删除和查找,对集合我们可以取并集,交集,差集 private static void AddSet(RedisClient client) { if (client == null) throw new ArgumentNullException("client"); client.AddItemToSet("Set1001", "A"); client.AddItemToSet("Set1001", "B"); client.AddItemToSet("Set1001", "C"); client.AddItemToSet("Set1001", "D"); var hastset1 = client.GetAllItemsFromSet("Set1001"); foreach (var item in hastset1) { Console.WriteLine("Set无序集合Value:{0}", item); //出来的结果是无须的 } client.AddItemToSet("Set1002", "K"); client.AddItemToSet("Set1002", "C"); client.AddItemToSet("Set1002", "A"); client.AddItemToSet("Set1002", "J"); var hastset2 = client.GetAllItemsFromSet("Set1002"); foreach (var item in hastset2) { Console.WriteLine("Set无序集合ValueB:{0}", item); //出来的结果是无须的 } var hashUnion = client.GetUnionFromSets(new string[] { "Set1001", "Set1002" }); foreach (var item in hashUnion) { Console.WriteLine("求Set1001和Set1002的并集:{0}", item); //并集 } var hashG = client.GetIntersectFromSets(new string[] { "Set1001", "Set1002" }); foreach (var item in hashG) { Console.WriteLine("求Set1001和Set1002的交集:{0}", item); //交集 } var hashD = client.GetDifferencesFromSet("Set1001", new string[] { "Set1002" }); //[返回存在于第一个集合,但是不存在于其他集合的数据。差集] foreach (var item in hashD) { Console.WriteLine("求Set1001和Set1002的差集:{0}", item); //差集 } } /* sorted set 是set的一个升级版本,它在set的基础上增加了一个顺序的属性,这一属性在添加修改.元素的时候可以指定, * 每次指定后,zset(表示有序集合)会自动重新按新的值调整顺序。可以理解为有列的表,一列存 value,一列存顺序。操作中key理解为zset的名字. */ private static void AddSetSorted(RedisClient client) { if (client == null) throw new ArgumentNullException("client"); client.AddItemToSortedSet("SetSorted1001", "A"); client.AddItemToSortedSet("SetSorted1001", "B"); client.AddItemToSortedSet("SetSorted1001", "C"); var listSetSorted = client.GetAllItemsFromSortedSet("SetSorted1001"); foreach (var item in listSetSorted) { Console.WriteLine("SetSorted有序集合{0}", item); } client.AddItemToSortedSet("SetSorted1002", "A", 400); client.AddItemToSortedSet("SetSorted1002", "D", 200); client.AddItemToSortedSet("SetSorted1002", "B", 300); // 升序获取第一个值:"D" var list = client.GetRangeFromSortedSet("SetSorted1002", 0, 0); foreach (var item in list) { Console.WriteLine(item); } //降序获取第一个值:"A" list = client.GetRangeFromSortedSetDesc("SetSorted1002", 0, 0); foreach (var item in list) { Console.WriteLine(item); } } } class Person { public string Name { get; set; } public int Age { get; set; } } ~~~   如何要想查看自己操作是否成功,也可以像MongoDB那样下载一个客户端工具,这里推荐一款Redis Desktop Manager。这个工具就相当于SQL Server的客户端工具一样。通过这款工具可以查看Redis服务器中保存的数据和对应格式。其使用也非常简单,只需要添加一个Redis服务连接即可。该工具的下载地址为:[http://pan.baidu.com/s/1sjp55Ul](http://pan.baidu.com/s/1sjp55Ul) # 五、小结    到此,本专题的内容就介绍结束了。关于Redis更深入的内容我觉得大家可以在项目中用到了可以自己深入研究,这里只是作为一个快速入门的教程。所以该NoSQL系列可能会先告一段落,接下来将计划一个全新的系列:Web API和Windows Azure系列。   本文所有源码下载地址:[http://files.cnblogs.com/files/zhili/RedisQuickStart.zip](http://files.cnblogs.com/files/zhili/RedisQuickStart.zip) > 原文出处:http://www.cnblogs.com/zhili/p/MongodbQuickStart.html
';

专题一:MongoDB快速入门

最后更新于:2022-04-02 00:35:39

[TOC] # 一、前言    现在越来越多的公司开始采用非关系数据库了,并且很多公司的面试都要求面试者有MongoDB的使用经验,至于非关系数据库与关系型数据库之间的区别大家可以自行百度。但是作为程序员的我们,既然大部分公司都需要有NOSQL的使用经验,自然我们就应该学习起来了。所以也就有了这个系列了。NOSQL包括很多,但是使用最大的还是属于MongoDB和Redis。所以在本系列中将详细介绍下这两种非关系数据库的环境搭建和一些常规使用。本专题就首先介绍下MongoDB开发环境的搭建和完成一些简单的增删改查操作。下面就随着我一起去学习吧。 # 二、MongoDB开发环境搭建    MongoDB的开发环境的搭建相对来说还是很简单的,尽管说MongoDB是非关系数据库,但是和关系型数据(如SQL Server)一样,都是用来持久化数据的。自然和非关系型数据目的是一样的,其开发方式也是非常类似的。大家都知道,在对SQL Server进行操作时,需要搭建一个SQL Server服务器,然后用.NET的相关技术充当客户端来对SQL Server服务器进行操作,来完成对数据的持久化保存操作。所以,对于MongDB的开发模式也是一样的,只是它们之间持久化的数据格式不一样而已。SQL Server等关系型数据库都是以表来保存数据的,而MongoDB等非关系型数据库都是以JSON格式来保存数据的。   既然,它们的开发模式是一样的,在之前我们对SQL Server操作都是首先需要连接SQL Server服务器,然后本地开发需要引入SQL Server驱动来进行开发。所以MongoDB的开发环境的搭建也不例外。   首先,我们需要去MongoDB下载MongoDB。下载地址:[https://www.mongodb.org/downloads](https://www.mongodb.org/downloads)。由于,我的操作系统是32位的,所以我这里下载的版本就是32位3.0.4版本。下载下来后,然后进行解压。    其实,到这里,MongoDB的开发环境就完成了。这里大家肯定会问,不会吧,这么快,以前SQL Server安装程序可是要安装很久的啊,怎么MongoDB这么快就好?此时大家千万不要疑惑,此时开发环境真的已经大家好了。下面就让我们看看如何通过来完成对MongoDB的增删改查操作。 # 三、基本操作    首先,打开命令行工具,然后切换到你MongoDB所在的目录。通过允许mongod.exe程序来启动MongoDB服务器,同时还需要用--dbpath参数来指定数据存放的文件夹。如果不指定参数将不能成功启动MongoDB服务,具体的命令如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad3652244.png)   通过上图可以看到,我们的MongoDB服务已经启动成功了,MongoDB默认监听的端口就是27017。下面就通过浏览器来验证下MongoDB服务是否启动成功了。输入地址:[http://localhost:27017/](http://localhost:27017/)。打开后,如果看到如下图所示的结果,就表明MongoDB服务已经启动成功了。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad3676522.png)   既然,MongoDB服务已经启动了,接下来就需要客户端对服务器进行请求来完成把数据保存到服务器上。我们同样可以通过命令行的方式来启动MongoDB的客户端,重新打开一个命令行工具,通过mongo.exe命令来启动MongoDB的客户端。具体命令如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad3695b86.png)   从上图可以看到,客户端默认链接的是"test"数据库,就如SQL Server默认链接的是master数据库一样。既然,我们客户端和服务器都已经准备好了,接下来就需要在客户端通过命令来发出对服务器的请求,来完成增删改查操作。   数据库我们已经有了,即"test"数据库,按照常规的数据库操作,我们需要创建一个表,然后往表里插入一条数据。但是在非关系数据库中,并没有表的概念,只有集合的概念,大家可以把非关系数据库中集合的概念理解为关系数据库中表的一个概念。并且在MongoDB中并不需要单独的创建集合命令,因为在插入的数据的同时也会完成集合的创建。这里把需要创建的集合命名为"person"。通过**insert()方法**来完成数据的插入。具体的命令如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad36aff5b.png)   通过上面可以看出,我们已经成功像person集合插入了2条记录。可以通过find()方法来查询下集合person中是否现在已经存在2条记录。具体的查找命令如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad36c98dd.png)   从图中可以发现,我们确实已经成功插入了2条记录了,并且MongoDB服务已经自动为其加入_id这个字段,该字段的值也是由MongoDB服务默认为我们生成的GUID,来保证数据的唯一性。除此之外,我们还可以指定特定的筛选条件来筛选记录。具体命令如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad36e8d28.png)  接下来,我们可以通过update()和remove()方法来完成数据的删除和更新。具体的命令和效果如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad3757c50.png)   update方法的第一个参数为“查询条件”,第二个参数为“更新的值”。remove方法如果不带参数将删除所有数据**(db.person.remove( { } ))**。带参数指的是“查询条件”,即删除掉查询到的数据。   通过上面,我们就完成了MongoDB的增删改查操作了。上面,我们是通过命令行的方式来完成的,但是这样的方式未免有些不方便,此时就想:有没有什么GUI的工具来完成这些操作呢?就如SQL Server的客户端那样。对于这点,答案是肯定的,这里我用的是“MongoVUE 1.5.3”版本,个人觉得还是蛮还用的,大家可以去百度云盘去下载破解版的。下面让我们通过MongoDB客户端的GUI工具来查询下刚才我们插入的数据,打开“MongoVUE”工具,然后点Connect按钮来创建链接,连接就如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad378153f.png)   链接成功之后,我们就可以看到类似SQL Server那样的数据库结构界面了,具体的效果如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad3796299.png)   并且通过GUI客户端工具可以很方便地完成增删改查操作,而不需要手敲命令去完成。 # 四、通过C#来操作MongoDB    上面已经介绍了通过命令行和客户端GUI工具来完成对MongoDB的操作,但是实际开发过程中,我们用的更多还是通过代码来完成数据的持久化。下面就简单介绍下,如果通过C#语言来完成对MongoDB的增删改查操作。   同样,我们用C#来操作MongoDB,一样也需要启动MongoDB服务器,只有服务启动了,我们才能对其操作,说白了我们的程序就是充当一个客户端,然后通过C#语言来发送命令让MongoDB服务器执行相应的增删改查操作,但是之前MongoDB服务宿主在控制台中的,这样的宿主方式太过于麻烦了。因为每次服务重启之后,还需要手动通过命令行方式来启动服务。然而服务一般都是让其自启动的。所以MongoDB服务也可以宿主支持宿主在Windows服务中。首先,以管理员权限启动命令行,然后输入如下命令来将MongoDB宿主在Windows服务中: mongod --dbpath=F:\Study\No-Sql\MongoDB\data --logpath=F:\Study\No-Sql\MongoDB\log\mongolog.txt --port 2322 --install. 具体的运行效果如下图所示: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-08-04_55c0ad37ba83f.png)    从上图可以看出,我们还可以通过--remove命令来移除服务,并且在指定logpath和dbpath参数的时候必须指定为绝对路径,否则会出现错误,并且指定logpath参数的值时,文件名必须要指定,如果文件在指定目录下存在的话会报出警告说文件名已存在,已将日志移动另外一个日志文件下了,但是这不影响,服务依然可以安装成功。关于mongod.exe的更多命令可以通过 mongod /help来查看。创建成功后,你将在Windows服务列表将查看到。然后进行启动即可。这样每次服务重启就不需要手动去执行命令行了,服务会指定重启。   下面我们还是回到正题。在使用C#操作MongoDB服务器之前,我们还需要下载对应的驱动程序,这样才能通过C#来访问到服务器,这里通过Nuget来下载官方的“MongoDB.Driver”驱动,下载完成之后,就可以用C#代码来调用驱动中的API来操作mongoDB。其操作代码基本与命令行的方式差不多,这里就不一一解释了,大家可以自行看下面的代码和参考命令行来进行理解。具体的代码如下所示: ~~~ using System.Collections.Generic; using System.Threading.Tasks; using MongoDB.Bson; using MongoDB.Driver; namespace MongodbDemo { class Program { static void Main(string[] args) { var mongodbHelper =new MongodbHelper(); //var updateTask = mongodbHelper.Update(new Person() { Name = "LearninghardUpdate", Age = 25 }); //updateTask.Wait(); var taskAdd = mongodbHelper.Add(new Person() { Id = ObjectId.GenerateNewId().ToString(), Name = "Learninghard2", Age = 25 }); taskAdd.Wait(); foreach (var person in mongodbHelper.SelectAll()) { Console.WriteLine("Name: {0}, Age: {1}", person.Name, person.Age); } Console.Read(); } } public class MongodbHelper { private const string Conn = "mongodb://localhost:2322"; private const string DbName = "test"; private const string TbName = "person"; private readonly MongoClient client; private readonly IMongoDatabase dbDatabase; public MongodbHelper() { // 创建数据连接 client = new MongoClient(Conn); // 获取指定数据库 dbDatabase = client.GetDatabase(DbName); } public async Task Add(Person p) { // 获取表 var collection = dbDatabase.GetCollection(TbName); // 插入 await collection.InsertOneAsync(p); } public async Task Delete(string name) { var collection = dbDatabase.GetCollection(TbName); var filter = Builders.Filter.Eq("Name", name); await collection.DeleteOneAsync(filter); } public async Task Update(Person p) { //获取表 var col = dbDatabase.GetCollection(TbName); var filter = Builders.Filter.Eq("Age", p.Age); var update = Builders.Update.Set("Name", p.Name); await col.UpdateManyAsync(filter, update); } public Person SelectOne(string name) { var collection = dbDatabase.GetCollection(TbName); var filter = Builders.Filter.Eq("Name", name); var person = collection.Find(filter).FirstAsync().Result; return person; } public IEnumerable SelectAll() { var persons =new List(); var collection = dbDatabase.GetCollection(TbName); var result = collection.Find(p => true).ToListAsync(); result.Wait(); persons.AddRange(result.Result); return persons; } } public class Person { public string Id { get; set; } public string Name { get; set; } public int Age { get; set; } } } ~~~   具体的运行效果这里就不贴图了,大家可以自行下载代码进行运行查看。 # 五、总结    到此,本专题的内容就介绍结束,本专题只是简单介绍了MongoDB开发环境的搭建和通过命令行和MongoDB GUI工具来对MongoDB进行操作,最后介绍了在实际开发环境中,通过C#来操作MongoDB以及将MongoDB宿主在Windows服务中。本专题只是一个开始,希望本专题可以使得大家对MongoD可以快速入门。接下来的专题将介绍MongoDB索引、集群和故障转移的支持。   本专题所有源码下载:[http://files.cnblogs.com/files/zhili/MongoDBQuickStart.zip](http://files.cnblogs.com/files/zhili/MongoDBQuickStart.zip) > 原文出处:http://www.cnblogs.com/zhili/p/MongodbQuickStart.html
';