C#链接阿里云KVStore
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的更多相关文章
- C#链接阿里云OCS
一.阿里云OCS简单介绍 阿里云OCS兼容Memcached,因为OCS就相当于Memcached的服务器端,我们代码只是当作客户端,链接上服务器端就行了.阿里云OCS介绍详情见 http://www ...
- 数据库工具链接阿里云MySQL数据库
数据库工具:Toad for MySQL ssh工具:XShell 5 跳板机配置: 配置通道: 源主机:数据库工具链接的地址: 侦听接口:数据库工具侦听接口: 目标主机:数据库阿里云地址: 目标端口 ...
- 使用Xshell链接阿里云服务
1.下载Xshell,进入xshell官网 https://xshell.en.softonic.com/,选择免费版本进行下载,在该页面https://www.netsarang.com/zh/fr ...
- 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: ...
- 本机ubuntu链接阿里云服务器(也是ubuntu)
首先在本机安装ssh工具,并修改配置文件(参考:http://www.cnblogs.com/herd/p/5009067.html) 第一步:ssh 100.121.156.32(即:服务器的ip地 ...
- navicat 链接阿里云服务器数据库报80070007 的错误
navicat用ssh跳转登录mysql连接时报: 80070007: SSH Tunnel: Server does not support diffie-hellman-group1-sha1 f ...
- 阿里云服务器 && 如何window链接到阿里云服务器
现在的时间是:2016年10月11日 1:购买学生机 阿里云手机app上 -> 学生专区 -> 购买: 需要注意的是:如果没有自己需要的系统,比如没有linux操作系统的ecs,那 ...
- 阿里云服务器Centos7.4开放80端口的记录
问题: 阿里云服务器安装的是centos7, 搭建网站安装lnmp1.5后发现访问不了, 不明所以, 在一论坛找到关于80端口未开放的原因. 需求: 开放80端口.于是有了下面第一,二,三部分关于开放 ...
- 语音识别(ASR) 阿里云
做语音识别这块的呢,国内领先的有科大讯飞,BAT这几家公司,鉴于使用科大讯飞的接口需要付费,腾讯云的语音识别申请了几天也没给通过,比较了一下阿里和百度的,个人觉得阿里云的好用一些,这篇博客来讲讲怎么讲 ...
随机推荐
- MongoDB学习笔记——Master/Slave主从复制
Master/Slave主从复制 主从复制MongoDB中比较常用的一种方式,如果要实现主从复制至少应该有两个MongoDB实例,一个作为主节点负责客户端请求,另一个作为从节点负责从主节点映射数据,提 ...
- MySQL用户无法登陆问题
安装完MySQL后,我们通常添加拥有相应权限的普通用户用来访问数据库.在使用普通用户(假设为tom)本地登录数据库的时候,经常会出现无法登录的情况,但是从其他的mysql客户端却可以登录.在本地使用t ...
- Linux下NDK编译FFMPEG包含neon参数
FFMPEG编译成Android库已经有很多案例了,编译优化neon的也很多,以下是我通过实践成功的案例,这里主要讲编译的配置文件,其他设置可结合Linux下使用NDK编译FFMPEG(libstag ...
- Python序列化之json与pickle
1.json介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Progra ...
- x01.Lab.StoreApp: XP 停服,微软变脸
变脸,川剧的一种表演形式,除了哄哄小孩,似乎别无用处.而川剧变脸从业者何其多也,存在时间何其长也.以如此多的从业者,如此长的时间,来进行科研,其成果一定是斐然吧.推而广之,试问天下谁能敌! 微软变脸, ...
- ELK Kafka json to elk
Logstash配置 input { kafka { zk_connect => "127.0.0.1:2181" topic_id => "clus ...
- [转]在NopCommerce中新增一个Domain Model的步骤
本文转自:http://www.cnblogs.com/aneasystone/archive/2012/08/27/2659183.html 在NopCommerce中新增一个Domain Mode ...
- MMORPG大型游戏设计与开发(客户端架构 part6 of vegine)
客户端的变量模块部分主要是将一些常用可变的值集中管理,如窗口的大小,是否开启音乐,音量的大小等等.这些变量通常会应该到客户端的操作,一般来说变量改变的时候会调用一个回调进行处理.下面我们就看看该模块的 ...
- Stanford机器学习笔记-7. Machine Learning System Design
7 Machine Learning System Design Content 7 Machine Learning System Design 7.1 Prioritizing What to W ...
- 解决Apache/PHP无法启动的问题
最近经常被问到Apache无法启动的情况,所以写一篇文章,总结一下Windows下经常遇到的 Apache/PHP 无法启动的情况的解决方法. Apache/PHP 无法启动分两种情况: 1..Apa ...