在分布式缓存的应用中,会遇到多个客户端同时争用的问题。这个时候,需要用到分布式锁,得到锁的客户端才有操作权限

下面通过一个简单例子介绍:
这里引用的是Memcached.ClientLibrary.dll
  1. //引用
  2. using Memcached.ClientLibrary;
  3. namespace Memcache.AddLock
  4. {
  5. public class MemcacheHelper
  6. {
  7. //实例化Client
  8. public MemcachedClient MClient;
  9.  
  10. public MemcacheHelper()
  11. {
  12. //参数设置
  13. string SockIOPoolName = "demo";
  14. string[] MemcacheServiceList = { "127.0.0.1:11211" };
  15.  
  16. //设置连接池
  17. SockIOPool SPool = SockIOPool.GetInstance(SockIOPoolName);
  18. SPool.SetServers(MemcacheServiceList);
  19. SPool.Initialize();
  20.  
  21. MClient = new MemcachedClient();
  22. MClient.PoolName = SockIOPoolName;
  23. //是否启用压缩数据:如果启用了压缩,数据压缩长于门槛的数据将被储存在压缩的形式
  24. MClient.EnableCompression = false;
  25. ////压缩设置,超过指定大小的都压缩
  26. //MClient.CompressionThreshold = 1024 * 1024;
  27. }
  28.  
  29. /// <summary>
  30. /// 根据key存储对象
  31. /// </summary>
  32. /// <param name="key"></param>
  33. /// <param name="value"></param>
  34. /// <returns></returns>
  35. public bool Set(string key, object value)
  36. {
  37. var result = MClient.Set(key, value);
  38. return result;
  39. }
  40.  
  41. /// <summary>
  42. /// 根据key存储对象,并且设置过期时间
  43. /// </summary>
  44. /// <param name="key"></param>
  45. /// <param name="value"></param>
  46. /// <param name="timeOut"></param>
  47. /// <returns></returns>
  48. public bool Set(string key, object value, DateTime timeOut)
  49. {
  50. var result = MClient.Set(key, value, timeOut);
  51. return result;
  52. }
  53.  
  54. /// <summary>
  55. /// 根据key获取对应的对象
  56. /// </summary>
  57. /// <param name="key"></param>
  58. /// <returns></returns>
  59. public object Get(string key)
  60. {
  61. var result = MClient.Get(key);
  62. return result;
  63. }
  64.  
  65. /// <summary>
  66. /// 替换对应key的value
  67. /// </summary>
  68. /// <param name="key"></param>
  69. /// <param name="value"></param>
  70. /// <returns></returns>
  71. public bool Replace(string key, object value)
  72. {
  73. var result = MClient.Replace(key, value);
  74. return result;
  75. }
  76.  
  77. /// <summary>
  78. /// 删除对应key
  79. /// </summary>
  80. /// <param name="key"></param>
  81. /// <returns></returns>
  82. public bool Delete(string key)
  83. {
  84. return MClient.Delete(key);
  85. }
  86.  
  87. /// <summary>
  88. /// 删除对应key,并设置从内存中移除的时间点
  89. /// </summary>
  90. /// <param name="key"></param>
  91. /// <param name="timeOut"></param>
  92. /// <returns></returns>
  93. public bool Delete(string key, DateTime timeOut)
  94. {
  95. return MClient.Delete(key, timeOut);
  96. }
  97.  
  98. /// <summary>
  99. /// 判断key是否存在,存在返回true,不存在返回false
  100. /// </summary>
  101. /// <param name="key"></param>
  102. /// <returns></returns>
  103. public bool KeyExists(string key)
  104. {
  105. return MClient.KeyExists(key);
  106. }
  107.  
  108. /// <summary>
  109. /// Memcache分布式锁
  110. /// </summary>
  111. /// <param name="key"></param>
  112. /// <param name="value"></param>
  113. /// <returns>当key存在返回false,当key不存在返回true</returns>
  114. public bool Add(string key, object value)
  115. {
  116. return MClient.Add(key, value);
  117. }
  118.  
  119. /// <summary>
  120. /// Memcache分布式锁,并且设置过期时间
  121. /// Memcached分布式锁可以使用 Add 命令,该命令只有KEY不存在时,才进行添加,否则不会处理。Memcached 所有命令都是原子性的,并发下add 同一个KEY,只会一个会成功。
  122. /// 利用这个原理,可以先定义一个锁 LockKEY,Add 成功的认为是得到锁。并且设置[过期超时] 时间,保证宕机后,也不会死锁。
  123. /// 在完成具体操作后,判断锁 LockKEY 是否已超时。如果超时则不删除锁,如果不超时则 Delete 删除锁。
  124. /// </summary>
  125. /// <param name="key"></param>
  126. /// <param name="value"></param>
  127. /// <param name="timeOut"></param>
  128. /// <returns>当key存在返回false,当key不存在返回true</returns>
  129. public bool Add(string key, object value, DateTime timeOut)
  130. {
  131. return MClient.Add(key, value, timeOut);
  132. }
  133. }
  134. }

