KVStore的简单介绍

  阿里云KVStore兼容Redis。因为KVStore就相当于Redis的服务器端,我们代码只是当作客户端,链接上服务器端就行了,阿里云的KVStore详情文档见,https://docs.aliyun.com/#/pub/kvstore/key-value-store/kvstore-introduction

C#客户端链接OCS

  1.阿里云文档上介绍的是用ServiceStack去链接KVStore。那我们项目中就用nuget去下载ServiceStack包。nuget搜索ServiceStack,搜索到的结果如下图,安装图中标识的就可以了。这个应该是最新的V4版本,当提醒你需要用商业版的时候,可以去还原之前的V3版本,具体还原方法见,https://github.com/ServiceStackV3/ServiceStackV3

  nuget搜索结果如下:

  2.安装好以后,写链接和调用kvstore的代码。其中_setting.AccessId, _setting.AccessKey, _setting.HostAddress,分别是KVStore的实例ID,链接密码和链接地址。

  1 using ServiceStack.Redis;
2 //using ServiceStack.Text;
3 using ServiceStack.Common;
4 using System;
5 using System.Collections.Generic;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Web.Script.Serialization;
10 using Zupo.Core.Caching;
11 using System.Text.RegularExpressions;
12
13
14 namespace KVStore
15 {
16 public class KVStoreService
17 {
18
19 IKVStoreSetting _setting;
20 private IRedisClient redisClient;
21 private bool linkServer = true;
22
23 public KVStoreService(IKVStoreSetting setting)
24 {
25 try
26 {
27 this._setting = setting;
28 //连接池模式
29 //string[] testReadWriteHosts = new[] {
30 //string.Format("redis://:{0}:{1}@{2}:6379",_setting.AccessId,_setting.AccessKey,_setting.HostAddress)/*redis://:实例id:密码@访问地址:端口*/
31 //};
32 //RedisClientManagerConfig RedisConfig = new RedisClientManagerConfig();
33 //RedisConfig.AutoStart = true;
34 //RedisConfig.MaxReadPoolSize = 60;
35 //RedisConfig.MaxWritePoolSize = 60;
36 ////RedisConfig.VerifyMasterConnections = false;//需要设置
37 ////PooledRedisClientManager redisPoolManager = new PooledRedisClientManager(10/*连接池个数*/, 10/*连接池超时时间*/, testReadWriteHosts);
38 //PooledRedisClientManager redisPoolManager = new PooledRedisClientManager(10/*连接池个数*/, 10/*连接池超时时间*/, testReadWriteHosts);
39 //redisClient = redisPoolManager.GetClient();//获取连接
40 ////RedisNativeClient redisNativeClient = (RedisNativeClient)redisClient;
41 ////redisNativeClient.Client = null;//KVStore不支持client setname所以这里需要显示的把client对象置为null
42 //var dbSize = redisClient.DbSize;
43
44 //单链接模式
45 //string host = _setting.HostAddress;/*访问host地址*/
46 //string password = string.Format("{0}:{1}", _setting.AccessId, _setting.AccessKey);/*实例id:密码*/
47 //redisClient = new RedisClient(host, 6379, password);
48 //var dbSize = redisClient.DbSize;
49
50 RedisClientManagerConfig RedisConfig = new RedisClientManagerConfig();
51 RedisConfig.AutoStart = true;
52 RedisConfig.MaxReadPoolSize = 60;
53 RedisConfig.MaxWritePoolSize = 60;
54 RedisConfig.DefaultDb = 1; //默认第一个db
55
56 PooledRedisClientManager prcm = new PooledRedisClientManager(new List<string>() { string.Format("{0}:{1}@{2}:6379", _setting.AccessId, _setting.AccessKey, _setting.HostAddress) },
57 new List<string>() { string.Format("{0}:{1}@{2}:6379", _setting.AccessId, _setting.AccessKey, _setting.HostAddress) }, RedisConfig);
58 redisClient = prcm.GetClient();
59 }
60 catch (Exception)
61 {
62 linkServer = false;
63 }
64 }
65
66 /// <summary>
67 /// 是否处于链接状态
68 /// </summary>
69 protected bool LinkServer
70 {
71 get
72 {
73 return linkServer;
74 }
75 }
76
77 /// <summary>
78 /// 根据传入的key-value添加一条记录,当key已存在返回false
79 /// </summary>
80 /// <typeparam name="T"></typeparam>
81 /// <param name="key"></param>
82 /// <param name="value"></param>
83 /// <returns></returns>
84 protected bool Add<T>(string key, T value)
85 {
86 return redisClient.Add<T>(key, value);
87 }
88
89 /// <summary>
90 /// 根据传入的key-value添加一条记录,当key已存在返回false
91 /// </summary>
92 /// <typeparam name="T"></typeparam>
93 /// <param name="key"></param>
94 /// <param name="value"></param>
95 /// <param name="expiresIn">TimeSpan</param>
96 /// <returns></returns>
97 protected bool AddExpires<T>(string key, T value, TimeSpan expiresIn)
98 {
99 return redisClient.Add<T>(key, value, expiresIn);
100 }
101
102 /// <summary>
103 /// 获取
104 /// </summary>
105 /// <typeparam name="T"></typeparam>
106 /// <param name="key"></param>
107 /// <returns></returns>
108 protected T Get<T>(string key)
109 {
110 try
111 {
112 return redisClient.Get<T>(key);
113 }
114 catch(Exception ex)
115 {
116 throw ex;
117 }
118 }
119
120 protected List<T> GetList<T>(string key)
121 {
122 return redisClient.Get<List<T>>(key);
123 }
124
125 /// <summary>
126 /// 根据传入的多个key获取多条记录的值
127 /// </summary>
128 /// <typeparam name="T"></typeparam>
129 /// <param name="keys"></param>
130 /// <returns></returns>
131 protected IDictionary<string, T> GetAll<T>(IEnumerable<string> keys)
132 {
133 return redisClient.GetAll<T>(keys);
134 }
135
136 /// <summary>
137 /// 根据传入的key移除一条记录
138 /// </summary>
139 /// <param name="key"></param>
140 /// <returns></returns>
141 public void Remove(string key)
142 {
143 redisClient.Remove(key);
144 }
145
146 /// <summary>
147 /// 根据传入的多个key移除多条记录
148 /// </summary>
149 /// <param name="keys"></param>
150 protected void RemoveAll(IEnumerable<string> keys)
151 {
152 redisClient.RemoveAll(keys);
153 }
154
155 /// <summary>
156 /// Removes items by pattern
157 /// </summary>
158 /// <param name="pattern">pattern</param>
159 public void RemoveByPattern(string pattern)
160 {
161 var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
162 var keysToRemove = new List<String>();
163
164 var allkeys = redisClient.GetAllKeys();
165 foreach (var key in allkeys)
166 if (regex.IsMatch(key))
167 keysToRemove.Add(key);
168
169 foreach (string key in keysToRemove)
170 {
171 Remove(key);
172 }
173 }
174
175
176 /// <summary>
177 /// 清空kv-store缓存
178 /// </summary>
179 /// <returns></returns>
180 public void Clear()
181 {
182 var allkeys = redisClient.GetAllKeys();
183 redisClient.RemoveAll(allkeys);
184 }
185
186 /// <summary>
187 /// 根据传入的key覆盖一条记录的值,当key不存在不会添加
188 /// </summary>
189 /// <typeparam name="T"></typeparam>
190 /// <param name="key"></param>
191 /// <param name="value"></param>
192 /// <returns></returns>
193 protected bool Replace<T>(string key, T value)
194 {
195 return redisClient.Replace<T>(key, value);
196 }
197
198 /// <summary>
199 /// 根据传入的key修改一条记录的值,当key不存在则添加
200 /// </summary>
201 /// <typeparam name="T"></typeparam>
202 /// <param name="key"></param>
203 /// <param name="value"></param>
204 /// <returns></returns>
205 protected bool Set<T>(string key, T value)
206 {
207 try
208 {
209 return redisClient.Set<T>(key, value);
210 }
211 catch(Exception ex)
212 {
213 throw ex;
214 }
215 }
216
217 protected bool Set<T>(string key, List<T> value)
218 {
219 try
220 {
221 JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
222 //执行序列化
223 string objectStr = jsonSerializer.Serialize(value);
224
225 return redisClient.Set(key, value);
226 }
227 catch (Exception ex)
228 {
229 throw ex;
230 }
231 }
232
233 /// <summary>
234 /// 根据传入的key修改一条记录的值,当key不存在则添加
235 /// </summary>
236 /// <typeparam name="T"></typeparam>
237 /// <param name="key"></param>
238 /// <param name="value"></param>
239 /// <param name="expiresIn">TimeSpan</param>
240 /// <returns></returns>
241 protected bool SetExpires<T>(string key, T value, TimeSpan expiresIn)
242 {
243 return redisClient.Set<T>(key, value, expiresIn);
244 }
245
246 /// <summary>
247 /// 根据传入的多个key覆盖多条记录
248 /// </summary>
249 /// <typeparam name="T"></typeparam>
250 /// <param name="values"></param>
251 protected void SetAll<T>(IDictionary<string, T> values)
252 {
253 redisClient.SetAll<T>(values);
254 }
255
256 /// <summary>
257 /// 判断Key在本数据库内是否已被使用(包括各种类型、内置集合等等)
258 /// </summary>
259 /// <param name="key"></param>
260 /// <returns></returns>
261 public bool Contains(string key)
262 {
263 return redisClient.ContainsKey(key);
264 }
265
266 /// <summary>
267 /// 获取所有的Keys集合
268 /// </summary>
269 /// <returns></returns>
270 protected List<string> GetAllKeys()
271 {
272 return redisClient.GetAllKeys();
273 }
274
275 /// <summary>
276 /// 重命名一个Key,值不变
277 /// </summary>
278 /// <param name="fromName"></param>
279 /// <param name="toName"></param>
280 protected void RenameKey(string fromName, string toName)
281 {
282 redisClient.RenameKey(fromName, toName);
283 }
284
285 /// <summary>
286 /// 清除本数据库的所有数据
287 /// </summary>
288 protected void FlushDb()
289 {
290 redisClient.FlushAll();
291 }
292
293 /// <summary>
294 /// 根据Key获取当前存储的值是什么类型:
295 /// </summary>
296 /// <param name="key">None = 0 String = 1 List = 2 Set = 3 SortedSet = 4 Hash = 5</param>
297 /// <returns></returns>
298 protected RedisKeyType GetEntryType(string key)
299 {
300 return redisClient.GetEntryType(key);
301 }
302
303 /// <summary>
304 /// 添加一个项到内部的List<T>
305 /// </summary>
306 /// <param name="listId"></param>
307 /// <param name="value"></param>
308 protected void AddItemToList(string listId, string value)
309 {
310 redisClient.AddItemToList(listId, value);
311 }
312
313 /// <summary>
314 /// 添加一个项到内部的HashSet<T>
315 /// </summary>
316 /// <param name="setId"></param>
317 /// <param name="item"></param>
318 protected void AddItemToSet(string setId, string item)
319 {
320 redisClient.AddItemToSet(setId, item);
321 }
322
323 /// <summary>
324 /// 一次过将参数中的List<T>中的多个值添加入内部的List<T>
325 /// </summary>
326 /// <param name="listId"></param>
327 /// <param name="values"></param>
328 protected void AddRangeToList(string listId, List<string> values)
329 {
330 redisClient.AddRangeToList(listId, values);
331 }
332
333 /// <summary>
334 /// 一次过将参数中的HashSet<T>中的多个值添加入内部的HashSet<T>
335 /// </summary>
336 /// <param name="setId"></param>
337 /// <param name="items"></param>
338 protected void AddRangeToSet(string setId, List<string> items)
339 {
340 redisClient.AddRangeToSet(setId, items);
341 }
342
343 /// <summary>
344 /// 获取指定ListId的内部List<T>的所有值
345 /// </summary>
346 /// <param name="listId"></param>
347 /// <returns></returns>
348 protected List<string> GetAllItemsFromList(string listId)
349 {
350 return redisClient.GetAllItemsFromList(listId);
351 }
352
353 /// <summary>
354 /// 获取指定SetId的内部HashSet<T>的所有值
355 /// </summary>
356 /// <param name="setId"></param>
357 /// <returns></returns>
358 protected HashSet<string> GetAllItemsFromSet(string setId)
359 {
360 return redisClient.GetAllItemsFromSet(setId);
361 }
362
363 /// <summary>
364 /// 根据ListId和下标获取一项
365 /// </summary>
366 /// <param name="listId"></param>
367 /// <param name="listIndex"></param>
368 /// <returns></returns>
369 protected string GetItemFromList(string listId, int listIndex)
370 {
371 return redisClient.GetItemFromList(listId, listIndex);
372 }
373 }
374 }

      

