Redis入门学习
一、软件安装
Redis下载地址:https://github.com/MSOpenTech/redis/releases
因为官方并不支持windows系统,需要从微软的GitHub上下载。
解压缩后文件夹内容如图所示(版本3.2.100):
最开始会用到的文件有redis-server.exe、redis-cli.exe以及一个配置文件redis.windows.conf。
1)启动redis服务,运行cmd.exe
进入到redis文件夹
cd desttop/redis
启动redis-server.exe 并使用配置文件,出现如下图所示就是启动成功了。
redis-server.exe redis.windows.conf
2)启动客户端,再打开一个cmd.exe
进入到文件夹后启动redis-cli.exe
redis-cli.exe
国际惯例,ping helloworld ,解锁熟练掌握redis的成就。
3)为什么默认使用6379端口
Redis作者antirez同学在twitter上说将在下一篇博文(http://oldblog.antirez.com/post/redis-as-LRU-cache.html)中向大家解释为什么他选择6379作为默认端口号。而现在这篇博文出炉,在解释了Redis的LRU机制之后,如期向大家解释了采用6379作为默认端口的原因。6379在是手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字。
二、基本用法
redis是以kev-value形式进行数据存储的,value有字符串、哈希表、列表、集合、有序集合等。
一些命令的使用,可以参考http://doc.redisfans.com/学习。
配置文件的使用,redis.windows-service.conf(以windows服务运行时修改),
1.密码修改
# requirepass foobared //去掉注释#,将foobared替换为你自己的密码
2.文件命名修改
dbfilename dump.rdb // xxxx.rdb
三、C#使用Redis
1)使用到的第三方dll:
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" /> <package id="StackExchange.Redis" version="1.2.6" targetFramework="net45" />
2)搜集到的RedisHelper方法,增加了批量操作
1 /// <summary> 2 /// Redis操作 3 /// </summary> 4 public class RedisHelper 5 { 6 /// <summary> 7 /// 连接redis库的Number 8 /// </summary> 9 private int DbNum { set; get; } 10 private readonly ConnectionMultiplexer _conn; 11 /// <summary> 12 /// 自定义键前缀 13 /// </summary> 14 public string CustomKey; 15 16 #region 构造函数 17 18 public RedisHelper(int dbNum = 0) 19 : this(dbNum, null) 20 { 21 } 22 23 public RedisHelper(int dbNum, string readWriteHosts) 24 { 25 DbNum = dbNum; 26 _conn = 27 string.IsNullOrWhiteSpace(readWriteHosts) ? 28 RedisConnectionHelp.Instance : 29 RedisConnectionHelp.GetConnectionMultiplexer(readWriteHosts); 30 } 31 32 #endregion 构造函数 33 34 #region String 35 36 #region 同步方法 37 38 /// <summary> 39 /// 保存单个key value 40 /// </summary> 41 /// <param name="key">Redis Key</param> 42 /// <param name="value">保存的值</param> 43 /// <param name="expiry">过期时间</param> 44 /// <returns></returns> 45 public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 46 { 47 key = AddSysCustomKey(key); 48 return Do(db => db.StringSet(key, value, expiry)); 49 } 50 51 /// <summary> 52 /// 保存多个key value 53 /// </summary> 54 /// <param name="keyValues">键值对</param> 55 /// <returns></returns> 56 public bool StringSet(List<KeyValuePair<RedisKey, RedisValue>> keyValues) 57 { 58 List<KeyValuePair<RedisKey, RedisValue>> newkeyValues = 59 keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList(); 60 return Do(db => db.StringSet(newkeyValues.ToArray())); 61 } 62 63 /// <summary> 64 /// 保存一个对象 65 /// </summary> 66 /// <typeparam name="T"></typeparam> 67 /// <param name="key"></param> 68 /// <param name="obj"></param> 69 /// <param name="expiry"></param> 70 /// <returns></returns> 71 public bool StringSet<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 72 { 73 key = AddSysCustomKey(key); 74 string json = ConvertJson(obj); 75 return Do(db => db.StringSet(key, json, expiry)); 76 } 77 78 /// <summary> 79 /// 获取单个key的值 80 /// </summary> 81 /// <param name="key">Redis Key</param> 82 /// <returns></returns> 83 public byte[] StringGet(string key) 84 { 85 key = AddSysCustomKey(key); 86 return Do(db => db.StringGet(key)); 87 } 88 89 /// <summary> 90 /// 获取多个Key 91 /// </summary> 92 /// <param name="listKey">Redis Key集合</param> 93 /// <returns></returns> 94 public RedisValue[] StringGet(List<string> listKey) 95 { 96 List<string> newKeys = listKey.Select(AddSysCustomKey).ToList(); 97 return Do(db => db.StringGet(ConvertRedisKeys(newKeys))); 98 } 99 100 /// <summary> 101 /// 获取一个key的对象 102 /// </summary> 103 /// <typeparam name="T"></typeparam> 104 /// <param name="key"></param> 105 /// <returns></returns> 106 public T StringGet<T>(string key) 107 { 108 key = AddSysCustomKey(key); 109 return Do(db => ConvertObj<T>(db.StringGet(key))); 110 } 111 112 public object StringGetObj(string key) 113 { 114 key = AddSysCustomKey(key); 115 var database = _conn.GetDatabase(DbNum); 116 return database.StringGet(key); 117 } 118 119 public static object GetObjFromBytes(byte[] buffer) 120 { 121 using (System.IO.MemoryStream stream = new System.IO.MemoryStream(buffer)) 122 { 123 stream.Position = 0; 124 System.Runtime.Serialization.IFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 125 Object reobj = bf.Deserialize(stream); 126 return reobj; 127 } 128 } 129 130 /// <summary> 131 /// 为数字增长val 132 /// </summary> 133 /// <param name="key"></param> 134 /// <param name="val">可以为负</param> 135 /// <returns>增长后的值</returns> 136 public double StringIncrement(string key, double val = 1) 137 { 138 key = AddSysCustomKey(key); 139 return Do(db => db.StringIncrement(key, val)); 140 } 141 142 /// <summary> 143 /// 为数字减少val 144 /// </summary> 145 /// <param name="key"></param> 146 /// <param name="val">可以为负</param> 147 /// <returns>减少后的值</returns> 148 public double StringDecrement(string key, double val = 1) 149 { 150 key = AddSysCustomKey(key); 151 return Do(db => db.StringDecrement(key, val)); 152 } 153 154 #endregion 同步方法 155 156 #region 异步方法 157 158 /// <summary> 159 /// 保存单个key value 160 /// </summary> 161 /// <param name="key">Redis Key</param> 162 /// <param name="value">保存的值</param> 163 /// <param name="expiry">过期时间</param> 164 /// <returns></returns> 165 public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?)) 166 { 167 key = AddSysCustomKey(key); 168 return await Do(db => db.StringSetAsync(key, value, expiry)); 169 } 170 171 /// <summary> 172 /// 保存多个key value 173 /// </summary> 174 /// <param name="keyValues">键值对</param> 175 /// <returns></returns> 176 public async Task<bool> StringSetAsync(List<KeyValuePair<RedisKey, RedisValue>> keyValues) 177 { 178 List<KeyValuePair<RedisKey, RedisValue>> newkeyValues = 179 keyValues.Select(p => new KeyValuePair<RedisKey, RedisValue>(AddSysCustomKey(p.Key), p.Value)).ToList(); 180 return await Do(db => db.StringSetAsync(newkeyValues.ToArray())); 181 } 182 183 /// <summary> 184 /// 保存一个对象 185 /// </summary> 186 /// <typeparam name="T"></typeparam> 187 /// <param name="key"></param> 188 /// <param name="obj"></param> 189 /// <param name="expiry"></param> 190 /// <returns></returns> 191 public async Task<bool> StringSetAsync<T>(string key, T obj, TimeSpan? expiry = default(TimeSpan?)) 192 { 193 key = AddSysCustomKey(key); 194 string json = ConvertJson(obj); 195 return await Do(db => db.StringSetAsync(key, json, expiry)); 196 } 197 198 /// <summary> 199 /// 获取单个key的值 200 /// </summary> 201 /// <param name="key">Redis Key</param> 202 /// <returns></returns> 203 public async Task<string> StringGetAsync(string key) 204 { 205 key = AddSysCustomKey(key); 206 return await Do(db => db.StringGetAsync(key)); 207 } 208 209 /// <summary> 210 /// 获取多个Key 211 /// </summary> 212 /// <param name="listKey">Redis Key集合</param> 213 /// <returns></returns> 214 public async Task<RedisValue[]> StringGetAsync(List<string> listKey) 215 { 216 List<string> newKeys = listKey.Select(AddSysCustomKey).ToList(); 217 return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys))); 218 } 219 220 /// <summary> 221 /// 获取一个key的对象 222 /// </summary> 223 /// <typeparam name="T"></typeparam> 224 /// <param name="key"></param> 225 /// <returns></returns> 226 public async Task<T> StringGetAsync<T>(string key) 227 { 228 key = AddSysCustomKey(key); 229 string result = await Do(db => db.StringGetAsync(key)); 230 return ConvertObj<T>(result); 231 } 232 233 /// <summary> 234 /// 为数字增长val 235 /// </summary> 236 /// <param name="key"></param> 237 /// <param name="val">可以为负</param> 238 /// <returns>增长后的值</returns> 239 public async Task<double> StringIncrementAsync(string key, double val = 1) 240 { 241 key = AddSysCustomKey(key); 242 return await Do(db => db.StringIncrementAsync(key, val)); 243 } 244 245 /// <summary> 246 /// 为数字减少val 247 /// </summary> 248 /// <param name="key"></param> 249 /// <param name="val">可以为负</param> 250 /// <returns>减少后的值</returns> 251 public async Task<double> StringDecrementAsync(string key, double val = 1) 252 { 253 key = AddSysCustomKey(key); 254 return await Do(db => db.StringDecrementAsync(key, val)); 255 } 256 257 #endregion 异步方法 258 259 #endregion String 260 261 #region Hash 262 263 #region 同步方法 264 265 /// <summary> 266 /// 判断某个数据是否已经被缓存 267 /// </summary> 268 /// <param name="key"></param> 269 /// <param name="dataKey"></param> 270 /// <returns></returns> 271 public bool HashExists(string key, string dataKey) 272 { 273 key = AddSysCustomKey(key); 274 return Do(db => db.HashExists(key, dataKey)); 275 } 276 277 /// <summary> 278 /// 存储数据到hash表 279 /// </summary> 280 /// <typeparam name="T"></typeparam> 281 /// <param name="key"></param> 282 /// <param name="dataKey"></param> 283 /// <param name="t"></param> 284 /// <returns></returns> 285 public bool HashSet<T>(string key, string dataKey, T t) 286 { 287 key = AddSysCustomKey(key); 288 return Do(db => 289 { 290 string json = ConvertJson(t); 291 return db.HashSet(key, dataKey, json); 292 }); 293 } 294 295 /// <summary> 296 /// 移除hash中的某值 297 /// </summary> 298 /// <param name="key"></param> 299 /// <param name="dataKey"></param> 300 /// <returns></returns> 301 public bool HashDelete(string key, string dataKey) 302 { 303 key = AddSysCustomKey(key); 304 return Do(db => db.HashDelete(key, dataKey)); 305 } 306 307 /// <summary> 308 /// 移除hash中的多个值 309 /// </summary> 310 /// <param name="key"></param> 311 /// <param name="dataKeys"></param> 312 /// <returns></returns> 313 public long HashDelete(string key, List<RedisValue> dataKeys) 314 { 315 key = AddSysCustomKey(key); 316 //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"}; 317 return Do(db => db.HashDelete(key, dataKeys.ToArray())); 318 } 319 320 /// <summary> 321 /// 从hash表获取数据 322 /// </summary> 323 /// <typeparam name="T"></typeparam> 324 /// <param name="key"></param> 325 /// <param name="dataKey"></param> 326 /// <returns></returns> 327 public T HashGet<T>(string key, string dataKey) 328 { 329 key = AddSysCustomKey(key); 330 return Do(db => 331 { 332 string value = db.HashGet(key, dataKey); 333 return ConvertObj<T>(value); 334 }); 335 } 336 337 /// <summary> 338 /// 为数字增长val 339 /// </summary> 340 /// <param name="key"></param> 341 /// <param name="dataKey"></param> 342 /// <param name="val">可以为负</param> 343 /// <returns>增长后的值</returns> 344 public double HashIncrement(string key, string dataKey, double val = 1) 345 { 346 key = AddSysCustomKey(key); 347 return Do(db => db.HashIncrement(key, dataKey, val)); 348 } 349 350 /// <summary> 351 /// 为数字减少val 352 /// </summary> 353 /// <param name="key"></param> 354 /// <param name="dataKey"></param> 355 /// <param name="val">可以为负</param> 356 /// <returns>减少后的值</returns> 357 public double HashDecrement(string key, string dataKey, double val = 1) 358 { 359 key = AddSysCustomKey(key); 360 return Do(db => db.HashDecrement(key, dataKey, val)); 361 } 362 363 /// <summary> 364 /// 获取hashkey所有Redis key 365 /// </summary> 366 /// <typeparam name="T"></typeparam> 367 /// <param name="key"></param> 368 /// <returns></returns> 369 public List<T> HashKeys<T>(string key) 370 { 371 key = AddSysCustomKey(key); 372 return Do(db => 373 { 374 RedisValue[] values = db.HashKeys(key); 375 return ConvetList<T>(values); 376 }); 377 } 378 379 #endregion 同步方法 380 381 #region 异步方法 382 383 /// <summary> 384 /// 判断某个数据是否已经被缓存 385 /// </summary> 386 /// <param name="key"></param> 387 /// <param name="dataKey"></param> 388 /// <returns></returns> 389 public async Task<bool> HashExistsAsync(string key, string dataKey) 390 { 391 key = AddSysCustomKey(key); 392 return await Do(db => db.HashExistsAsync(key, dataKey)); 393 } 394 395 /// <summary> 396 /// 存储数据到hash表 397 /// </summary> 398 /// <typeparam name="T"></typeparam> 399 /// <param name="key"></param> 400 /// <param name="dataKey"></param> 401 /// <param name="t"></param> 402 /// <returns></returns> 403 public async Task<bool> HashSetAsync<T>(string key, string dataKey, T t) 404 { 405 key = AddSysCustomKey(key); 406 return await Do(db => 407 { 408 string json = ConvertJson(t); 409 return db.HashSetAsync(key, dataKey, json); 410 }); 411 } 412 413 /// <summary> 414 /// 移除hash中的某值 415 /// </summary> 416 /// <param name="key"></param> 417 /// <param name="dataKey"></param> 418 /// <returns></returns> 419 public async Task<bool> HashDeleteAsync(string key, string dataKey) 420 { 421 key = AddSysCustomKey(key); 422 return await Do(db => db.HashDeleteAsync(key, dataKey)); 423 } 424 425 /// <summary> 426 /// 移除hash中的多个值 427 /// </summary> 428 /// <param name="key"></param> 429 /// <param name="dataKeys"></param> 430 /// <returns></returns> 431 public async Task<long> HashDeleteAsync(string key, List<RedisValue> dataKeys) 432 { 433 key = AddSysCustomKey(key); 434 //List<RedisValue> dataKeys1 = new List<RedisValue>() {"1","2"}; 435 return await Do(db => db.HashDeleteAsync(key, dataKeys.ToArray())); 436 } 437 438 /// <summary> 439 /// 从hash表获取数据 440 /// </summary> 441 /// <typeparam name="T"></typeparam> 442 /// <param name="key"></param> 443 /// <param name="dataKey"></param> 444 /// <returns></returns> 445 public async Task<T> HashGeAsync<T>(string key, string dataKey) 446 { 447 key = AddSysCustomKey(key); 448 string value = await Do(db => db.HashGetAsync(key, dataKey)); 449 return ConvertObj<T>(value); 450 } 451 452 /// <summary> 453 /// 为数字增长val 454 /// </summary> 455 /// <param name="key"></param> 456 /// <param name="dataKey"></param> 457 /// <param name="val">可以为负</param> 458 /// <returns>增长后的值</returns> 459 public async Task<double> HashIncrementAsync(string key, string dataKey, double val = 1) 460 { 461 key = AddSysCustomKey(key); 462 return await Do(db => db.HashIncrementAsync(key, dataKey, val)); 463 } 464 465 /// <summary> 466 /// 为数字减少val 467 /// </summary> 468 /// <param name="key"></param> 469 /// <param name="dataKey"></param> 470 /// <param name="val">可以为负</param> 471 /// <returns>减少后的值</returns> 472 public async Task<double> HashDecrementAsync(string key, string dataKey, double val = 1) 473 { 474 key = AddSysCustomKey(key); 475 return await Do(db => db.HashDecrementAsync(key, dataKey, val)); 476 } 477 478 /// <summary> 479 /// 获取hashkey所有Redis key 480 /// </summary> 481 /// <typeparam name="T"></typeparam> 482 /// <param name="key"></param> 483 /// <returns></returns> 484 public async Task<List<T>> HashKeysAsync<T>(string key) 485 { 486 key = AddSysCustomKey(key); 487 RedisValue[] values = await Do(db => db.HashKeysAsync(key)); 488 return ConvetList<T>(values); 489 } 490 491 #endregion 异步方法 492 493 #endregion Hash 494 495 #region List 496 497 #region 同步方法 498 499 /// <summary> 500 /// 移除指定ListId的内部List的值 501 /// </summary> 502 /// <param name="key"></param> 503 /// <param name="value"></param> 504 public void ListRemove<T>(string key, T value) 505 { 506 key = AddSysCustomKey(key); 507 Do(db => db.ListRemove(key, ConvertJson(value))); 508 } 509 510 /// <summary> 511 /// 获取指定key的List 512 /// </summary> 513 /// <param name="key"></param> 514 /// <returns></returns> 515 public List<T> ListRange<T>(string key) 516 { 517 key = AddSysCustomKey(key); 518 return Do(redis => 519 { 520 var values = redis.ListRange(key); 521 return ConvetList<T>(values); 522 }); 523 } 524 525 /// <summary> 526 /// 入队 527 /// </summary> 528 /// <param name="key"></param> 529 /// <param name="value"></param> 530 public void ListRightPush<T>(string key, T value) 531 { 532 key = AddSysCustomKey(key); 533 Do(db => db.ListRightPush(key, ConvertJson(value))); 534 } 535 536 /// <summary> 537 /// 出队 538 /// </summary> 539 /// <typeparam name="T"></typeparam> 540 /// <param name="key"></param> 541 /// <returns></returns> 542 public T ListRightPop<T>(string key) 543 { 544 key = AddSysCustomKey(key); 545 return Do(db => 546 { 547 var value = db.ListRightPop(key); 548 return ConvertObj<T>(value); 549 }); 550 } 551 552 /// <summary> 553 /// 入栈 554 /// </summary> 555 /// <typeparam name="T"></typeparam> 556 /// <param name="key"></param> 557 /// <param name="value"></param> 558 public void ListLeftPush<T>(string key, T value) 559 { 560 key = AddSysCustomKey(key); 561 Do(db => db.ListLeftPush(key, ConvertJson(value))); 562 } 563 564 /// <summary> 565 /// 出栈 566 /// </summary> 567 /// <typeparam name="T"></typeparam> 568 /// <param name="key"></param> 569 /// <returns></returns> 570 public T ListLeftPop<T>(string key) 571 { 572 key = AddSysCustomKey(key); 573 return Do(db => 574 { 575 var value = db.ListLeftPop(key); 576 return ConvertObj<T>(value); 577 }); 578 } 579 580 /// <summary> 581 /// 获取集合中的数量 582 /// </summary> 583 /// <param name="key"></param> 584 /// <returns></returns> 585 public long ListLength(string key) 586 { 587 key = AddSysCustomKey(key); 588 return Do(redis => redis.ListLength(key)); 589 } 590 591 #endregion 同步方法 592 593 #region 异步方法 594 595 /// <summary> 596 /// 移除指定ListId的内部List的值 597 /// </summary> 598 /// <param name="key"></param> 599 /// <param name="value"></param> 600 public async Task<long> ListRemoveAsync<T>(string key, T value) 601 { 602 key = AddSysCustomKey(key); 603 return await Do(db => db.ListRemoveAsync(key, ConvertJson(value))); 604 } 605 606 /// <summary> 607 /// 获取指定key的List 608 /// </summary> 609 /// <param name="key"></param> 610 /// <returns></returns> 611 public async Task<List<T>> ListRangeAsync<T>(string key) 612 { 613 key = AddSysCustomKey(key); 614 var values = await Do(redis => redis.ListRangeAsync(key)); 615 return ConvetList<T>(values); 616 } 617 618 /// <summary> 619 /// 入队 620 /// </summary> 621 /// <param name="key"></param> 622 /// <param name="value"></param> 623 public async Task<long> ListRightPushAsync<T>(string key, T value) 624 { 625 key = AddSysCustomKey(key); 626 return await Do(db => db.ListRightPushAsync(key, ConvertJson(value))); 627 } 628 629 /// <summary> 630 /// 出队 631 /// </summary> 632 /// <typeparam name="T"></typeparam> 633 /// <param name="key"></param> 634 /// <returns></returns> 635 public async Task<T> ListRightPopAsync<T>(string key) 636 { 637 key = AddSysCustomKey(key); 638 var value = await Do(db => db.ListRightPopAsync(key)); 639 return ConvertObj<T>(value); 640 } 641 642 /// <summary> 643 /// 入栈 644 /// </summary> 645 /// <typeparam name="T"></typeparam> 646 /// <param name="key"></param> 647 /// <param name="value"></param> 648 public async Task<long> ListLeftPushAsync<T>(string key, T value) 649 { 650 key = AddSysCustomKey(key); 651 return await Do(db => db.ListLeftPushAsync(key, ConvertJson(value))); 652 } 653 654 /// <summary> 655 /// 出栈 656 /// </summary> 657 /// <typeparam name="T"></typeparam> 658 /// <param name="key"></param> 659 /// <returns></returns> 660 public async Task<T> ListLeftPopAsync<T>(string key) 661 { 662 key = AddSysCustomKey(key); 663 var value = await Do(db => db.ListLeftPopAsync(key)); 664 return ConvertObj<T>(value); 665 } 666 667 /// <summary> 668 /// 获取集合中的数量 669 /// </summary> 670 /// <param name="key"></param> 671 /// <returns></returns> 672 public async Task<long> ListLengthAsync(string key) 673 { 674 key = AddSysCustomKey(key); 675 return await Do(redis => redis.ListLengthAsync(key)); 676 } 677 678 #endregion 异步方法 679 680 #endregion List 681 682 #region SortedSet 有序集合 683 684 #region 同步方法 685 686 /// <summary> 687 /// 添加 688 /// </summary> 689 /// <param name="key"></param> 690 /// <param name="value"></param> 691 /// <param name="score"></param> 692 public bool SortedSetAdd<T>(string key, T value, double score) 693 { 694 key = AddSysCustomKey(key); 695 return Do(redis => redis.SortedSetAdd(key, ConvertJson<T>(value), score)); 696 } 697 698 /// <summary> 699 /// 删除 700 /// </summary> 701 /// <param name="key"></param> 702 /// <param name="value"></param> 703 public bool SortedSetRemove<T>(string key, T value) 704 { 705 key = AddSysCustomKey(key); 706 return Do(redis => redis.SortedSetRemove(key, ConvertJson(value))); 707 } 708 709 /// <summary> 710 /// 获取全部 711 /// </summary> 712 /// <param name="key"></param> 713 /// <returns></returns> 714 public List<T> SortedSetRangeByRank<T>(string key) 715 { 716 key = AddSysCustomKey(key); 717 return Do(redis => 718 { 719 var values = redis.SortedSetRangeByRank(key); 720 return ConvetList<T>(values); 721 }); 722 } 723 724 /// <summary> 725 /// 获取集合中的数量 726 /// </summary> 727 /// <param name="key"></param> 728 /// <returns></returns> 729 public long SortedSetLength(string key) 730 { 731 key = AddSysCustomKey(key); 732 return Do(redis => redis.SortedSetLength(key)); 733 } 734 735 #endregion 同步方法 736 737 #region 异步方法 738 739 /// <summary> 740 /// 添加 741 /// </summary> 742 /// <param name="key"></param> 743 /// <param name="value"></param> 744 /// <param name="score"></param> 745 public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score) 746 { 747 key = AddSysCustomKey(key); 748 return await Do(redis => redis.SortedSetAddAsync(key, ConvertJson<T>(value), score)); 749 } 750 751 /// <summary> 752 /// 删除 753 /// </summary> 754 /// <param name="key"></param> 755 /// <param name="value"></param> 756 public async Task<bool> SortedSetRemoveAsync<T>(string key, T value) 757 { 758 key = AddSysCustomKey(key); 759 return await Do(redis => redis.SortedSetRemoveAsync(key, ConvertJson(value))); 760 } 761 762 /// <summary> 763 /// 获取全部 764 /// </summary> 765 /// <param name="key"></param> 766 /// <returns></returns> 767 public async Task<List<T>> SortedSetRangeByRankAsync<T>(string key) 768 { 769 key = AddSysCustomKey(key); 770 var values = await Do(redis => redis.SortedSetRangeByRankAsync(key)); 771 return ConvetList<T>(values); 772 } 773 774 /// <summary> 775 /// 获取集合中的数量 776 /// </summary> 777 /// <param name="key"></param> 778 /// <returns></returns> 779 public async Task<long> SortedSetLengthAsync(string key) 780 { 781 key = AddSysCustomKey(key); 782 return await Do(redis => redis.SortedSetLengthAsync(key)); 783 } 784 785 #endregion 异步方法 786 787 #endregion SortedSet 有序集合 788 789 #region key 790 791 /// <summary> 792 /// 删除单个key 793 /// </summary> 794 /// <param name="key">redis key</param> 795 /// <returns>是否删除成功</returns> 796 public bool KeyDelete(string key) 797 { 798 key = AddSysCustomKey(key); 799 return Do(db => db.KeyDelete(key)); 800 } 801 802 /// <summary> 803 /// 删除多个key 804 /// </summary> 805 /// <param name="keys">rediskey</param> 806 /// <returns>成功删除的个数</returns> 807 public long KeyDelete(List<string> keys) 808 { 809 List<string> newKeys = keys.Select(AddSysCustomKey).ToList(); 810 return Do(db => db.KeyDelete(ConvertRedisKeys(newKeys))); 811 } 812 813 /// <summary> 814 /// 判断key是否存储 815 /// </summary> 816 /// <param name="key">redis key</param> 817 /// <returns></returns> 818 public bool KeyExists(string key) 819 { 820 key = AddSysCustomKey(key); 821 return Do(db => db.KeyExists(key)); 822 } 823 824 /// <summary> 825 /// 重新命名key 826 /// </summary> 827 /// <param name="key">就的redis key</param> 828 /// <param name="newKey">新的redis key</param> 829 /// <returns></returns> 830 public bool KeyRename(string key, string newKey) 831 { 832 key = AddSysCustomKey(key); 833 return Do(db => db.KeyRename(key, newKey)); 834 } 835 836 /// <summary> 837 /// 设置Key的时间 838 /// </summary> 839 /// <param name="key">redis key</param> 840 /// <param name="expiry"></param> 841 /// <returns></returns> 842 public bool KeyExpire(string key, TimeSpan? expiry = default(TimeSpan?)) 843 { 844 key = AddSysCustomKey(key); 845 return Do(db => db.KeyExpire(key, expiry)); 846 } 847 848 #endregion key 849 850 #region 发布订阅 851 852 /// <summary> 853 /// Redis发布订阅 订阅 854 /// </summary> 855 /// <param name="subChannel"></param> 856 /// <param name="handler"></param> 857 public void Subscribe(string subChannel, Action<RedisChannel, RedisValue> handler = null) 858 { 859 ISubscriber sub = _conn.GetSubscriber(); 860 sub.Subscribe(subChannel, (channel, message) => 861 { 862 if (handler == null) 863 { 864 Console.WriteLine(subChannel + " 订阅收到消息:" + message); 865 } 866 else 867 { 868 handler(channel, message); 869 } 870 }); 871 } 872 873 /// <summary> 874 /// Redis发布订阅 发布 875 /// </summary> 876 /// <typeparam name="T"></typeparam> 877 /// <param name="channel"></param> 878 /// <param name="msg"></param> 879 /// <returns></returns> 880 public long Publish<T>(string channel, T msg) 881 { 882 ISubscriber sub = _conn.GetSubscriber(); 883 return sub.Publish(channel, ConvertJson(msg)); 884 } 885 886 /// <summary> 887 /// Redis发布订阅 取消订阅 888 /// </summary> 889 /// <param name="channel"></param> 890 public void Unsubscribe(string channel) 891 { 892 ISubscriber sub = _conn.GetSubscriber(); 893 sub.Unsubscribe(channel); 894 } 895 896 /// <summary> 897 /// Redis发布订阅 取消全部订阅 898 /// </summary> 899 public void UnsubscribeAll() 900 { 901 ISubscriber sub = _conn.GetSubscriber(); 902 sub.UnsubscribeAll(); 903 } 904 905 #endregion 发布订阅 906 907 #region 其他 908 909 public ITransaction CreateTransaction() 910 { 911 return GetDatabase().CreateTransaction(); 912 } 913 914 public IDatabase GetDatabase() 915 { 916 return _conn.GetDatabase(DbNum); 917 } 918 919 public IServer GetServer(string hostAndPort) 920 { 921 return _conn.GetServer(hostAndPort); 922 } 923 924 /// <summary> 925 /// 设置前缀 926 /// </summary> 927 /// <param name="customKey"></param> 928 public void SetSysCustomKey(string customKey) 929 { 930 CustomKey = customKey; 931 } 932 933 #endregion 其他 934 935 #region 辅助方法 936 937 private string AddSysCustomKey(string oldKey) 938 { 939 var prefixKey = CustomKey ?? RedisConnectionHelp.SysCustomKey; 940 return prefixKey + oldKey; 941 } 942 943 private T Do<T>(Func<IDatabase, T> func) 944 { 945 var database = _conn.GetDatabase(DbNum); 946 return func(database); 947 } 948 949 public string ConvertJson<T>(T value) 950 { 951 string result = value is string ? value.ToString() : JsonConvert.SerializeObject(value); 952 return result; 953 } 954 955 public T ConvertObj<T>(RedisValue value) 956 { 957 return JsonConvert.DeserializeObject<T>(value); 958 } 959 960 private List<T> ConvetList<T>(RedisValue[] values) 961 { 962 List<T> result = new List<T>(); 963 foreach (var item in values) 964 { 965 var model = ConvertObj<T>(item); 966 result.Add(model); 967 } 968 return result; 969 } 970 971 private RedisKey[] ConvertRedisKeys(List<string> redisKeys) 972 { 973 return redisKeys.Select(redisKey => (RedisKey)redisKey).ToArray(); 974 } 975 976 #endregion 辅助方法 977 978 #region 批量操作 979 980 #region 批量写Key-Value 981 /// <summary> 982 /// 批量写Key-Value 983 /// </summary> 984 /// <param name="keyValues"></param> 985 /// <returns></returns> 986 public bool StringWriteBatch(List<KeyValuePair<RedisKey, RedisValue>> keyValues) 987 { 988 bool result = false; 989 try 990 { 991 var db = _conn.GetDatabase(); 992 var batch = db.CreateBatch(); 993 foreach (var item in keyValues) 994 { 995 batch.StringSetAsync(item.Key, item.Value); 996 } 997 batch.Execute(); 998 result = true; 999 } 1000 catch 1001 { 1002 } 1003 return result; 1004 } 1005 #endregion 1006 1007 #region 批量读Key-Value 1008 /// <summary> 1009 /// 批量读Key-Value 1010 /// </summary> 1011 /// <typeparam name="T"></typeparam> 1012 /// <param name="lstKey"></param> 1013 /// <returns></returns> 1014 public List<T> StringReadBatch<T>(List<RedisKey> lstKey) 1015 { 1016 List<Task<RedisValue>> valueList = new List<Task<RedisValue>>(); 1017 List<T> lstResult = new List<T>(); 1018 try 1019 { 1020 var db = _conn.GetDatabase(); 1021 var batch = db.CreateBatch(); 1022 foreach (var item in lstKey) 1023 { 1024 Task<RedisValue> value = batch.StringGetAsync(item); 1025 valueList.Add(value); 1026 } 1027 batch.Execute(); 1028 1029 foreach (var item in valueList) 1030 { 1031 T t = ConvertObj<T>(item.Result); 1032 lstResult.Add(t); 1033 } 1034 } 1035 catch 1036 { 1037 } 1038 return lstResult; 1039 } 1040 1041 /// <summary> 1042 /// 批量读操作,返回DataSe集合 1043 /// </summary> 1044 /// <param name="lstKey"></param> 1045 /// <returns></returns> 1046 public DataSet StringReadBatch(List<RedisKey> lstKey) 1047 { 1048 if (lstKey == null || lstKey.Count < 1) return null; 1049 List<Task<RedisValue>> valueList = new List<Task<RedisValue>>(); 1050 DataSet ds = new DataSet(); 1051 try 1052 { 1053 var db = _conn.GetDatabase(); 1054 var batch = db.CreateBatch(); 1055 foreach (var item in lstKey) 1056 { 1057 Task<RedisValue> value = batch.StringGetAsync(item); 1058 valueList.Add(value); 1059 } 1060 batch.Execute(); 1061 1062 foreach (var item in valueList) 1063 { 1064 DataTable t = ConvertObj<DataTable>(item.Result); 1065 ds.Tables.Add(t); 1066 } 1067 } 1068 catch 1069 { 1070 } 1071 return ds; 1072 } 1073 #endregion 1074 1075 #region 批量写Hash 1076 /// <summary> 1077 /// 批量写Hash 1078 /// </summary> 1079 /// <param name="keyValues"></param> 1080 /// <returns></returns> 1081 public bool HashWriteBatch(List<KeyValuePair<RedisKey, HashEntry[]>> keyValues) 1082 { 1083 bool result = false; 1084 try 1085 { 1086 var db = _conn.GetDatabase(); 1087 var batch = db.CreateBatch(); 1088 foreach (var item in keyValues) 1089 { 1090 batch.HashSetAsync(item.Key, item.Value); 1091 } 1092 batch.Execute(); 1093 result = true; 1094 } 1095 catch 1096 { 1097 } 1098 return result; 1099 } 1100 #endregion 1101 1102 #region 批量读Hash 1103 /// <summary> 1104 /// 批量读Hash 1105 /// </summary> 1106 ///<param name="keyFields">hash键和field</param> 1107 /// <returns></returns> 1108 public List<T> HashReadBatch<T>(List<KeyValuePair<RedisKey, RedisValue[]>> keyFields) 1109 { 1110 List<Task<RedisValue[]>> valueList = new List<Task<RedisValue[]>>(); 1111 List<T> lstResult = new List<T>(); 1112 try 1113 { 1114 var db = _conn.GetDatabase(); 1115 var batch = db.CreateBatch(); 1116 foreach (var item in keyFields) 1117 { 1118 Task<RedisValue[]> value = batch.HashGetAsync(item.Key, item.Value); 1119 valueList.Add(value); 1120 } 1121 batch.Execute(); 1122 1123 foreach (var item in valueList) 1124 { 1125 if (item.Result == null) continue; 1126 foreach (var redisValue in item.Result) 1127 { 1128 T t = ConvertObj<T>(redisValue); 1129 lstResult.Add(t); 1130 } 1131 } 1132 } 1133 catch 1134 { 1135 } 1136 return lstResult; 1137 } 1138 #endregion 1139 1140 #endregion
3)单例模式
1 /// <summary> 2 /// ConnectionMultiplexer对象管理帮助类 3 /// </summary> 4 public static class RedisConnectionHelp 5 { 6 //系统自定义Key前缀 7 public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? ""; 8 9 //"127.0.0.1:6379,allowadmin=true 10 private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString; 11 12 private static readonly object Locker = new object(); 13 private static ConnectionMultiplexer _instance; 14 private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>(); 15 16 /// <summary> 17 /// 单例获取 18 /// </summary> 19 public static ConnectionMultiplexer Instance 20 { 21 get 22 { 23 if (_instance == null) 24 { 25 lock (Locker) 26 { 27 if (_instance == null || !_instance.IsConnected) 28 { 29 _instance = GetManager(); 30 } 31 } 32 } 33 return _instance; 34 } 35 } 36 37 /// <summary> 38 /// 缓存获取 39 /// </summary> 40 /// <param name="connectionString"></param> 41 /// <returns></returns> 42 public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString) 43 { 44 if (!ConnectionCache.ContainsKey(connectionString)) 45 { 46 ConnectionCache[connectionString] = GetManager(connectionString); 47 } 48 return ConnectionCache[connectionString]; 49 } 50 51 private static ConnectionMultiplexer GetManager(string connectionString = null) 52 { 53 connectionString = connectionString ?? RedisConnectionString; 54 var connect = ConnectionMultiplexer.Connect(connectionString); 55 56 //注册如下事件 57 connect.ConnectionFailed += MuxerConnectionFailed; 58 connect.ConnectionRestored += MuxerConnectionRestored; 59 connect.ErrorMessage += MuxerErrorMessage; 60 connect.ConfigurationChanged += MuxerConfigurationChanged; 61 connect.HashSlotMoved += MuxerHashSlotMoved; 62 connect.InternalError += MuxerInternalError; 63 64 return connect; 65 } 66 67 #region 事件 68 69 /// <summary> 70 /// 配置更改时 71 /// </summary> 72 /// <param name="sender"></param> 73 /// <param name="e"></param> 74 private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e) 75 { 76 Console.WriteLine("Configuration changed: " + e.EndPoint); 77 } 78 79 /// <summary> 80 /// 发生错误时 81 /// </summary> 82 /// <param name="sender"></param> 83 /// <param name="e"></param> 84 private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e) 85 { 86 Console.WriteLine("ErrorMessage: " + e.Message); 87 } 88 89 /// <summary> 90 /// 重新建立连接之前的错误 91 /// </summary> 92 /// <param name="sender"></param> 93 /// <param name="e"></param> 94 private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e) 95 { 96 Console.WriteLine("ConnectionRestored: " + e.EndPoint); 97 } 98 99 /// <summary> 100 /// 连接失败 , 如果重新连接成功你将不会收到这个通知 101 /// </summary> 102 /// <param name="sender"></param> 103 /// <param name="e"></param> 104 private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e) 105 { 106 Console.WriteLine("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message))); 107 } 108 109 /// <summary> 110 /// 更改集群 111 /// </summary> 112 /// <param name="sender"></param> 113 /// <param name="e"></param> 114 private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e) 115 { 116 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint); 117 } 118 119 /// <summary> 120 /// redis类库错误 121 /// </summary> 122 /// <param name="sender"></param> 123 /// <param name="e"></param> 124 private static void MuxerInternalError(object sender, InternalErrorEventArgs e) 125 { 126 Console.WriteLine("InternalError:Message" + e.Exception.Message); 127 } 128 129 #endregion 事件 130 }
4)app.config中增加redis连接字符串
<connectionStrings> <add name="RedisExchangeHosts" connectionString="127.0.0.1:6379,password=xxxxxx"/> </connectionStrings>