热爱技术,追求卓越
不断求索,精益求精

使用redisson的RMapCache的addAndGet方法报错ERR Error running script

redisson虽然是个不错的开源组件,但还在发展中,今天在使用redisson(版本3.7.5)的RMapCache的时候,报如下错误:

org.redisson.client.RedisException: ERR Error running script (call to f_cb87dfaf85a65541ca30fc07170c12f219d89c54): @user_script:1: user_script:1: attempt to perform arithmetic on a nil value . channel: [id: 0x076a07ec, L:/192.168.0.49:60754 - R:172.17.0.2/172.17.0.2:6390] command: (EVAL), params: [local value = redis.call('hget', KEYS[1], ARGV[2]); local expireDate = 92233720368547758; local t = ..., 8, TEST_MAP, redisson__timeout__set:{TEST_MAP}, redisson__idle__set:{TEST_MAP}, redisson_map_cache_created:{TEST_MAP}, redisson_map_cache_updated:{TEST_MAP}, redisson__map_cache__last_access__set:{TEST_MAP}, redisson_map_cache_removed:{TEST_MAP}, {TEST_MAP}:redisson_options, ...]
    at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:331)
    at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:128)
    at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:108)
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
    at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:367)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:745)

出现这个错误的版本是较新的3.7.5版本,依赖如下:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.7.5</version>
</dependency>

报错的测试代码如下:

@Test
public void testMapCache(){
    try {
        String key = "TEST_MAP_KEY";
        RMapCache<String, Long> map = redissonClient.getMapCache("TEST_MAP");
        map.fastPutIfAbsent(key, 1L, 10, TimeUnit.SECONDS);
        if(!map.fastPutIfAbsent(key, 1L, 10, TimeUnit.SECONDS)){
            System.out.println(map.addAndGet(key, 1L));
        }   
    } catch (Exception e) {
        e.printStackTrace();
    }
}

把上面的Long数据类型变成Integer,修改后的代码如下,却没有错误。

@Test
public void testMapCache(){
    try {
        String key = "TEST_MAP_KEY";
        RMapCache<String, Integer> map = redissonClient.getMapCache("TEST_MAP");
        map.fastPutIfAbsent(key, 1, 10, TimeUnit.SECONDS);
        if(!map.fastPutIfAbsent(key, 1, 10, TimeUnit.SECONDS)){
            System.out.println(map.addAndGet(key, 1));
        }   
    } catch (Exception e) {
        e.printStackTrace();
    }
}

说明redisson对数据类型的处理还做得不够完善,记录下这个错误,使用的时候小心,已经把该问题提交到github:

https://github.com/redisson/redisson/issues/1628

经测试,最新版3.8.0也有同样问题,redis服务端版本4.0.6.

这个问题最终解决了是用法原因导致,可参考文章《使用redisson的RMapCache先put后addAndGet报错ERR Error running script的解决方法

赞(1)
未经允许不得转载:LoveCTO » 使用redisson的RMapCache的addAndGet方法报错ERR Error running script

热爱技术 追求卓越 精益求精