第一部分:为什么我的项目中要使用Redis
我知道有些地方没说到位,希望大神们提出来,我会吸取教训,大家共同进步!
- 注册时邮件激活的部分使用Redis
- 发送邮件时使用Redis的消息队列,减轻网站压力。
- 使用Lucene.Net在进行分词时使用Redis消息队列和多线程来避免界面卡死等性能问题。
- 请大家先思考一个问题:这个问题在大并发、高负载的网站中必须考虑!大家思考如何让速度更快。
三种方法:(1)数据库(2)页面静态化(3)Redis、Memcached
第二部分:Redis是什么
概述:redis是一种nosql数据库,他的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,并且他比memcached支持更多的数据结构(string,list列表[队列和栈],set[集合],sorted set[有序集合] hash(hash表))
2.1介绍:
- Redis是一个高性能的key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。
- Redis 很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。(注: 摘自百度全科),1.主要是支持持久化2.支持更多数据结构 3.支持主从同步
- Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。
2.2 memcached和redis的比较:
2.3Redis的优势:
2.4Redis在windows下的安装:
注:关于Redis的安装网上有很多文章,讲的要比我的好,建议大家去看那些大神的文章,这里我只简单介绍一下。
![](https://i-blog.csdnimg.cn/blog_migrate/d2a6d41f4230e0c373184e4fd75546f8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2b9b9ccaf49fbe3766dee73a157f10a2.png)
如果你看到有6379 在监听,说明ok(默认的端口号时候:6379)
2.5Redis的数据结构:
前言:Redis中存储的数据都为字符串格式的。下面来分别介绍Redis中常用的数据结构。
- string数据结构
太简单了,略过。
- list数据结构
概述: 什么是list ,list是一种数据结构,可以当做队列和栈来使用。
当你从左边添加数据,再从左边取数据,就模拟出栈;当你从右边添加数据,再从左边取数据,就模拟出队列。因此Redis真的很强大,看到栈和队列这样的数据结构,你难道就不激动吗?这样的数据结构太TM好了,能帮我们处理很多棘手的问题。这里我先卖个关子,下面会介绍我在项目中是如何使用Redis解决棘手的问题。
- set集合
和list结构差不多,这里不再啰嗦。
下面就是操作set的一些命令。
- hash数据结构
图中的"user:100"就相当于key,而它所指向的类似于表结构的数据就是value,这样的数据结构有利于存储对象数据。也是非常常用的方法。
注意:
redis指令不区分大小写,但是出于规范考虑,应该使用大写
redis中存放的键是区分大小写的.
Redis常用命令文档:http://redis.readthedocs.io/en/2.6/
第三部分:Redis如何使用
3.1C#中如何使用Redis来解决邮箱激活的实效性。
首先思考个问题:为什么要进行邮件激活?激活码该存到哪里?(大家先思考,我不直接说,这样通过下面的例子你会体会的更深。)
原因:用户在注册的时候,虽然正则表达式能检查邮箱的格式是否正确,但是正则检查不了邮箱是否可用,于是让用户进行激活,就能避免用户填写一个不可用的邮箱。
传统方法的代码实现:
1)数据库表的设计:
在用户注册的表中添加一个字段:IsActive用来判断激活的状态。
该表用来存放激活码。
代码实现:
BLL层代码:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
DAL层代码:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
UI层代码:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
一般处理程序:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
邮件发送代码:
public static void SendEmail(string toEmail, string subject, string body) { string smtpServer = ConfigurationManager.AppSettings["SmtpServer"]; string smtpFrom = ConfigurationManager.AppSettings["SmtpFrom"]; string smtpUserName = ConfigurationManager.AppSettings["SmtpUserName"]; string smtpPassword = ConfigurationManager.AppSettings["SmtpPassword"]; MailMessage mailObj = new MailMessage(); mailObj.IsBodyHtml = true; //from:abc@qq.com mailObj.From = new MailAddress(smtpFrom); //发送人邮箱地址 mailObj.To.Add(toEmail); //收件人邮箱地址 http://www.44wa.com/book/4843.html mailObj.Subject = subject; //主题 mailObj.Body = body; //正文 SmtpClient smtp = new SmtpClient();//通过.Net内置的SmtpClient类和邮件服务器进行通讯,发送邮件。 //是和发邮件方的smtp通讯,由发邮件方的邮件服务器和收邮件方的邮件服务器通讯进行邮件的转接。 smtp.Host = smtpServer; //smtp服务器名称 smtp.UseDefaultCredentials = true; smtp.Credentials = new NetworkCredential(smtpUserName, smtpPassword); //发送人的登录名和密码 smtp.Send(mailObj); } 关于邮箱的账号和密码最好配置到配置文件中。为了安全。
好好思考一下这样写的缺陷在哪?不仅有缺陷而且还有安全问题,有哪些安全问题?如果用户量大的话这样设计是否合理?会对什么有压力?如果不合理该如何优化?
首先我们来分析一下:
上面的方法是在用户表的基础上再增加一个字段,用来存激活码。这样合理吗?
由于激活码只用一次,所以在用户表的基础上再增加一个字段会麻烦一下,之前的功能会有影响。那到底该怎么解决比较好?
这时候Redis的好处就非常明显了,key-value数据库,并且还能设置数据的有效时间,很好的解决了上面遇到的问题,只需要改动上面很少的一部分代码就可以实现想要的功能。
代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
如果到这里真的就OK了吗?我在这里买个关子,大家可以想想为什么我要添加下面的这段代码:
1 //把注册用户信息,放入消息队列。便于另外一个程序来获取消息队列数据,发送邮件 2 using (var client = RedisManager.ClientManager.GetClient()) 3 { 4 string info = username + "|" + email; 5 client.EnqueueItemOnList("NewRegUsers", info); 6 }
请大家先好好思考一下,问题有哪些,在评论区可以提出来,后面我会一一分析,因为后面会提到很多东西,比如并发量、定时器、Redis的消息队列、多线程、Windows服务等等。尽情期待~~~~~~~~~~
第四部分:Redis使用过程中需要注意的地方
尽情期待~~~~~~~~~~
第五部分:总结
尽情期待~~~~~~~~~~