ASP.NET Redis 开发

 

文件并发(日志处理)--队列--Redis+Log4Net

Redis简介

Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景。Redis纯粹为应用而产生,它是一个高性能的key-value数据库,并且提供了多种语言的API

性能测试结果表示SET操作每秒钟可达110000次,GET操作每秒81000次(当然不同的服务器配置性能不同)。

redis目前提供五种数据类型:string(字符串),list(链表), Hash(哈希),set(集合)及zset(sorted set)  (有序集合)

Redis与Memcached的比较.

1.Memcached是多线程,而Redis使用单线程.

2.Memcached使用预分配的内存池的方式,Redis使用现场申请内存的方式来存储数据,并且可以配置虚拟内存。

3.Redis可以实现持久化,主从复制,实现故障恢复。

4.Memcached只是简单的key与value,但是Redis支持数据类型比较多。

Redis的存储分为内存存储、磁盘存储 .从这一点,也说明了Redis与Memcached是有区别的。Redis 与Memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改 操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis有两种存储方式,默认是snapshot方式,实现方法是定时将内存的快照(snapshot)持久化到硬盘,这种方法缺点是持久化之后如果出现crash则会丢失一段数据。因此在完美主义者的推动下作者增加了aof方式。aof即append only mode,在写入内存数据的同时将操作命令保存到日志文件,在一个并发更改上万的系统中,命令日志是一个非常庞大的数据,管理维护成本非常高,恢复重建时间会非常长,这样导致失去aof高可用性本意。另外更重要的是Redis是一个内存数据结构模型,所有的优势都是建立在对内存复杂数据结构高效的原子操作上,这样就看出aof是一个非常不协调的部分。

其实aof目的主要是数据可靠性及高可用性.

Redis安装

文章的最后我提供了下载包,当然你也可以去官网下载最新版本的Redis https://github.com/dmajkic/redis/downloads

将服务程序拷贝到一个磁盘上的目录,如下图:

文件说明:

redis-server.exe:服务程序

redis-check-dump.exe:本地数据库检查

redis-check-aof.exe:更新日志检查

redis-benchmark.exe:性能测试,用以模拟同时由N个客户端发送M个 SETs/GETs 查询.

redis-cli.exe: 服务端开启后,我们的客户端就可以输入各种命令测试了

1、打开一个cmd窗口,使用cd命令切换到指定目录(F:\Redis)运行 redis-server.exe redis.conf

2、重新打开一个cmd窗口,使用cd命令切换到指定目录(F:\Redis)运行 redis-cli.exe -h 127.0.0.1 -p 6379,其中 127.0.0.1是本地ip,6379是redis服务端的默认端口 (这样可以开启一个客户端程序进行特殊指令的测试).

