1.為什么要使用lua腳本,使用lua腳本操作redis有哪些好處
- 1.我現(xiàn)在模擬一個場景獲取一個用戶的購物車?yán)锩嫠猩唐返脑斍椤?/li>
- 1.1 用戶購物車的redis數(shù)據(jù)結(jié)構(gòu)
Map itemInfo = new HashMap();
itemInfo.put("name","刮胡刀");
itemInfo.put("type","電動");
itemInfo.put("price","200.00");
....穿件10件商品
Jedis jedis = CacheUtils.getJedis();
try{
jedis.sadd("car." + userId,"item.info." +Item);
jedis.sadd("car." + userId,"item.info." +Item2);
jedis.hmset("item.info." +Item ,itemInfo);
jedis.hmset("item.info." +Item2 ,itemInfo2);
.......插入10件商品
}finally{
CacheUtils.returnJedis(jedis);
}
- 1.2 獲取某個用戶購物車的所有詳情
Jedis jedis = CacheUtils.getJedis();
try{
Set<String> infos = jedis.smembers("car."+userId);
for (String info : infos){
Map itemInfo = jedis.hgetAll(info);
}
}finally{
CacheUtils.returnJedis(jedis);
}
以上代碼實現(xiàn)了獲取某個用戶購物車的所有商品。
- 1.3 使用lua獲取某個用戶購物車的所有詳情
StringBuffer lua = new StringBuffer();
lua.append(" local infos = redis.call('SMEMBERS','car.'..KEYS[1]); ")
.append("local datas = {}; ")
.append("for i,info in ipairs(config_ids) do ")
.append(" local info = redis.call('HGETALL',info); ")
.append(" table.insert(datas,info); ")
.append("end; ")
.append("return datas ");
Jedis jedis = CacheUtils.getJedis();
String scriptLoad = jedis.scriptLoad(lua.toString());
try {
List<String> list = (List<String>)jedis.evalsha(scriptLoad,1,userId);
} finally {
CacheUtils.returnJedis(jedis);
}
- 1.3.1 使用lua能減少網(wǎng)絡(luò)的開銷,假設(shè)原先10次請求和10次響應(yīng),使用lua將減少至1次請求1次響應(yīng),并且lua會被緩存到redis中再次執(zhí)行這個方法的時候,直接在redis中獲取緩存的腳本直接執(zhí)行,進(jìn)一步的減少網(wǎng)絡(luò)的開銷。
- 1.3.2 減少線程持有jedis對象的時間,更快的把redis對象釋放掉。
- 1.3.3 lua能保證整一個代碼塊的原子性,通過lua可以實現(xiàn)一些簡單的分布式鎖的功能。
2.使用lua的注意事項
- 1 使用lua操作redis的時候需要注意【不能執(zhí)行太復(fù)雜的邏輯】一旦lua腳本執(zhí)行了太復(fù)雜的邏輯勢必會占用了redis的整個資源,使得其他的線程只能阻塞,嚴(yán)重會影響整個系統(tǒng)的吞吐量。