异常日志
org.springframework.dao.InvalidDataAccessApiUsageException: ERR 'EVAL' command keys must in same slot. channel: [id: 0x10457fd7...
原因分析
测试环境为单机版,线上环境为集群版,导致同样的lua脚本,在线上出错。
lua脚本为保证事务,传入的key必须是在同一个slot中。Redis集群引入了哈希槽的概念,一共有16348个slot,然后根据 CRC16(key) mod 16384 来计算放入哪个slot中。
解决方案
方案1(推荐)
在KEY上加{},这样在hash key 的时候只会计算{}内的内容,使得Key落在同一个slot内。
假设有两个Key,user:20200911,user:20200912,可以改写成{user}:20200911,{user}:20200912,这样redis做hash运算的时候只会取user ,这两个key自然会落在同一个slot中。
方案2(不推荐)
线上环境切换redis至单机版,一般不建议这么做。
心得总结
1.尽量模拟一套与线上环境相似的UAT环境。保证两者的运行环境相似。
2.对于不熟悉的技术方案,要慎用,考虑全面,引入lua脚本控制事务的时候,最好有现成的线上已运行的方案。
3.加深对底层的了解,而不仅仅只是停留在使用层面。