控制台程序:

  1. //引用
  2. using Memcached.ClientLibrary;
  3. namespace Memcache.AddLock
  4. {
  5. /// <summary>
  6. /// Memcache分布式锁简单实例
  7. /// </summary>
  8. public class Program
  9. {
  10. //创建一个公共类
  11. public static MemcacheHelper memcache;
  12.  
  13. public static void Main(string[] args)
  14. {
  15. memcache = new MemcacheHelper();
  16. Console.WriteLine("线程开始前,输出" + memcache.Get("demoKey"));
  17. var result = memcache.Delete("demoKey");
  18. Console.WriteLine("线程开始前,输出" + memcache.Get("demoKey") + ",删除对应key返回:" + result);
  19. Console.WriteLine("线程开始前,输出" + memcache.Delete("LockKey"));
  20. memcache.Set("demoKey", "0");
  21. //定义三个线程
  22. Thread myThread1 = new Thread(new ParameterizedThreadStart(AddVal));
  23. Thread myThread2 = new Thread(new ParameterizedThreadStart(AddVal));
  24. Thread myThread3 = new Thread(AddVal);
  25. myThread1.Start("1");
  26. myThread2.Start("2");
  27. myThread3.Start();
  28. Console.WriteLine("等待两个线程结束");
  29. Console.ReadKey();
  30. }
  31.  
  32. public static void AddVal(object num)
  33. {
  34. for (int i = 0; i < 500; i++)
  35. {
  36. //int result = int.Parse(memcache.Get("demoKey").ToString());
  37. //memcache.Set("demoKey", (result + 1).ToString());
  38.  
  39. //如果0.5秒不释放锁 自动释放,避免死锁
  40. if (memcache.Add("LockKey", "Hello World", DateTime.Now.AddSeconds(0.5)))
  41. {
  42. //得到锁
  43. try
  44. {
  45. int result = int.Parse(memcache.Get("demoKey").ToString());
  46. memcache.Set("demoKey", (result + 1).ToString());
  47.  
  48. //注意:这里最好加上主动去删除锁
  49. //检查锁是否超时(直接去删除就可以)
  50. memcache.Delete("LockKey");
  51. }
  52. catch (Exception ex)
  53. {
  54. //发生异常时也直接删除锁
  55. memcache.Delete("LockKey");
  56. }
  57. }
  58. else
  59. {
  60. i = i - 1; //没有得到锁时等待
  61. }
  62. }
  63. Console.WriteLine("线程" + num + "结束,输出" + memcache.Get("demoKey"));
  64. }
  65. }
  66. }

运行结果效果图说明:

图一是没有加分布式锁的情况下执行结果
 
图二是加分布式锁的情况下执行结果,三个线程各循环500次,最终缓存值应该为1500才正确

