redis在.net架构中的应用(1)--使用servicestack连接redis(转)

引言:作为少有的.net架构下的大型网站,stackoverflow曾发表了一篇文章,介绍了其技术体系,原文链接http://highscalability.com/blog/2011/3/3/stack-overflow-architecture-update-now-at-95-million-page-vi.html。从文中可以看到,该网站运用了redis作为其缓存层。而新浪微博早就已经大量使用redis。作为一个新兴的nosql数据库,redis既解决了memcached持久化的问题,又在性能上和传统的memcached+mysql不相上下。

1 redis安装与配置

目前redis在windows上的运行还不稳定,一般都是将其部署在linux服务器下,网上可以搜到很多安装教程,本文不再赘述http://www.oschina.net/question/12_18065

2下载servicestack.Redis

目前redis官方版本不支持.net直接进行连接,需要使用一些开源类库。目前最流行的就是ServiceStack.redis,github链接为https://github.com/ServiceStack/ServiceStack.Redis

点击页面右侧的DownLoad.Zip,下载后解压,在build\release\MonoDevelop\ServiceStack.Redis下找到所需要的四个dll

3 利用servicestack连接redis

新建一个VS project,引入以上四个dll,接下来我们就可以利用C#连接redis数据库了,一个最简单的例子:

4 目前servicestack.redis仍然在不断发展和改进中,所以一些方法描述并不是很清晰,所以提供一个已经封装好的类共大家使用,

redis的网络连接方式和传统的rdbms相似,一种是长连接,一种是连接池,此处使用长连接进行连接

