ASP.NET Redis 开发 [转]

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图片(生成二进制)或者序列化的对象。基本操作如下:

[csharp] view plaincopy

  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(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和反序列化

[csharp] view plaincopy

  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内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构

[csharp] view plaincopy

  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实现的,添加,删除和查找,对集合我们可以取并集,交集,差集.

[csharp] view plaincopy

  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数据结构,

[csharp] view plaincopy

  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/1c0ChL5m

时间: 2024-12-29 23:53:38

ASP.NET Redis 开发 [转]的相关文章

ASP.NET Redis 开发 入门

ASP.NET Redis 开发 文件并发(日志处理)--队列--Redis+Log4Net Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景.Redis纯粹为应用而产生,它是一个高性能的key-value数据库,并且提供了多种语言的API 性能测试结果表示SET操作每秒钟可达110000次,GET操作每秒81000次(当然不同的服务器配置性能不同). redis目前提供五种数据类型:str

ASP.NET Redis 开发

Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景.Redis纯粹为应用而产生,它是一个高性能的key-value数据库,并且提供了多种语言的API 性能测试结果表示SET操作每秒钟可达110000次,GET操作每秒81000次(当然不同的服务器配置性能不同). redis目前提供五种数据类型:string(字符串),list(链表), Hash(哈希),set(集合)及zset(sorted

ASP.Net MVC开发基础学习笔记(3):Razor视图引擎、控制器与路由机制学习

首页 头条 文章 频道                         设计频道 Web前端 Python开发 Java技术 Android应用 iOS应用 资源 小组 相亲 频道 首页 头条 文章 小组 相亲 资源 设计 前端 Python Java 安卓 iOS 登录 注册 首页 最新文章 经典回顾 开发 Web前端 Python Android iOS Java C/C++ PHP .NET Ruby Go 设计 UI设计 网页设计 交互设计 用户体验 设计教程 设计职场 极客 IT技术

ASP.NET程序开发范例宝典

在整理资料时发现一些非常有用的资料源码尤其是初学者,大部分是平时用到的知识点,可以参考其实现方法,分享给大家学习,但请不要用于商业用途. 如果对你有用请多多推荐给其他人分享. 点击对应章节标题下载本章节下所有源代码. 目录: 第2章 HTML开发与实践 15 2.1 框架的使用 16 实例009 使用FrameSet框架布局聊天室 16 实例010 使用IFrame框架布局企业管理系统 17 2.2 滚屏的实现 18 实例011 滚动显示博客公告 18 实例012 滚屏效果并实现超级链接 20

Asp.Net MVC4开发一:概要

之前为写Asp.Net MVC4而写了Linq应用系列: Linq技术一:Linq to SQL和Devart Linq to SQL Model Linq技术二:Linq to XML及xml增删改查的不同实现方式 Linq技术三:Linq to Object 和生成数据表的扩展方法 Linq技术四:动态Linq技术 -- Linq.Expressions 现在开始写Asp.Net MVC4的系列应用, 主要方面包括: 1. Entity Framework在Asp.Net MVC4中的应用.

ASP.NET Core开发-后台任务利器Hangfire使用

ASP.NET Core开发系列之后台任务利器Hangfire 使用. Hangfire 是一款强大的.NET开源后台任务利器,无需Windows服务/任务计划程序. 可以使用于ASP.NET 应用也可以使用于控制台.Hangfire 只需简单几句代码即可创建新的不同种类的任务. 目前 Hangfire 已经支持.NET Core ,现在就给大家讲解下在ASP.NET Core 里的使用. Hangfire GitHub:https://github.com/HangfireIO/Hangfir

ASP.NET Core开发-读取配置文件Configuration

ASP.NET Core 是如何读取配置文件,今天我们来学习. ASP.NET Core的配置系统已经和之前版本的ASP.NET有所不同了,之前是依赖于System.Configuration和XML配置文件web.config. 新的配置系统支持多种格式的配置文件. 下面我们来以json 格式的配置文件正式开始学习. 我们新建一个ASP.NET Core Web 应用程序,选择无身份验证. 读取配置文件 在项目目录下有个 appsettings.json ,我们先来操作这个文件. 在appse

asp.net 分布式应用开发

Net Framework推出的许多新技术为上述任务的实现提供了相对简单的解决方案.其中,基于SOAP的Web Service在处理分布式应用时具有比传统的DCOM/CORBA明显的优点,结合基于Web的ASP.NET页面开发技术和SQL Server数据存储技术(或Xml文档),在.Net下开发N层应用程序也不再困难. 一.分布式处理概述 分布式处理是将应用程序逻辑分布到2台或者更多台计算机上,在物理上或逻辑上分离的单元中.这一概念并不是新生事物,在大型工程已经得到广泛使用.只不过,Inter

.NET基础 (21)ASP NET应用开发

ASP.NET中的WebForm相关的内容其实有点儿过时了,但在很多的老项目中还是WebForm的,这些都是遗留问题,新上的项目基本上都用MVC了,在微软最新的 ASP.NET 的版本中已经默认使用MVC了.参考ASP.NET 5简介 ASP NET应用开发基础1 请解释ASP NET以什么形式运行2 常见的HTTP Code有哪些3 GET请求和POST请求有何区别4 介绍ASP NET的页面生存周期 控件和页面1 什么是静态页面,什么是动态页面2 请简述ViewState的功能和实现机制3