redis的集合比较命令失效的问题 diffAndStore

最近在使用redis的集合命令做对账比较时,上线前一切正常,上线后差异对比失效,两个完全相同的集合,在做diffAndStore后,差异的结果不为空。

本地进行了测试,本地redis使用了集群方式,结果本地复现,复现代码如下

        // redis的key的定义
        String localBillKey = "pay:reconciliation:local";
        String remoteBillKey = "pay:reconciliation:remote";
        String unionBillKey = "pay:reconciliation:union";
        String localMoreBillKey = "pay:reconciliation:localMore";
        String remoteMoreBillKey = "pay:reconciliation:remoteMore";
        List<String> keys = new ArrayList<>();
        keys.add(localBillKey);
        keys.add(remoteBillKey);
        keys.add(unionBillKey);
        keys.add(localMoreBillKey);
        keys.add(remoteMoreBillKey);
        // 对账前清理旧数据
        redis.delete(keys);
        BoundSetOperations<String, String> localBillKeyBoundSetOps = redis.boundSetOps(localBillKey);
        localBillKeyBoundSetOps.add("31812281457172855520647ffdEjiCtC,4200000214201812288098277144,0.01,2018-12-28 14:57:22",
                "31812281902498165520647526wg2aL1,4200000230201812285953513148,0.02,2018-12-28 19:02:58",
                "3181228095336491552064927e7V8AXl,4200000213201812285727593109,0.02,2018-12-28 09:53:41",
                "3181228094542800552064927eL6sNF5,4200000212201812282025391199,0.02,2018-12-28 09:45:48",
                "3181228094117343552064e2e3yfko10,4200000237201812286581975010,0.01,2018-12-28 09:41:23",
                "318122814105006455206475267JKCTr,4200000218201812283499936418,0.02,2018-12-28 14:10:57",
                "31812281736495635520647526utHwU5,4200000209201812283114535740,0.02,2018-12-28 17:36:55",
                "31812281443495415520647526BSD8dJ,4200000223201812280997256864,0.02,2018-12-28 14:43:55",
                "3181228095450983552064927egO84KB,4200000238201812285307041090,0.02,2018-12-28 09:54:56",
                "31812281531203625520648bdeOQLgBN,4200000231201812283770763156,0.02,2018-12-28 15:31:26",
                "31812281752496305520647526RVHKFG,4200000216201812289494841996,0.02,2018-12-28 17:52:55");

        BoundSetOperations<String, String> remoteBillKeyBoundSetOps = redis.boundSetOps(remoteBillKey);
        remoteBillKeyBoundSetOps.add("31812281902498165520647526wg2aL1,4200000230201812285953513148,0.02,2018-12-28 19:02:58",
                "3181228095450983552064927egO84KB,4200000238201812285307041090,0.02,2018-12-28 09:54:56",
                "3181228095336491552064927e7V8AXl,4200000213201812285727593109,0.02,2018-12-28 09:53:41",
                "31812281531203625520648bdeOQLgBN,4200000231201812283770763156,0.02,2018-12-28 15:31:26",
                "3181228094542800552064927eL6sNF5,4200000212201812282025391199,0.02,2018-12-28 09:45:48",
                "31812281752496305520647526RVHKFG,4200000216201812289494841996,0.02,2018-12-28 17:52:55",
                "31812281736495635520647526utHwU5,4200000209201812283114535740,0.02,2018-12-28 17:36:55",
                "31812281443495415520647526BSD8dJ,4200000223201812280997256864,0.02,2018-12-28 14:43:55",
                "3181228094117343552064e2e3yfko10,4200000237201812286581975010,0.01,2018-12-28 09:41:23",
                "31812281457172855520647ffdEjiCtC,4200000214201812288098277144,0.01,2018-12-28 14:57:22",
                "318122814105006455206475267JKCTr,4200000218201812283499936418,0.02,2018-12-28 14:10:57");

        // 4, 进行对比,获取共同的结果
        localBillKeyBoundSetOps.intersectAndStore(remoteBillKey, unionBillKey);
        Set<String> membersxx = redis.boundSetOps(unionBillKey).members();
        LOGGER.info("union {}", membersxx);
        // 5,获取本地多的情况,需要结合对账详情表
        localBillKeyBoundSetOps.diffAndStore(unionBillKey, localMoreBillKey);
        Set<String> members = redis.boundSetOps(localMoreBillKey).members();
        if (CollectionUtils.isNotEmpty(members)) {
            LOGGER.error("doReconciliation summary,localMore {}", members);
        }
        // 6,获取支付宝/微信多的情况,需要结合对账详情表
        redis.boundSetOps(remoteBillKey).diffAndStore(unionBillKey, remoteMoreBillKey);
        Set<String> members2 = redis.boundSetOps(remoteMoreBillKey).members();
        if (CollectionUtils.isNotEmpty(members2)) {
            LOGGER.error("doReconciliation summary,remoteMore {}", members2);
        }
        // 7,对账后,清理中间数据
        redis.delete(keys);

        return "success";
    }

