Java的Redis操作
阿新 • • 發佈:2018-12-21
Java的Redis客戶端Jedis:
Jedis jedis = new Jedis("127.0.0.1",6379);
//key
Set<String> keys = jedis.keys("*");
//String
jedis.set("k4","k4_Redis");
//List
List<String> list = jedis.lrange("mylist",0,-1);
//set
jedis.sadd("orders","jd001");
jedis.sadd("orders","jd002");
jedis.sadd("orders","jd003");
Set<String> set1 = jedis.smembers("orders");
//hash
jedis.hset("hash1","userName","lisi");
System.out.println(jedis.hget("hash1","userName"));
Map<String,String> map = new HashMap<String,String>();
map.put("telphone","13810169999");
map.put("address","atguigu");
map.put("email"," [email protected]");
jedis.hmset("hash2",map);
List<String> result = jedis.hmget("hash2", "telphone","email");
//zset
jedis.zadd("zset01",60d,"v1");
jedis.zadd("zset01",70d,"v2");
jedis.zadd("zset01",80d,"v3");
jedis.zadd("zset01",90d,"v4");
Set<String> s1 = jedis.zrange("zset01",0,-1);
連結池:
public class JedisPoolUtil { private static volatile JedisPool jedisPool = null; //被volatile修飾的變數不會被本地執行緒快取,對該變數的讀寫都是直接操作共享記憶體。 private JedisPoolUtil() {} public static JedisPool getJedisPoolInstance(){ if(null == jedisPool) { synchronized (JedisPoolUtil.class){if(null == jedisPool) { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxActive(1000); poolConfig.setMaxIdle(32); poolConfig.setMaxWait(100*1000); poolConfig.setTestOnBorrow(true); jedisPool = new JedisPool(poolConfig,"127.0.0.1"); } } } return jedisPool; }
連結池—釋放方法:
public static void release(JedisPool jedisPool,Jedis jedis)
{
if(null != jedis)
{
jedisPool.returnResourceObject(jedis);
}
}
連結池--主函式:
public class Test01 { public static void main(String[] args) { JedisPool jedisPool = JedisPoolUtil.getJedisPoolInstance(); Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.set("k18","v183"); } catch (Exception e) { e.printStackTrace(); }finally{ JedisPoolUtil.release(jedisPool, jedis); } } }
連結池引數:
- maxActive:控制一個pool可分配多少個jedis例項,通過pool.getResource()來獲取;如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis例項,則此時pool的狀態為exhausted。
- maxIdle:控制一個pool最多有多少個狀態為idle(空閒)的jedis例項; whenExhaustedAction:表示當pool中的jedis例項都被allocated完時,pool要採取的操作;預設有三種。 WHEN_EXHAUSTED_FAIL --> 表示無jedis例項時,直接丟擲NoSuchElementException; WHEN_EXHAUSTED_BLOCK --> 則表示阻塞住,或者達到maxWait時丟擲JedisConnectionException; WHEN_EXHAUSTED_GROW --> 則表示新建一個jedis例項,也就說設定的maxActive無用;
- maxWait:表示當borrow一個jedis例項時,最大的等待時間,如果超過等待時間,則直接拋JedisConnectionException;
- testOnBorrow:獲得一個jedis例項的時候是否檢查連線可用性(ping());如果為true,則得到的jedis例項均是可用的;
- testOnReturn:return 一個jedis例項給pool時,是否檢查連線可用性(ping());
- testWhileIdle:如果為true,表示有一個idle object evitor執行緒對idle object進行掃描,如果validate失敗,此object會被從pool中drop掉;這一項只有在timeBetweenEvictionRunsMillis大於0時才有意義;
- timeBetweenEvictionRunsMillis:表示idle object evitor兩次掃描之間要sleep的毫秒數;
- numTestsPerEvictionRun:表示idle object evitor每次掃描的最多的物件數;
- minEvictableIdleTimeMillis:表示一個物件至少停留在idle狀態的最短時間,然後才能被idle object evitor掃描並驅逐;這一項只有在timeBetweenEvictionRunsMillis大於0時才有意義;
- softMinEvictableIdleTimeMillis:在minEvictableIdleTimeMillis基礎上,加入了至少minIdle個物件已經在pool裡面了。如果為-1,evicted不會根據idle time驅逐任何物件。如果minEvictableIdleTimeMillis>0,則此項設定無意義,且只有在timeBetweenEvictionRunsMillis大於0時才有意義;
- lifo:borrowObject返回物件時,是採用DEFAULT_LIFO(last in first out,即類似cache的最頻繁使用佇列),如果為False,則表示FIFO佇列;
Redis事務--秒殺案例:
1、解決計數器和人員記錄的原子操作
超賣問題:
2、利用樂觀鎖淘汰使用者,解決超賣問題。
jsp:
<form id="msform" action="${pageContext.request.contextPath}/miaosha">
<input type="hidden" id="userid" name="userid" value="">
<input type="hidden" id="prodid" name="prodid" value="pd1">
<input type="button" id="miaosha_btn" name="miaosha_btn" value="秒殺點我"/>
</form>
<script type="text/javascript" src="${pageContext.request.contextPath}/script/jquery/jquery-3.1.0.js"></script>
<script type="text/javascript">
$(function(){
$("#miaosha_btn").click(function(){
var userid="user_"+Math.floor(Math.random()*100);
$("#userid").val(userid);
var url=$("#msform").attr("action");
$.post(url,$("#msform").serialize(),function(data){
if(data=="false"){
alert("搶光了" );
$("#miaosha_btn").attr("disabled",true);
}
});
})
})
</script>
Servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userid =request.getParameter("userid");
String prodid =request.getParameter("prodid");
boolean if_success=Miaosha_Redis.do_miaosha(userid,prodid);
response.getWriter().print(if_success);
}
Redis:
public static boolean do_miaosha(String uid,String prodid){
Jedis jedis = new Jedis "127.0.0.1",6379);
System.out.println("connection is OK==========>: "+jedis.ping());
jedis.watch(prodid);
Integer num = Integer.parseInt(jedis.get(prodid));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(num.intValue()==0){
jedis.unwatch();
return false;
}else{
Transaction transaction = jedis.multi();
transaction.decr(prodid);
transaction.lpush(prodid+"-usr", uid);
List list=transaction.exec();
if(list==null){
System.out.println("秒殺失敗");
}else{
System.out.println(uid+":秒殺成功");
}
jedis.close();
return true;
}
}