强烈建议在使用之前阅读注释

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using ServiceStack.Redis;
  7 namespace TestRedis
  8 {
  9     class RedisHelper:IDisposable
 10     {
 11         /*[email protected] All Rights Reserved
 12          * Author:Mars
 13          * Date:2013.08.27
 14          * QQ:258248340
 15          * servicestack.redis为github中的开源项目
 16          * redis是一个典型的k/v型数据库
 17          * redis共支持五种类型的数据 string,list,hash,set,sortedset
 18          *
 19          * string是最简单的字符串类型
 20          *
 21          * list是字符串列表,其内部是用双向链表实现的,因此在获取/设置数据时可以支持正负索引
 22          * 也可以将其当做堆栈结构使用
 23          *
 24          * hash类型是一种字典结构,也是最接近RDBMS的数据类型,其存储了字段和字段值的映射,但字段值只能是
 25          * 字符串类型,散列类型适合存储对象,建议使用对象类别和ID构成键名,使用字段表示对象属性,字
 26          * 段值存储属性值,例如:car:2 price 500 ,car:2  color black,用redis命令设置散列时,命令格式
 27          * 如下:HSET key field value,即key,字段名,字段值
 28          *
 29          * set是一种集合类型,redis中可以对集合进行交集,并集和互斥运算
 30          *
 31          * sorted set是在集合的基础上为每个元素关联了一个“分数”,我们能够
 32          * 获得分数最高的前N个元素,获得指定分数范围内的元素,元素是不同的,但是"分数"可以是相同的
 33          * set是用散列表和跳跃表实现的,获取数据的速度平均为o(log(N))
 34          *
 35          * 需要注意的是,redis所有数据类型都不支持嵌套
 36          * redis中一般不区分插入和更新操作,只是命令的返回值不同
 37          * 在插入key时,如果不存在,将会自动创建
 38          *
 39          * 在实际生产环境中,由于多线程并发的关系,建议使用连接池,本类只是用于测试简单的数据类型
 40          */
 41
 42         /*
 43          * 以下方法为基本的设置数据和取数据
 44          */
 45         private static RedisClient redisCli = null;
 46         /// <summary>
 47         /// 建立redis长连接
 48         /// </summary>
 49         /// 将此处的IP换为自己的redis实例IP,如果设有密码,第三个参数为密码,string 类型
 50         public static void CreateClient(string hostIP,int port,string keyword)
 51         {
 52             if (redisCli == null)
 53             {
 54                 redisCli = new RedisClient(hostIP, port, keyword);
 55             }
 56
 57         }
 58         public static void CreateClient(string hostIP, int port)
 59         {
 60             if (redisCli == null)
 61             {
 62                 redisCli = new RedisClient(hostIP, port);
 63              }
 64
 65         }
 66         //private static RedisClient redisCli = new RedisClient("192.168.101.165", 6379, "123456");
 67         /// <summary>
 68         /// 获取key,返回string格式
 69         /// </summary>
 70         /// <param name="key"></param>
 71         /// <returns></returns>
 72         public static string getValueString(string key)
 73         {
 74
 75                 string value = redisCli.GetValue(key);
 76                 return value;
 77
 78
 79         }
 80         /// <summary>
 81         /// 获取key,返回byte[]格式
 82         /// </summary>
 83         /// <param name="key"></param>
 84         /// <returns></returns>
 85         public static byte[] getValueByte(string key)
 86         {
 87             byte[] value = redisCli.Get(key);
 88             return value;
 89         }
 90         /// <summary>
 91         /// 获得某个hash型key下的所有字段
 92         /// </summary>
 93         /// <param name="hashId"></param>
 94         /// <returns></returns>
 95         public static List<string> GetHashFields(string hashId)
 96         {
 97             List<string> hashFields = redisCli.GetHashKeys(hashId);
 98             return hashFields;
 99         }
100         /// <summary>
101         /// 获得某个hash型key下的所有值
102         /// </summary>
103         /// <param name="hashId"></param>
104         /// <returns></returns>
105         public static List<string> GetHashValues(string hashId)
106         {
107             List<string> hashValues = redisCli.GetHashKeys(hashId);
108             return hashValues;
109         }
110         /// <summary>
111         /// 获得hash型key某个字段的值
112         /// </summary>
113         /// <param name="key"></param>
114         /// <param name="field"></param>
115         public static string GetHashField(string key, string field)
116         {
117             string value = redisCli.GetValueFromHash(key, field);
118             return value;
119         }
120         /// <summary>
121         /// 设置hash型key某个字段的值
122         /// </summary>
123         /// <param name="key"></param>
124         /// <param name="field"></param>
125         /// <param name="value"></param>
126         public static void SetHashField(string key, string field, string value)
127         {
128             redisCli.SetEntryInHash(key, field, value);
129         }
130         /// <summary>
131         ///使某个字段增加
132         /// </summary>
133         /// <param name="key"></param>
134         /// <param name="field"></param>
135         /// <returns></returns>
136         public static void SetHashIncr(string key, string field, long incre)
137         {
138             redisCli.IncrementValueInHash(key, field, incre);
139
140         }
141         /// <summary>
142         /// 向list类型数据添加成员,向列表底部(右侧)添加
143         /// </summary>
144         /// <param name="Item"></param>
145         /// <param name="list"></param>
146         public static void AddItemToListRight(string list, string item)
147         {
148             redisCli.AddItemToList(list, item);
149         }
150         /// <summary>
151         /// 向list类型数据添加成员,向列表顶部(左侧)添加
152         /// </summary>
153         /// <param name="list"></param>
154         /// <param name="item"></param>
155         public static void AddItemToListLeft(string list, string item)
156         {
157             redisCli.LPush(list, Encoding.Default.GetBytes(item));
158         }
159         /// <summary>
160         /// 从list类型数据读取所有成员
161         /// </summary>
162         public static List<string> GetAllItems(string list)
163         {
164             List<string> listMembers = redisCli.GetAllItemsFromList(list);
165             return listMembers;
166         }
167         /// <summary>
168         /// 从list类型数据指定索引处获取数据,支持正索引和负索引
169         /// </summary>
170         /// <param name="list"></param>
171         /// <returns></returns>
172         public static string GetItemFromList(string list, int index)
173         {
174             string item = redisCli.GetItemFromList(list, index);
175             return item;
176         }
177         /// <summary>
178         /// 向列表底部(右侧)批量添加数据
179         /// </summary>
180         /// <param name="list"></param>
181         /// <param name="values"></param>
182         public static void GetRangeToList(string list, List<string> values)
183         {
184             redisCli.AddRangeToList(list, values);
185         }
186         /// <summary>
187         /// 向集合中添加数据
188         /// </summary>
189         /// <param name="item"></param>
190         /// <param name="set"></param>
191         public static void GetItemToSet(string item, string set)
192         {
193             redisCli.AddItemToSet(item, set);
194         }
195         /// <summary>
196         /// 获得集合中所有数据
197         /// </summary>
198         /// <param name="set"></param>
199         /// <returns></returns>
200         public static HashSet<string> GetAllItemsFromSet(string set)
201         {
202             HashSet<string> items = redisCli.GetAllItemsFromSet(set);
203             return items;
204         }
205         /// <summary>
206         /// 获取fromSet集合和其他集合不同的数据
207         /// </summary>
208         /// <param name="fromSet"></param>
209         /// <param name="toSet"></param>
210         /// <returns></returns>
211         public static HashSet<string> GetSetDiff(string fromSet, params string[] toSet)
212         {
213             HashSet<string> diff = redisCli.GetDifferencesFromSet(fromSet, toSet);
214             return diff;
215         }
216         /// <summary>
217         /// 获得所有集合的并集
218         /// </summary>
219         /// <param name="set"></param>
220         /// <returns></returns>
221         public static HashSet<string> GetSetUnion(params string[] set)
222         {
223             HashSet<string> union = redisCli.GetUnionFromSets(set);
224             return union;
225         }
226         /// <summary>
227         /// 获得所有集合的交集
228         /// </summary>
229         /// <param name="set"></param>
230         /// <returns></returns>
231         public static HashSet<string> GetSetInter(params string[] set)
232         {
233             HashSet<string> inter = redisCli.GetIntersectFromSets(set);
234             return inter;
235         }
236         /// <summary>
237         /// 向有序集合中添加元素
238         /// </summary>
239         /// <param name="set"></param>
240         /// <param name="value"></param>
241         /// <param name="score"></param>
242         public static void AddItemToSortedSet(string set,string value,long score)
243         {
244             redisCli.AddItemToSortedSet(set,value,score);
245         }
246         /// <summary>
247         /// 获得某个值在有序集合中的排名,按分数的降序排列
248         /// </summary>
249         /// <param name="set"></param>
250         /// <param name="value"></param>
251         /// <returns></returns>
252         public static int GetItemIndexInSortedSetDesc(string set, string value)
253         {
254             int index = redisCli.GetItemIndexInSortedSetDesc(set, value);
255             return index;
256         }
257         /// <summary>
258         /// 获得某个值在有序集合中的排名,按分数的升序排列
259         /// </summary>
260         /// <param name="set"></param>
261         /// <param name="value"></param>
262         /// <returns></returns>
263         public static int GetItemIndexInSortedSet(string set, string value)
264         {
265             int index = redisCli.GetItemIndexInSortedSet(set, value);
266             return index;
267         }
268         /// <summary>
269         /// 获得有序集合中某个值得分数
270         /// </summary>
271         /// <param name="set"></param>
272         /// <param name="value"></param>
273         /// <returns></returns>
274         public static double GetItemScoreInSortedSet(string set, string value)
275         {
276             double score = redisCli.GetItemScoreInSortedSet(set, value);
277             return score;
278         }
279         /// <summary>
280         /// 获得有序集合中,某个排名范围的所有值
281         /// </summary>
282         /// <param name="set"></param>
283         /// <param name="beginRank"></param>
284         /// <param name="endRank"></param>
285         /// <returns></returns>
286         public static List<string> GetRangeFromSortedSet(string set,int beginRank, int endRank)
287         {
288             List<string> valueList=redisCli.GetRangeFromSortedSet(set,beginRank,endRank);
289             return valueList;
290         }
291         /// <summary>
292         /// 获得有序集合中,某个分数范围内的所有值,升序
293         /// </summary>
294         /// <param name="set"></param>
295         /// <param name="beginScore"></param>
296         /// <param name="endScore"></param>
297         /// <returns></returns>
298         public static List<string> GetRangeFromSortedSet(string set, double beginScore, double endScore)
299         {
300             List<string> valueList = redisCli.GetRangeFromSortedSetByHighestScore(set, beginScore, endScore);
301             return valueList;
302         }
303         /// <summary>
304         /// 获得有序集合中,某个分数范围内的所有值,降序
305         /// </summary>
306         /// <param name="set"></param>
307         /// <param name="beginScore"></param>
308         /// <param name="endScore"></param>
309         /// <returns></returns>
310         public static List<string> GetRangeFromSortedSetDesc(string set, double beginScore, double endScore)
311         {
312             List<string> vlaueList=redisCli.GetRangeFromSortedSetByLowestScore(set,beginScore,endScore);
313             return vlaueList;
314         }
315         public void Dispose()
316         {
317             redisCli.Dispose();
318         }
319
320     }
321 }

