背景介绍的文章地址:传送门
这边直接介绍怎么使用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解析上面花了不少时间。特记录下解决方案。
本文为博主原创文章,未经博主允许不得转载。
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载