可以将此服务设置为windows系统服务,下载Redis服务安装软件,安装即可。(https://github.com/rgl/redis/downloads )

安装完成Redis服务后,我们会在计算机的服务里面看到

然后启动此服务。

接下来在使用Redis时,还需要下载C#驱动(也就是C#开发库),如下图:

Redis常用数据类型

使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不同的大象构建不同的冰箱。

Redis最为常用的数据类型主要有以下五种:

  • String
  • Hash
  • List
  • Set
  • Sorted set

String类型

String是最常用的一种数据类型,普通的key/value存储都可以归为此类 。一个Key对应一个Value,string类型是二进制安全的。Redis的string可以包含任何数据,比如jpg图片(生成二进制)或者序列化的对象。基本操作如下:

  1. var client = new RedisClient("127.0.0.1", 6379);
  2. client.Set<int>("pwd", 1111);
  3. int pwd=client.Get<int>("pwd");
  4. Console.WriteLine(pwd);
  5. UserInfo userInfo = new UserInfo() { UserName = "zhangsan", UserPwd = "1111" };<span style="font-family:宋体;">//</span>(底层使用json序列化 )
  6. client.Set<UserInfo>("userInfo", userInfo);
  7. UserInfo user=client.Get<UserInfo>("userInfo");
  8. Console.WriteLine(user.UserName);
  9. List<UserInfo> list = new List<UserInfo>() { new UserInfo(){UserName="lisi",UserPwd="111"},new UserInfo(){UserName="wangwu",UserPwd="123"} };
  10. client.Set<List<UserInfo>>("list",list);
  11. List<UserInfo>userInfoList=client.Get<List<UserInfo>>("list");
  12. foreach (UserInfo userInfo in userInfoList)
  13. {
  14. Console.WriteLine(userInfo.UserName);
  15. }

Hash类型

Hash是一个string 类型的field和value的映射表。hash特别适合存储对象。相对于将对象的每个字段存成单个string 类型。一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象。

作为一个key value存在,很多开发者自然的使用set/get方式来使用Redis,实际上这并不是最优化的使用方法。尤其在未启用VM情况下,Redis全部数据需要放入内存,节约内存尤其重要.

增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争 .. redis是个单线程的程序,为什么会这么快呢 ?

1、大量线程导致的线程切换开销

2、锁、

3、非必要的内存拷贝。

4. Redis多样的数据结构,每种结构只做自己爱做的事.

Hash对应的Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个HashMap的成员比较少时,Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,当成员量增大时会自动转成真正的HashMap.

Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和反序列化

  1. client.SetEntryInHash("user", "userInfo", "aaaaaaaaaa");
  2. List<string> list = client.GetHashKeys("user");
  3. List<string> list = client.GetHashValues("userInfo");//获取值
  4. List<string> list = client.GetAllKeys();//获取所有的key。

Redis为不同数据类型分别提供了一组参数来控制内存使用,我们在前面提到过的Redis Hash的value内部是一个

HashMap,如果该Map的成员比较少,则会采用一维数组的方式来紧凑存储该MAP,省去了大量指针的内存开销,这个参数在redis,conf配置文件中下面2项。

Hash-max-zipmap-entries 64

Hash-max-zipmap-value 512.

含义是当value这个Map内部不超过多少个成员时会采用线性紧凑格式存储,默认是64,即value内部有64个以下的成员就是使用线性紧凑存储,超过该值自动转成真正的HashMap.

Hash-max-zipmap-value含义是当value这个MAP内部的每个成员值长度不超过多少字节就会采用线性紧凑存储来节省空间。以上两个条件任意一个条件超过设置值都会转成真正的HashMap,也就不会再节省内存了,这个值设置多少需要权衡,HashMap的优势就是查找和操作时间短。

一个key可对应多个field,一个field对应一个value

这里同时需要注意,Redis提供了接口(hgetall)可以直接取到全部的属性数据,但是如果内部Map的成员很多,那么涉及到遍历整个内部Map的操作,由于Redis单线程模型的缘故,这个遍历操作可能会比较耗时,而另其它客户端的请求完全不响应,这点需要格外注意

建议使用对象类别和ID构成键名,使用字段表示对象属性,字

段值存储属性值,例如:car:2 price 500

List类型

list是一个链表结构,主要功能是push,pop,获取一个范围的所有的值等,操作中key理解为链表名字。 Redis的list类型其实就是一个每个子元素都是string类型的双向链表。我们可以通过push,pop操作从链表的头部或者尾部添加删除元素,这样list既可以作为栈,又可以作为队列。Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构

  1. //队列使用
  2. client.EnqueueItemOnList("name", "zhangsan");
  3. client.EnqueueItemOnList("name", "lisi");
  4. int count= client.GetListCount("name");
  5. for (int i = 0; i < count; i++)
  6. {
  7. Console.WriteLine(client.DequeueItemFromList("name"));
  8. }
  9. //栈使用
  10. client.PushItemToList("name2", "wangwu");
  11. client.PushItemToList("name2", "maliu");
  12. int count = client.GetListCount("name2");
  13. for (int i = 0; i < count; i++)
  14. {
  15. Console.WriteLine(client.PopItemFromList("name2"));
  16. }

Set类型

它是string类型的无序集合。set是通过hash table实现的,添加,删除和查找,对集合我们可以取并集,交集,差集.

  1. //对Set类型进行操作
  2. client.AddItemToSet("a3", "ddd");
  3. client.AddItemToSet("a3", "ccc");
  4. client.AddItemToSet("a3", "tttt");
  5. client.AddItemToSet("a3", "sssh");
  6. client.AddItemToSet("a3", "hhhh");
  7. System.Collections.Generic.HashSet<string>hashset=client.GetAllItemsFromSet("a3");
  8. foreach (string str in hashset)
  9. {
  10. Console.WriteLine(str);
  11. }
  12. //求并集
  13. client.AddItemToSet("a3", "ddd");
  14. client.AddItemToSet("a3", "ccc");
  15. client.AddItemToSet("a3", "tttt");
  16. client.AddItemToSet("a3", "sssh");
  17. client.AddItemToSet("a3", "hhhh");
  18. client.AddItemToSet("a4", "hhhh");
  19. client.AddItemToSet("a4", "h777");
  20. System.Collections.Generic.HashSet<string>hashset=  client.GetUnionFromSets(new string[] { "a3","a4"});
  21. foreach (string str in hashset)
  22. {
  23. Console.WriteLine(str);
  24. }
  25. //求交集
  26. System.Collections.Generic.HashSet<string> hashset = client.GetIntersectFromSets(new string[] { “a3”, “a4” });
  27. //求差集.
  28. System.Collections.Generic.HashSet<string> hashset = client.GetDifferencesFromSet("a3",new string[] { "a4"});

返回存在于第一个集合,但是不存在于其他集合的数据。差集

Sorted Set类型

sorted set 是set的一个升级版本,它在set的基础上增加了一个顺序的属性,这一属性在添加修改   .元素的时候可以指定,每次指定后,zset(表示有序集合)会自动重新按新的值调整顺序。可以理解为有列的表,一列存 value,一列存顺序。操作中key理解为zset的名字.

Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,

  1. client.AddItemToSortedSet("a5", "ffff");
  2. client.AddItemToSortedSet("a5","bbbb");
  3. client.AddItemToSortedSet("a5", "gggg");
  4. client.AddItemToSortedSet("a5", "cccc");
  5. client.AddItemToSortedSet("a5", "waaa");
  6. System.Collections.Generic.List<string> list =client.GetAllItemsFromSortedSet("a5");
  7. foreach (string str in list)
  8. {
  9. Console.WriteLine(str);
  10. }

Redis工具和所需资料代码全下载,地址:http://pan.baidu.com/s/155F6A

博客地址: http://www.cnblogs.com/jiekzou/
博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。

ASP.NET Redis 开发 入门的更多相关文章

  1. ASP.NET Redis 开发

    文件并发(日志处理)--队列--Redis+Log4Net Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高 ...

  2. ASP.NET Redis 开发 [转]

    Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景.Redis纯粹为应用而产生,它是一个高性能的 ...

  3. ASP.NET Redis 开发(转载)

    Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景.Redis纯粹为应用而产生,它是一个高性能的 ...

  4. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  5. ASP.Net Core使用分布式缓存Redis从入门到实战演练

    一.课程介绍 人生苦短,我用.NET Core!缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力.  所以经常要用到且不会频繁改变且被用户共享的 ...

  6. 水果项目第3集-asp.net web api开发入门

    app后台开发,可以用asp.net webservice技术. 也有一种重量级一点的叫WCF,也可以用来做app后台开发. 现在可以用asp.net web api来开发app后台. Asp.net ...

  7. ASP开发入门+实战电子书共50本 —下载目录

    小弟为大家整理50个ASP电子书籍,有入门,也有实战电子书,做成了一个下载目录,欢迎大家下载. 资源名称 资源地址 ASP.NET开发实战1200例_第I卷 http://down.51cto.com ...

  8. 005.Getting started with ASP.NET Core MVC and Visual Studio -- 【VS开发asp.net core mvc 入门】

    Getting started with ASP.NET Core MVC and Visual Studio VS开发asp.net core mvc 入门 2017-3-7 2 分钟阅读时长 本文 ...

  9. 《ASP.NET Core应用开发入门教程》与《ASP.NET Core 应用开发项目实战》正式出版

    “全书之写印,实系初稿.有时公私琐务猬集,每写一句,三搁其笔:有时兴会淋漓,走笔疾书,絮絮不休:有时意趣萧索,执笔木坐,草草而止.每写一段,自助覆阅,辄摇其首,觉有大不妥者,即贴补重书,故剪刀浆糊乃不 ...

随机推荐

  1. opengl:初次接触

    1.概述 OpenGL(Open Graphics Library),开放的图形程序接口,是编程接口的规范,并不是像OpenCV那样是库.GLFW是开源的基于opengl标准的库,并且是跨平台的.其开 ...

  2. List根据某个字段(属性)去重

    有时候自带的list.Distinct()去重并不能满足魔门的要求,比如以下情况 如果testList的Name相同则视为重复,则可以如下实现,比写循环语句简洁多了 testList.Where((x ...

  3. rsync的服务端和客户端搭建

    首先要看看有没有rsync,没有就按装一个rsync 1配置文件 然后创建rsyncd.conf文件,并添加如下内容(文件默认不存在) [root@chensiqi2 backup]# cat /et ...

  4. bzoj1711

    题解: 原点->食物建一个1 食物->牛见一个1 牛->牛'见一个1 牛'->饮料1 饮料->汇点1 代码: #include<cstdio> #includ ...

  5. 随手写的一个检测php连接mysql的小脚本

    最近偶然接触到一点点的php开发,要用到mysql数据库,由于mysql和php版本的关系,php5里面连接函数有mysql_connect(),mysqli_connect()两种,php7中又使用 ...

  6. CMD命令提示符下选中文字即可以复制和SecureCRT一样

    用过 SecureCRT 的都会觉得复制粘贴很方便.只要选中相应文字,会自动复制.然后点鼠标右键就可以粘贴,非常方便. 但是在windows系统下的CMD里面,每次都要点鼠标右键→标记,再选中相应文字 ...

  7. I2S音频总线学习(二)I2S总线协议

    http://blog.csdn.net/ce123_zhouwei/article/details/6919954

  8. windows 10 安装 sql 2005 安装失败

    windows 10 安装 sql 2005 安装失败 网上的方法记录: 安装中无法启动需要先用sp4的补丁文件sqlos.dll,sqlservr.exe 替换D:\Program Files (x ...

  9. 升级到XE10

    下午抽空从XE7升级到XE10,用的是lsuper大侠的Dx10Update1_23.0.21418.4207,用到的控件基本装全乎了. 过程中也碰到点问题,记录下子. 1. cnPack结构匹配线与 ...

  10. C# 根据日期计算星期几

    region 根据年月日计算星期几(Label2.Text=CaculateWeekDay(,,);) /// <summary> /// 根据年月日计算星期几(Label2.Text=C ...