本文就到这里,在接下来,我会跟大家讨论redis中的连接池、锁、线程安全、分布式等机制。

作者:Mars

出处:http://www.cnblogs.com/marsblog/

本文基于署名-非商业性使用 3.0中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 Mars (包含链接)

时间: 2024-08-06 01:06:15

redis在.net架构中的应用(1)--使用servicestack连接redis(转)的相关文章

Redis数据库的初步认识(二)-C/C++连接redis数据库

1用C语言连接数据库,首先要安装c语言的数据库 在目录/redis- 4.0.1/deps下面执行sudo make/make install命令 在执行完之后可能执行ldconfig命令来更新连接符 2连接数据库 redisContext* c=redisConnect("127.0.0.1",6379); 释放连接 redisFree(c); 3对redis进行的操作 reply1=static_cast<redisReply *>(redisCommand(c,&qu

Redis 2.8 架构分析

1  Redis架构分析 1.1   为什么要用nosqlàredis? 1)存储方式的区别: nosql:使用K-V的方式存储数据 例如:mset   id 0001  name  zhangsan age   18 关系型数据库:使用多表结构关联的方式存储数据 例如: Id Name Age 0001 Zhangsan 18 - - - 2)读写方式的区别: nosql:可以把不同类型的数据通过k-v的方式进行快速的读写操作,无关系性.数据结构简单. 关系型数据库:在不同类型的数据下需要进行