各种纠结后,猛然想起之前测试时时redis单点测试的,想到redis集群模式下是根据key的hash映射来分布数据的,两个集合的key不一样,可能会分布到不同的节点上,这样diffAndStore时就出现问题。

想到这里,使用redis提供的tag方式,重新修改了测试代码

 // redis的key的定义
        String localBillKey = "{pay:reconciliation}:local";
        String remoteBillKey = "{pay:reconciliation}:remote";
        String unionBillKey = "{pay:reconciliation}:union";
        String localMoreBillKey = "{pay:reconciliation}:localMore";
        String remoteMoreBillKey = "{pay:reconciliation}:remoteMore";
        List<String> keys = new ArrayList<>();
        keys.add(localBillKey);
        keys.add(remoteBillKey);
        keys.add(unionBillKey);
        keys.add(localMoreBillKey);
        keys.add(remoteMoreBillKey);
        // 对账前清理旧数据
        redis.delete(keys);
        BoundSetOperations<String, String> localBillKeyBoundSetOps = redis.boundSetOps(localBillKey);
        localBillKeyBoundSetOps.add("31812281457172855520647ffdEjiCtC,4200000214201812288098277144,0.01,2018-12-28 14:57:22",
                "31812281902498165520647526wg2aL1,4200000230201812285953513148,0.02,2018-12-28 19:02:58",
                "3181228095336491552064927e7V8AXl,4200000213201812285727593109,0.02,2018-12-28 09:53:41",
                "3181228094542800552064927eL6sNF5,4200000212201812282025391199,0.02,2018-12-28 09:45:48",
                "3181228094117343552064e2e3yfko10,4200000237201812286581975010,0.01,2018-12-28 09:41:23",
                "318122814105006455206475267JKCTr,4200000218201812283499936418,0.02,2018-12-28 14:10:57",
                "31812281736495635520647526utHwU5,4200000209201812283114535740,0.02,2018-12-28 17:36:55",
                "31812281443495415520647526BSD8dJ,4200000223201812280997256864,0.02,2018-12-28 14:43:55",
                "3181228095450983552064927egO84KB,4200000238201812285307041090,0.02,2018-12-28 09:54:56",
                "31812281531203625520648bdeOQLgBN,4200000231201812283770763156,0.02,2018-12-28 15:31:26",
                "31812281752496305520647526RVHKFG,4200000216201812289494841996,0.02,2018-12-28 17:52:55");

        BoundSetOperations<String, String> remoteBillKeyBoundSetOps = redis.boundSetOps(remoteBillKey);
        remoteBillKeyBoundSetOps.add("31812281902498165520647526wg2aL1,4200000230201812285953513148,0.02,2018-12-28 19:02:58",
                "3181228095450983552064927egO84KB,4200000238201812285307041090,0.02,2018-12-28 09:54:56",
                "3181228095336491552064927e7V8AXl,4200000213201812285727593109,0.02,2018-12-28 09:53:41",
                "31812281531203625520648bdeOQLgBN,4200000231201812283770763156,0.02,2018-12-28 15:31:26",
                "3181228094542800552064927eL6sNF5,4200000212201812282025391199,0.02,2018-12-28 09:45:48",
                "31812281752496305520647526RVHKFG,4200000216201812289494841996,0.02,2018-12-28 17:52:55",
                "31812281736495635520647526utHwU5,4200000209201812283114535740,0.02,2018-12-28 17:36:55",
                "31812281443495415520647526BSD8dJ,4200000223201812280997256864,0.02,2018-12-28 14:43:55",
                "3181228094117343552064e2e3yfko10,4200000237201812286581975010,0.01,2018-12-28 09:41:23",
                "31812281457172855520647ffdEjiCtC,4200000214201812288098277144,0.01,2018-12-28 14:57:22",
                "318122814105006455206475267JKCTr,4200000218201812283499936418,0.02,2018-12-28 14:10:57");

        // 4, 进行对比,获取共同的结果
        localBillKeyBoundSetOps.intersectAndStore(remoteBillKey, unionBillKey);
        Set<String> membersxx = redis.boundSetOps(unionBillKey).members();
        LOGGER.info("union {}", membersxx);
        // 5,获取本地多的情况,需要结合对账详情表
        localBillKeyBoundSetOps.diffAndStore(unionBillKey, localMoreBillKey);
        Set<String> members = redis.boundSetOps(localMoreBillKey).members();
        if (CollectionUtils.isNotEmpty(members)) {
            LOGGER.error("doReconciliation summary,localMore {}", members);
        }
        // 6,获取支付宝/微信多的情况,需要结合对账详情表
        redis.boundSetOps(remoteBillKey).diffAndStore(unionBillKey, remoteMoreBillKey);
        Set<String> members2 = redis.boundSetOps(remoteMoreBillKey).members();
        if (CollectionUtils.isNotEmpty(members2)) {
            LOGGER.error("doReconciliation summary,remoteMore {}", members2);
        }
        // 7,对账后,清理中间数据
        redis.delete(keys);

        return "success";

结果通过预期行为。测试环境redis和当初开发时redis均使用了单点,从而没有出现该问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值