使用注意点

  这个可以直接上传list和set等类型的数据,它也支持泛型方法,但因为网络传输肯定是要先序列化的,跟OCS一样的问题,所以我项目用的是EF,所以得先去忽略不需要序列化的字段和属性等,加上[IgnoreDataMember],不然有死循环就会造成内存溢出。

C#链接阿里云KVStore的更多相关文章

  1. C#链接阿里云OCS

    一.阿里云OCS简单介绍 阿里云OCS兼容Memcached,因为OCS就相当于Memcached的服务器端,我们代码只是当作客户端,链接上服务器端就行了.阿里云OCS介绍详情见 http://www ...

  2. 数据库工具链接阿里云MySQL数据库

    数据库工具:Toad for MySQL ssh工具:XShell 5 跳板机配置: 配置通道: 源主机:数据库工具链接的地址: 侦听接口:数据库工具侦听接口: 目标主机:数据库阿里云地址: 目标端口 ...

  3. 使用Xshell链接阿里云服务

    1.下载Xshell,进入xshell官网 https://xshell.en.softonic.com/,选择免费版本进行下载,在该页面https://www.netsarang.com/zh/fr ...

  4. navicat链接阿里云mysql报80070007: SSH Tunnel: Server does not support diffie-hellman-group1-sha1 for keyexchange

      http://www.jianshu.com/p/200572ed066c navicat 链接数据库 使用navicat 的ssh通道连接数据库回遇到权限问题 错误代码如下: 80070007: ...

  5. 本机ubuntu链接阿里云服务器(也是ubuntu)

    首先在本机安装ssh工具,并修改配置文件(参考:http://www.cnblogs.com/herd/p/5009067.html) 第一步:ssh 100.121.156.32(即:服务器的ip地 ...

  6. navicat 链接阿里云服务器数据库报80070007 的错误

    navicat用ssh跳转登录mysql连接时报: 80070007: SSH Tunnel: Server does not support diffie-hellman-group1-sha1 f ...

  7. 阿里云服务器 && 如何window链接到阿里云服务器

    现在的时间是:2016年10月11日 1:购买学生机 阿里云手机app上  ->  学生专区  ->  购买: 需要注意的是:如果没有自己需要的系统,比如没有linux操作系统的ecs,那 ...

  8. 阿里云服务器Centos7.4开放80端口的记录

    问题: 阿里云服务器安装的是centos7, 搭建网站安装lnmp1.5后发现访问不了, 不明所以, 在一论坛找到关于80端口未开放的原因. 需求: 开放80端口.于是有了下面第一,二,三部分关于开放 ...

  9. 语音识别(ASR) 阿里云

    做语音识别这块的呢,国内领先的有科大讯飞,BAT这几家公司,鉴于使用科大讯飞的接口需要付费,腾讯云的语音识别申请了几天也没给通过,比较了一下阿里和百度的,个人觉得阿里云的好用一些,这篇博客来讲讲怎么讲 ...

随机推荐

  1. maven 安装alipay-sdk包到本地及远程仓库

    安装到本地:mvn install:install-file -DgroupId=com.alipay -DartifactId=sdk-Java -Dversion=*** -Dpackaging= ...

  2. 简单阐述下Ajax以get方式请求的步骤 初学,不对的话,跟我说下,谢谢!

    首先, 在GET提交中"=,&"等字符与请求字符串的关键字相混淆.所以: 第一步,先对get提交过来的数据进行编码. 第二步,实例化ajax对象. 第三步,创建对服务器的连 ...

  3. Java api 入门教程 之 JAVA的StringBuffer类

    StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存 ...

  4. Linux信号

    信号本质上就是一个软件中断,它既可以作为两个进程间的通信的方式, 更重要的是, 信号可以终止一个正常程序的执行, 通常被用于处理意外情况 ,* 信号是异步的, 也就是进程并不知道信号何时会到达 $ki ...

  5. 虚拟机centos6.5 --安装jdk

    1.首先卸载默认安装的openjdk,如下 rpm -qa | grep java #查看当前是否已经安装了跟java有关的包 yum -y remove java #卸载 rpm -qa |grep ...

  6. 移动windows live writer文章的保存路径

    windows live writer强制安装在C盘,文章也是强制保存在我的文档中.那么我们想办法来改变保存的路径,防止重装系统的时候忘记保存C盘的东西. 网上找到的参考:http://www.dit ...

  7. XBOX ONE游戏开发之DEBUG配置(三)

    如何DEBUG 首先打开ADK命令提示窗口 输入命令 xbconnect {XBOX主机的IP} * XBOX主机的IP 在XBOX主机的开发者设置中可以看到,会有一个主机IP和一个工具IP 然后打开 ...

  8. 用ccproxy + stunnel做个加密代理

    https://www.stunnel.org/downloads.html ccproxy + stunnel做个加密http代理和socks5代理 目前国内用户无法访问某些国外网站,如http:/ ...

  9. poj2632 Crashing Robots

    Crashing Robots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9859   Accepted: 4209 D ...

  10. avalon.js路由

    之前自己写了一个AJAX加载页面的方法:有时候一个页面里面会分区域加载不同的东西(div,html),但是IE的回退按钮,就失去任何意义了: 这两天研究了一下avalon.js的路由: 需要准备: 1 ...