Redisson的semaphore初始化在多个pod实例(jvm)的情况下 会被覆盖吗

Redisson的semaphore初始化在多个pod实例(jvm)的情况下 会被覆盖吗

首先是结论,不会。

当我们在项目中使用redisson的时候,我们要首先给redisson内部设置一个信号量的大小。

@Configuration
public class RedissonConfig {


    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        config.setTransportMode(TransportMode.NIO);
        SingleServerConfig singleServerConfig = config.useSingleServer();
        //可以用"rediss://"来启用SSL连接

        singleServerConfig.setAddress("redis://xx.xx.xx.xx:xxxx");
        singleServerConfig.setPassword("password");
        singleServerConfig.setDatabase(1);
        RedissonClient redisson = Redisson.create(config);
        RSemaphore upload = redisson.getSemaphore("upload");
        upload.trySetPermits(30);
        return redisson;


    }

现在我们就成功在对应的redis服务器中的db1里设置里一个key为upload的信号量,大小为30。

现在担心的问题是,因为生产的环境中,我们会有多个pod实例,相当于运行多个jvm,这一段redisson的配置代码将会被多次执行。

如果我先启动成功的jvm已经对semaphore的值进行了操作,会不会被后启动的jvm将semaphore的值重新覆盖为30.

结论是不会。理由如下。

设置semaphore的对象的permits大小调用的是trySetPermits()方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7RvNPPff-1650793254016)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1650792935589.png)]

再往下一层调用。

public RFuture<Boolean> trySetPermitsAsync(int permits) {
        return this.commandExecutor.evalWriteAsync(this.getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
         "local value = redis.call('get', KEYS[1]); if (value == false or value == 0) then redis.call('set', KEYS[1], ARGV[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1;end;return 0;",
          Arrays.asList(this.getName(), this.getChannelName()), new Object[]{permits});
    }

由上述代码可以得知。

这个方法是用的redis的lua脚本去执行的。

local value = redis.call('get', KEYS[1]);
if (value == false or value == 0) then redis.call('set', KEYS[1], ARGV[1]);
    redis.call('publish', KEYS[2], ARGV[1]); 
    return 1;
end;
return 0;

在这段代码中 他会首先去判断 value == false的时候 是指redis中不存在这一个key,value== 0的时候是指,Redis中这一个key的值结构不正确。此时他会去根据你的命名set一个新的key进去。

由此可以得出,当我们的pod集群去同时进行semaphore的赋值初始化操作时,并不会对原先的值进行覆盖。

以上。

你可能感兴趣的:(java,redis)