Memcache分布式锁 转发 https://www.cnblogs.com/li150dan/p/9529090.html的更多相关文章

  1. MemCache在.NET中使用Memcached.ClientLibrary详解 转发 https://www.cnblogs.com/li150dan/p/9529112.html

    本文说明:memcached分布式缓存的负载均衡配置比例,数据压缩,socket的详细配置等,以及在.net中的常用方法 首先下载客户端的3个dll,ICSharpCode.SharpZipLib.d ...

  2. Memcache分布式锁

    在分布式缓存的应用中,会遇到多个客户端同时争用的问题.这个时候,需要用到分布式锁,得到锁的客户端才有操作权限 下面通过一个简单例子介绍: 这里引用的是Memcached.ClientLibrary.d ...

  3. ElasticSearch(站内搜索) 转发 https://www.cnblogs.com/xibei666/p/5929970.html

    简介 Elasticsearch是一个实时的分布式搜索和分析引擎.它可以帮助你用前所未有的速度去处理大规模数据.它可以用于全文搜索,结构化搜索以及分析,当然你也可以将这三者进行组合.Elasticse ...

  4. .net core redis 驱动推荐,为什么不使用 StackExchange.Redis 转发 https://www.cnblogs.com/kellynic/p/9325816.html

    前言 本人从事 .netcore 转型已两年有余,对 .net core 颇有好感,这一切得益于优秀的语法.框架设计. 2006年开始使用 .net 2.0,从 asp.net 到 winform 到 ...

  5. Cordova入门系列(二)分析第一个helloworld项目 转发 https://www.cnblogs.com/lishuxue/p/6015420.html

    Cordova入门系列(二)分析第一个helloworld项目   版权声明:本文为博主原创文章,转载请注明出处 上一章我们介绍了如何创建一个cordova android项目,这章我们介绍一下创建的 ...

  6. Cordova入门系列(三)Cordova插件调用 转发 https://www.cnblogs.com/lishuxue/p/6018416.html

    Cordova入门系列(三)Cordova插件调用   版权声明:本文为博主原创文章,转载请注明出处 上一章我们介绍了cordova android项目是如何运行的,这一章我们介绍cordova的核心 ...

  7. Cordova入门系列(一)创建项目 转发 https://www.cnblogs.com/lishuxue/p/6008678.html

    版权声明:本文为博主原创文章,转载请注明出处 Cordova是什么? 初学Cordova的人,虽然了解一点点,知道Cordova是用来将html, css, js变成app的,但并不知道到底是怎么用的 ...

  8. ActiveMQ安装配置及使用 转发 https://www.cnblogs.com/hushaojun/p/6016709.html

    ActiveMQ安装配置及使用 ActiveMQ介绍 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JM ...

  9. Topshelf:一款非常好用的 Windows 服务开发框架 转发https://www.cnblogs.com/happyframework/p/3601995.html

    背景 多数系统都会涉及到“后台服务”的开发,一般是为了调度一些自动执行的任务或从队列中消费一些消息,开发 windows service 有一点不爽的是:调试麻烦,当然你还需要知道 windows s ...

随机推荐

  1. idea编辑器快捷键调整

    习惯了Eclipse中的删除快捷键,idea中的快捷键用着不是很适应,于是乎调整了下. idea编辑器快捷键调整: 默认:删除代码行:Ctrl+Y复制代码行:Ctrl+D在当前行之前添加一行: Ctr ...

  2. Python mysql 创建连接

    安装 pymysql 模块 pip3 install pymysql # python2, 默认无 pip 命令 # python3, 默认自带 pip3 命令 mysql基本操作 # 导入 pymy ...

  3. vue从入门到进阶:简介(一)

    前言 用了这么久的vue了,但是一直没有时间写个系列文章,现在抽一定时间总结下vue的知识点. 首先,Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript ...

  4. input的type类型

    对部分生僻的input属性值解释: type="reset": 可以一键清空form表单里面所有的数据 <form> <input type="text ...

  5. Java 开源博客 Solo 1.9.0 发布 - 新皮肤

    这个版本主要是改进了评论模版机制,让大家更方便皮肤制作,并发布了一款新皮肤:9IPHP. Solo 是一款一个命令就能搭建好的 Java 开源博客系统,并内置了 15+ 套精心制作的皮肤.除此之外,S ...

  6. 苹果8plus怎么录屏视频

    现在越来越多的手机控,不管在什么地方,什么时候,都是低头看手机的居多,因为手机信息量太大了,一部手机就可以了解最新咨询,但是作为苹果8plus怎么录制手机屏幕,你们知道吗?今天就和大家一起分享苹果8p ...

  7. Android--手势及触摸事件的注意点(一)

    实现onInterceptTouchEvent方法可以用来拦截父ViewGroup传递下来的所有触屏事件,可以将所有触屏事件交由此ViewGroup自身的onTouchEvent来处理,也可以继续传递 ...

  8. MFC Bresesnham算法

    Bresesnham算法绘制直线段 Bresenham算法的意义:高效的将图形光栅化.其计算过程中均采用加法运算,故大大减少了程序的开销. 绘制直线段(MFC中) //传入参数:起点.终点,颜色 vo ...

  9. Android ListView的item背景色设置以及item点击无响应等相关问题

    Android ListView的item背景色设置以及item点击无响应等相关问题 在Android开发中,listview控件是非常常用的控件,在大多数情况下,大家都会改掉listview的ite ...

  10. 跨域调用接口的方法之一:$.ajaxSetup()

    跨域查询接口的数据,之前在公司时有发生过,产生的原因是,本地请求的域名或IP地址不一致,解除方法,也是修改域名和IP地址.比如: 接口中的数据来自IP地址:192.168.1.23/get.php 如 ...