• Redisson的RSetMultimapCache的bug


    1.RSetMultimapCache

    是redisson基于redis设计的数据结构
    主要用于存取数据结构为Map<String,Set> map 这种数据结构

    2.putAll方法的坑

    RSetMultimapCache<String, String> list = getRGroup(redissonClient);
    list.removeAll(data._1());
    list.putAll(data._1(), data._2());
    // data._2() 是一个空的set集合
    

    3.报错

    
    org.redisson.client.RedisException: org.redisson.client.RedisException: ERR Error running script (call to f_7c3b3f3f21cf881e4d180f655f0a0dd38e10881b): @user_script:1: @user_script: 1: Wrong number of args calling Redis command From Lua script . channel: [id: 0x26778fe0, L:/100.124.40.11:55608 - R:redis-d5v3mijcv6tt-proxy-nlb.jvessel-open-hb.jdcloud.com/11.91.185.242:6379] command: (EVAL), promise: java.util.concurrent.CompletableFuture@a2b40a1[Not completed, 1 dependents], params: [redis.call('hset', KEYS[1], ARGV[1], ARGV[2]); return redis.call('sadd', KEYS[2], unpack(ARGV, 3, #A..., 2, resource:group, {resource:group}:pbmdr/9bbtq0lNZx3p0Bhg, PooledUnsafeDirectByteBuf(ridx: 0, widx: 6, cap: 256), pbmdr/9bbtq0lNZx3p0Bhg]
    
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    	at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593)
    	at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
    	at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735)
    	at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
    	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
    	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
    	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:583)
    	at delta.storage.redis.RedisUtils.setResourceGroup(RedisUtils.java:288)
    	at delta.config.processor.ResourceGroupProcessor.process(ResourceGroupProcessor.java:57)
    	at delta.config.processor.ResourceGroupProcessor.process(ResourceGroupProcessor.java:25)
    	at delta.config.woker.ConfigFlushWorker.lambda$flush$1(ConfigFlushWorker.java:56)
    	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
    	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
    	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    	at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
    	at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
    	at java.util.concurrent.ForkJoinTask.doExec$$$capture(ForkJoinTask.java:289)
    	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java)
    	at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:401)
    	at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)
    	at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
    	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
    	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
    	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:583)
    	at delta.config.woker.ConfigFlushWorker.flush(ConfigFlushWorker.java:56)
    	at delta.config.test.resourcegroup.TestResourceGroup.getAllGroups(TestResourceGroup.java:30)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
    	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    	at java.util.ArrayList.forEach(ArrayList.java:1257)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    	at java.util.ArrayList.forEach(ArrayList.java:1257)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
    	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
    	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
    	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
    	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
    Caused by: org.redisson.client.RedisException: ERR Error running script (call to f_7c3b3f3f21cf881e4d180f655f0a0dd38e10881b): @user_script:1: @user_script: 1: Wrong number of args calling Redis command From Lua script . channel: [id: 0x26778fe0, L:/100.124.40.11:55608 - R:redis-d5v3mijcv6tt-proxy-nlb.jvessel-open-hb.jdcloud.com/11.91.185.242:6379] command: (EVAL), promise: java.util.concurrent.CompletableFuture@a2b40a1[Not completed, 1 dependents], params: [redis.call('hset', KEYS[1], ARGV[1], ARGV[2]); return redis.call('sadd', KEYS[2], unpack(ARGV, 3, #A..., 2, resource:group, {resource:group}:pbmdr/9bbtq0lNZx3p0Bhg, PooledUnsafeDirectByteBuf(ridx: 0, widx: 6, cap: 256), pbmdr/9bbtq0lNZx3p0Bhg]
    	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:370)
    	at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:198)
    	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:137)
    	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:113)
    	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:507)
    	at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)
    	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
    	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
    	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
    	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    	at java.lang.Thread.run(Thread.java:748)
    

    4.解决方案

    空集合过滤,保证非空集合在进行putAll操作

    5.redisson内部实现

    通过eval调用lua脚本实现原子性操作
    导致params对不上

    @Override
        public RFuture<Boolean> putAllAsync(K key, Iterable<? extends V> values) {
            List<Object> params = new ArrayList<Object>();
            ByteBuf keyState = encodeMapKey(key);
            params.add(keyState);
            String keyHash = hash(keyState);
            params.add(keyHash);
            for (Object value : values) {
                ByteBuf valueState = encodeMapValue(value);
                params.add(valueState);
            }
    
            String setName = getValuesName(keyHash);
            return commandExecutor.evalWriteAsync(getRawName(), codec, RedisCommands.EVAL_BOOLEAN_AMOUNT,
                    "redis.call('hset', KEYS[1], ARGV[1], ARGV[2]); " +
                    "return redis.call('sadd', KEYS[2], unpack(ARGV, 3, #ARGV)); ",
                Arrays.<Object>asList(getRawName(), setName), params.toArray());
        }
    

    里面调用lua脚本的语法unpack(ARGV,3,#ARGV),从第三位开始解包,第三位是空,所以后面unpack返回的是个空nil,空对象,不是空字符串

    6.redis的set集合数据结构

    使用工具创建一个单独的set变量h_set_test的key,value想是空集合的时候
    结果自动创建了一个集合,集合里面有一个数据new member,看来想存空集合是不可能的了

  • 相关阅读:
    c# 中的线程和同步
    Javascript 观察者模式
    连接SQLite 创建ADO.net实体类
    给软件增加注册功能 c#
    log4net 使用步骤
    C# 操作 Excel
    PCL编译历程
    设计模式
    kinect
    eclipse配置servlet错误
  • 原文地址:https://www.cnblogs.com/PythonOrg/p/16179528.html
Copyright © 2020-2023  润新知