zoukankan      html  css  js  c++  java
  • Redisson分布式锁总结

    1、分布式锁目前可能存在的问题(基于redis客户端jedis)
    加锁: set key value [expiration EX seconds|PX milliseconds] [NX|XX]
    该加锁方式是从Redis2.8之后便支持这种原子性加锁方式,之前设置setnx和设置过期时间不是原子性的。

    String ret = jedis.set(getKey(key), 
                           new CacheEntity<T>(serializable, version, System.currentTimeMillis()).getBytes(), 
                           "NX".getBytes(),
                           "EX".getBytes(), 
                           expireSecond);
    return StringUtils.equals("OK", ret);

    参数解释如下:

    • EX second :设置key的过期时间为 second 秒
    • PX millisecond :设置key的过期时间为 millisecond 毫秒
    • NX :只在key不存在时,才对key进行设置操作
    • XX :只在key已经存在时,才对key进行设置操作

    解锁

    ret = jedis.del(getKey(key));

    使用

    if (!lock.tryLockXxx(key)) {
      return ;
    }
    try {
      // TODO
    } finally { lock.unlockXxx(key); }

    基于jedis实现的分布式锁缺点

    • 不支持重入
    • 加锁时设置的value无意义
    • 锁超时时间不能自动续期,所以不好取值
    • 锁超时时间 > 业务执行时间,业务正常执行完成释放锁,没问题,业务节点奔溃,尚未释放锁,会导致其他业务系统线程最多等待整个超时时间
    • 锁超时时间 < 业务执行时间,锁超时自动释放,业务执行完成,再执行unlock,可能会错误的解锁
    • 加锁key设置在Master节点上,尚未同步到slave就宕机了,salve提升为新的master,没有上一个锁的信息,其他线程依然可以获取同一个key的锁

    2、Redisson客户端优势

    • 支持 SSL
    • 线程安全的实现
    • Reactive Streams API
    • 异步 API
    • 异步连接池
    • Lua 脚本
    • 分布式Java对象
    • Object holder, Binary stream holder, Geospatial holder, BitSet, AtomicLong, AtomicDouble, PublishSubscribe, Bloom filter, HyperLogLog
    • 分布式Java集合
    • Map, Multimap, Set, List, SortedSet, ScoredSortedSet, LexSortedSet, Queue, Deque, Blocking Queue, Bounded Blocking Queue, Blocking Deque, Delayed Queue, Priority Queue, Priority Deque
    • 分布式锁和同步器
    • Lock, FairLock, MultiLock, RedLock, ReadWriteLock, Semaphore, PermitExpirableSemaphore, CountDownLatch

    Redisson的基本用法参考这篇博客《基于redission的分布式锁

    自动续期源码:

    // tryAcquireAsync -> scheduleExpirationRenewal -> renewExpiration
    // 自动续期
    private void renewExpiration() {
        ...
    
        Timeout task = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
            @Override
            public void run(Timeout timeout) throws Exception {
                ExpirationEntry ent = EXPIRATION_RENEWAL_MAP.get(getEntryName());
                if (ent == null) {
                    return;
                }
                Long threadId = ent.getFirstThreadId();
                if (threadId == null) {
                    return;
                }
    
                RFuture<Boolean> future = renewExpirationAsync(threadId);
                future.onComplete((res, e) -> {
                    if (e != null) {
                        log.error("Can't update lock " + getRawName() + " expiration", e);
                        EXPIRATION_RENEWAL_MAP.remove(getEntryName());
                        return;
                    }
    
                    if (res) {
                        // reschedule itself
                        renewExpiration();
                    }
                });
            }
        }, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);
    
        ...
    }

    真正执行续期的lua脚本

    protected RFuture<Boolean> renewExpirationAsync(long threadId) {
        return evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
                              "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
                              "redis.call('pexpire', KEYS[1], ARGV[1]); " +
                              "return 1; " +
                              "end; " +
                              "return 0;",
                              Collections.singletonList(getRawName()),
                              internalLockLeaseTime, getLockName(threadId));
    }

    Netty中的时间轮算法 HashedWheelTimer

     

    郭慕荣博客园
  • 相关阅读:
    10种颜色 线性渐变 web buttons按钮 兼容IE6
    10个款优秀的jquery图片特效插件推荐 值得分享
    【转载】C#中多线程间的同步
    【转载】JavaScript获取当前Url路径
    【转载】MVC 强类型视图
    【转载】jQuery遍历
    【转载】MVC Ajax Helper或jQuery异步方式加载部分视图
    【转载】MVCHtmlHelper简单总结
    【转载】ASP.NET MVC之下拉框绑定四种方式
    【转载】MVC Ajax Helpers
  • 原文地址:https://www.cnblogs.com/jelly12345/p/14944612.html
Copyright © 2011-2022 走看看