网上找客户用什么软件,网络推广优化方法,东莞手机网站价格便宜,滨州seo排名全局锁在系统访问单个资源时或多或少都会要使用到锁#xff0c;如Java的Lock等#xff0c;但多个系统访问资源#xff0c;或在集群中各个实例需要访问资源时#xff0c;就需要建立全局的锁#xff0c;这里讲三种全局锁的方法。数据库利用ACID使用关系型数据库的ACID可以创…全局锁在系统访问单个资源时或多或少都会要使用到锁如Java的Lock等但多个系统访问资源或在集群中各个实例需要访问资源时就需要建立全局的锁这里讲三种全局锁的方法。数据库利用ACID使用关系型数据库的ACID可以创建一个锁UPDATE LOCKTABLE SET INSTANCE WHERE RESOURCEXXXX AND INSTANCE IS NULL;当返回更新了相应记录后就代表获得了锁对应的可以使用以下sql来释放获得的锁UPDATE LOCKTABLE SET INSTANCE WHERE RESOURCEXXXX AND INSTANCE;上面的方法看上去很好但是当获得锁的实例宕机那么这个锁就一直被占用着利用行锁为了解决实例非正常退出而没有释放锁可以使用数据库(ORACLE)的行锁SELECT 1 FROM LOCKTABLE WHERE RESOURCEXXXX FOR UPDATE;这样在commit/rollback之前就能持有这个锁如果调用方断开数据库也会自动rollback。可以使用NOWAIT循环查询的方式防止阻塞REDIS数据库固然可以但应对大量的资源需要长期持有大量锁也不是很恰当下面看下Redis如何创建全局锁SETNXSETNX是set if not exist的缩写也就是当值不存在时再进行赋值SETNX lock.resource 1//hold the lockDEL lock.resource以上伪代码简单演示了如何获得锁和释放锁和数据库的方法一样这种方法同同样存在实例宕机的风险导致死锁SET可惜Redis上没有像数据库中的for update。一个替代方法是使用expire。即给锁设定一个超时时间如果时间超过自动释放锁这里超时时间要合适不能过长让其他实例空等也不能过短实例没有结束就自动释放了。幸运的是Redis 2.6.12之后SET命令可以使用expire和notexistSET lock.resource NX EX timeout//hold the lockWATCH lock.resourceGET lock.resourceMULTIif(getResult)DEL lock.resourceEXEC使用watch/multi确保竞态条件RedLock防止单Redis不可用可以使用多个redis在半数以上节点获得锁的情况下代表获得锁否则就释放所有获得的锁。RedisonZookeeperredis的不足就是只能通过expire来控制锁持有者失联的情况。zookeeper在这方面就有一定的优势再加上zookeeper天生自带集群在可靠性上优于rediszookeeper可以创建ephemeral节点当客户端断开连接节点自动删除可以创建一个节点最小值持有当前锁create -e -s /LOCK/RESOURCE/REQUEST 1之后判断如果当前节点最小就获得锁如果没有就在前一个节点上加watch在watch中再进行判断这样就实现了等待获得锁的队列。总结全局锁在集群上的应用有不少最常见的就如集群内CRON任务执行的管理等。这里主要介绍的还是悲观锁在某些场景也可以使用乐观锁进行优化。