背景介绍的文章地址:传送门
这边直接介绍怎么使用 lua 实现。
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.List;
public class RedisManagerTest {
private RedisTemplate<String, String> redisTemplate;
private StringRedisSerializer stringRedisSerializer;
public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setStringRedisSerializer(StringRedisSerializer stringRedisSerializer) {
this.stringRedisSerializer = stringRedisSerializer;
}
private byte[][] deserializeByteListValue(Object... objs) {
byte[][] result = new byte[objs.length][];
for (int i=0;ilength;i++) {
int index = i;
result[index]=(objs[index]).toString().getBytes();
}
return result;
}
public Object eval(final RedisScript script, final List<String> keys, final Object... args) {
return redisTemplate.execute(script,stringRedisSerializer,stringRedisSerializer, keys, args);
}
}
RedisTemplate<String, String> 这里的泛型建议使用 String,之前使用 Serializable,lua 脚本里面死活解析不了传过去的数据。
下面是 redis 的配置
<bean id="lua" class="com.chai.utils.RedisManagerTest">
<property name="redisTemplate" ref="luaRedisTemplate"/>
<property name="stringRedisSerializer" ref="stringRedisSerializer"/>
</bean>
<bean id="luaRedisTemplate"
class="org.springframework.data.redis.core.RedisTemplate"
p:connectionFactory-ref="luaJedisConnFactory"/>
<bean id="luaJedisConnFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:hostName="${lua.redis.host}" p:port="${lua.redis.port}" p:timeout="${lua.redis.timeout}"
p:password="${lua.redis.password}"
p:poolConfig-ref="jedisPoolConfig"/>
<bean id="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="updateAvailableSavingsCard" class="org.springframework.data.redis.core.script.DefaultRedisScript">
<property name="location" value="classpath:/test.lua"/>
<property name="resultType" value="org.springframework.data.redis.connection.ReturnType"/>
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="300"/> <!-- 最大能够保持idel状态的对象数 -->
<property name="maxTotal" value="60000"/> <!-- 最大分配的对象数 -->
<property name="testOnBorrow" value="true"/> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->
</bean>
下面是测试类
public class test {
@Autowired
@Qualifier("lua")
private RedisManagerTest lua;
@Resource(name = "updateAvailableSavingsCard")
private RedisScript<ReturnType> updateAvailableSavingsCard;
@Test
public void eval(){
long startTime = System.currentTimeMillis();
Object evalObject = lua.eval(updateAvailableSavingsCard, Lists.newArrayList("test1"), "1,2,3");
long endTime = System.currentTimeMillis();
System.out.println("耗时:"+(endTime-startTime));
}
}
test.lua
local str = ARGV[1];
local sub_str_tab = {};
while (true) do
local pos = string.find(str, ",");
if (not pos) then
local size_t = table.getn(sub_str_tab)
table.insert(sub_str_tab,size_t+1,str);
break;
end
local sub_str = string.sub(str, 1, pos - 1);
local size_t = table.getn(sub_str_tab)
table.insert(sub_str_tab,size_t+1,sub_str);
local t = string.len(str);
str = string.sub(str, pos + 1, t);
end
local count;
for index,value in pairs(sub_str_tab) do
count=redis.call("SETBIT",KEYS[1],tonumber(value),1);
end
return count;
这边 java 传逗号隔开的数据到 lua 脚本,lua 脚本拿到数据之后,转换成 table,在循环 table 去 setbit 到 redis。
测试了下 10000 条数据,脚本的执行时间 371 毫秒
之前没弄个 lua,在这个 lua 解析上面花了不少时间。特记录下解决方案。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于