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. Apache的Order Allow,Deny 详解

    Allow和Deny可以用于apache的conf文件或者.htaccess文件中(配合Directory, Location, Files等),用来控制目录和文件的访问授权. 所以,最常用的是: O ...

  2. 揭开GrowingIO无埋点的神秘面纱

    揭开GrowingIO无埋点的神秘面纱   早在研究用户行为分析的时候,就发现国内的GrowingIO在宣传无埋点技术,最近正好抽出时间来研究一下所谓的无埋点到底是什么样的. 我分六部分来分析一下无埋 ...

  3. 【转】ETL增量抽取——通过时间戳方式实现

    这个实验主要思想是在创建数据库表的时候, 通过增加一个额外的字段,也就是时间戳字段, 例如在同步表 tt1 和表 tt2 的时候, 通过检查那个表是最新更新的,那个表就作为新表,而另外的表最为旧表被新 ...

  4. history

    history用来显示最近执行的命令,系统中将当前的允许的最大保存的历史命令条数保存在环境变量HISTSIZE中,缺省选项时表示显示最多HISTSIZE个命令,可以指定显示最近的n条命令 $histo ...

  5. Struts2开发环境搭建,及一个简单登录功能实例

    首先是搭建Struts2环境. 第一步 下载Struts2去Struts官网 http://struts.apache.org/ 下载Struts2组件.截至目前,struts2最新版本为2.3.1. ...

  6. SQLITE配置环境变量

      SQLITE配置环境变量和Java的配置其实是一样的,不过好像每个人配的时候不完全相同, 有的机器可以,另外一些机器同样的方法却行不通,总之思路是一样的多试几种,总有合适的参数 下面是我在配置时截 ...

  7. 利用增量备份恢复因归档丢失造成的DG gap

    故障现象:data guard归档出现gap,悲剧的是丢失的归档在主库上被rman备份时删除了,丢失的归档大约有20几个,数据库大小约2T,如果重建DG将非常耗时间,因此决定利用增量备份的方式恢复DG ...

  8. @Value取不到值引出的spring的2种配置文件applicationContext.xml和xxx-servlet.xml

    项目中经常会用到配置文件,定义成properties的形式比较常见,为了方便使用一般在spring配置文件中做如下配置: <context:property-placeholder ignore ...

  9. GitHub注册流程(中英对比)

    GitHub注册流程(中英对比) 注明:为方便完成注册,将以中英文网页截图对应展示. 1. 注册邮箱:        点击GitHub官网进行邮箱注册. 2. 制定个人计划:        页面跳转至 ...

  10. C++11 之 override

    1  公有继承 派生类公有继承自 (public inheritance) 基类,继承包含两部分:一是函数的 "接口" (interface),二是函数的 "实现&quo ...