Java连接Redis之redis的增删改查

一.新建一个maven工程,工程可以以jar的形式或war都行,然后导入正确的依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs

连接Redis后执行命令错误 MISCONF Redis is configured to save RDB snapshots

今天在redis中执行setrange name 1 chun 命令时报了如下错误提示: (error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the er

39、生鲜电商平台-redis缓存在商品中的设计与架构

说明:Java开源生鲜电商平台-redis缓存在商品中的设计与架构. 1. 各种计数,商品维度计数和用户维度计数 说起电商,肯定离不开商品,而附带商品有各种计数(喜欢数,评论数,鉴定数,浏览数,etc),Redis的命令都是原子性的,你可以轻松地利用INCR,DECR等命令来计数. 商品维度计数(喜欢数,评论数,鉴定数,浏览数,etc)  采用Redis 的类型: Hash. 如果你对redis数据类型不太熟悉,可以参考 http://redis.io/topics/data-types-int

百万PV架构中redis缓存服务群集部署

redis简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hash(哈希类型).这些数据类型都支持push/pop.add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的.在此基础上,redis支持各种不同方式的排序.与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周

架构设计:系统存储(18)——Redis集群方案:高性能

1.概述 通过上一篇文章(<架构设计:系统存储(17)--Redis集群方案:高可用>)的内容,Redis主从复制的基本功能和进行Redis高可用集群监控的Sentinel基本功能基本呈现给了读者.虽然本人并不清楚上一篇根据笔者实际工作经验所撰写的文章有什么重大问题,导致那么多朋友集体点踩而且截止目前又没有任何人愿意为笔者指出这些问题,但是这不会影响笔者继续学习.总结技术知识的热情.从这篇文章开始我们一起来讨论Redis中两种高性能集群方案,并且在讨论过程中将上一篇文章介绍的高可用集群方案结合

高性能网站架构设计之缓存篇(3)- Redis的配置

我们说Redis是一个强大的Key-Value存储系统,在前面我们已遇到了两个问题: 1.redis server 启动后,独占进程,能不能修改为后台服务呢? 2.redis server 服务是单线程的,而我的机器是多核的,能不能在同一台机器上开启多个实例更充分的利用 cpu 资源呢?但6379端口已经被前一个实例绑定,肯定会有冲突,那能不能修改默认端口呢? 答案是肯定的,redis 提供了灵活的配置方式,一种可以通过配置文件来配置,另一种你可以在运行时通过 config set 命令来修改配

redis入门指南书中概要

一.简介 1.redis是一个开源的.高性能的.基于键值对的缓存和存储系统,通过提供多种键值数据类型适应不同场景下的缓存和存储需求,同时redis高级功能能胜任消息队列.任务队列等不同角色. 2.内存存储与持久化:redis中所有数据都存储在内存中.但有问题,程序退出的时候内存中的数据会丢失,不过redis提供对持久化的支持,即将内存中的数据异步写入到硬盘中,不影响提供服务. 3.redis可以为每个键设置生存时间,到期后会自动删除,这一功能让redis成为了出色的缓存系统.作为缓存系统,red