Java客戶端Jedis
這里只講Jedis常規(guī)用法和五種數(shù)據(jù)結(jié)構(gòu)的方法(關(guān)于集群的搭建以后再寫)
2.稍微修飾下
3.運行效果
4.相應(yīng)的jar包(第一個不兼容,沒用,junit4.4:@test 做測試所需)
二,redis數(shù)據(jù)類型(String List Set Sorted Hash )方法介紹(方法參數(shù)類型如果每注明都是String)
1. Jedis jedis = new Jedis("192.168.0.163", 6379); //寫自己的地址
2.JedisCluster jedis = new JedisCluster(jedisClusterNodes);//jedisClusterNodes是多個IP組成
redis的String類型數(shù)據(jù)結(jié)構(gòu)的緩存操作:
/**
* 字符串緩存操作類或者JavaBean緩存操作類
* key String, value String-->看下邊的注意點2
* key byte[], value byte[]-->key.getBytes[], value 序列化為byte[],通常需要自己寫一個序列化工具
* 注意:這一點與memcached不一樣,memcached可以key String, value Object
* 1、memcached直接加序列化器就可以,或者在業(yè)務(wù)層中將Object-->String
* 2、redis執(zhí)行此接口,一般只會采用后者Object-->String
*/
String:
1. jedis.set(key,value);//set(String,String),value除了string以外,還可以是byte[]
/**
* 設(shè)置緩存
* 類似于memcached的set,不管是否已經(jīng)有相同的key,都成功
* 實際上只是set(String, String)
*/
2.jedis.setex(key, value, expire);
/**
* 設(shè)置緩存,并指定緩存過期時間,單位是秒
*/
3.jedis.setnx(key, value);
/**
* 設(shè)置緩存,如果設(shè)置的key不存在,直接設(shè)置,如果key已經(jīng)存在了,則什么操作都不做,直接返回
* 類似于memcached的add
*/
long setCount = jedis.setnx(keyPrefix+KEY_SPLIT+key, value);
4. jedis.get(key);
/**
* 根據(jù)key獲取緩存
* @param key
* @return String
*/
5. jedis.del(key);
/**
* 根據(jù)key刪除緩存
*/
6. jedis.expire(key, expire);
/**
* 更新緩存過期時間,單位:秒
* 從運行該方法開始,為相應(yīng)的key-value設(shè)置緩存過期時間expire
* 類似于memcached中的touch命令
*/
redis的List類型數(shù)據(jù)結(jié)構(gòu)的緩存操作:
List(有序列表工具類)
1. jedis.lpush(list, values);//可以多值(String list, String... values)
/**
* 從左邊(首部)加入列表
* 注意:
* 1、可以一次性入隊n個元素(這里使用了不定參數(shù),當然可以換做數(shù)組)
* 2、左邊入隊,相當于在隊頭插入元素,則之后的元素都要后移一位;而右邊入隊的話元素直接插在隊尾,之前的元素的索引不變
*/
2.
jedis.lpush(list, values);
jedis.expire(list, expire);//為該list設(shè)置緩存過期時間
/**
* 從左邊(首部)加入列表
* 并指定列表緩存過期時間
*/
3. jedis.rpush(list, values);
/**
* 從右邊(尾部)加入列表
*/
4.
jedis.rpush(list, values);
jedis.expire(list, expire);//設(shè)置緩存過期時間
/**
* 從右邊(尾部)加入列表
* 并設(shè)置緩存過期時間
*/
5. jedis.lset(list, index, value);
/**
* 設(shè)置list中index位置的元素
* index==-1表示最后一個元素
*/
6.jedis.lpop(list);
/**
* 從左邊(首部)出列表
*/
7.jedis.rpop(list);
/**
* 從右邊出列表
*/
8.jedis.lindex(list, index);
/**
* 返回list中index位置的元素
*/
9.jedis.lrange(list, start, end);
/**
* 返回list指定區(qū)間[start,end]內(nèi)的元素
*/
10. lrange(list, 0, -1);
/**
* 返回list內(nèi)的全部元素
*/
11. jedis.ltrim(list, start, end);
/**
* 讓list只保留指定區(qū)間[start,end]內(nèi)的元素,不在指定區(qū)間內(nèi)的元素都將被刪除
*/
12. jedis.lrem(list, count, value);//返回刪除了多少個元素
/**
* 刪除list中所有與value相等的元素
* 注意:
* count
* ==0 :刪除表中所有與value相等的元素
* >0:從表頭開始向表尾搜索,移除count個與value相等的元素
* <0:從表尾開始向表頭搜索,移除count個與value相等的元素
*/
13.lremove(list, 0, value);
/**
* 刪除list中所有與value相等的元素
*/
14.jedis.llen(list);
/**
* 返回list中共有多少個元素
*/
set無序集合工具類
注意:
元素在set中的存放順序為:與插入set的先后書順序無關(guān)(即無序)
不允許存放重復(fù)元素
對于set而言,Jedis有交集、差集、并集運算,可是ShardJedis沒有
1.jedis.sadd(set, values);
/*
* 對比:
* lpush(String key, String... strings);
* 返回push之后的list中包含的元素個數(shù)
*
* sadd(String key, String... members)
* 1:添加元素成功
* 0:set中已經(jīng)有要添加的元素了
*/
2.jedis.smembers(set)
/**
* 獲取set集合中的所有緩存
* @param set
*/
3. jedis.srem(set, values)
/**
* 刪除緩存
* @param set
* @param values
*/
4.jedis.sismember(set, value);
/**
* set集合是否包含value
* @param set
*/
5.jedis.scard(set);
/**
* 返回set集合的元素個數(shù)
* @param set
*/
Sorted Set(有序集合工具類)
/**
* sorted set緩存操作類
* 1、有序集合,最后的順序是按照score從小到大的順序排列
* 2、元素不能重復(fù)
* 3、沒有從set中獲取指定value的運算
*/
1.jedis.zadd(String sortedSet,double score, String value);
/**
* 添加緩存(一個)
* @param sortedSet 添加入的集合
* @param score 權(quán)重
* @param value 值
*/
2.jedis.zadd(String sortedSet,Map<String, Double> value2score);
/**
* 添加緩存(一次可添加多個)
* @param sortedSet 添加入的集合
* @param value2score 加入集合的元素集
*/
/***************************獲取緩存*****************************/
3.jedis.zrange(sortedSet,long start, long end);
/**
* 返回sortedSet內(nèi)[start,end]索引的元素set
* 1、在sortedSet中,元素是按照score從小到大排列的,
* 此方法從前向后獲取元素(即按元素的score從小到大排列)
*/
4.zrange(sortedSet, 0, -1);
/**
* 返回sortedSet內(nèi)所有元素,元素按照score從小到大排列
*/
5.jedis.zrevrange(sortedSet,long start, long end);
/**
* 返回sortedSet集合[start, end]中的元素
* 1、此方法相當于從后向前取元素,即元素從大到小排列
* 或者相當于將sortedSet從大到小排列,然后從前向后去元素
*/
6.zrevrange(sortedSet, 0, -1);
/**
* 返回sortedSet內(nèi)所有元素,元素按照score從大到小排列
*/
7.jedis.zrangeByScore(String sortedSet, double minScore, double maxScore);
/**
* 獲取sortedSet內(nèi)[minScore, maxScore]的元素
*/
8. jedis.zrem(String sortedSet, String... values);
/**
* 刪除多個緩存
* @param sortedSet
* @param values
*/
9. jedis.zremrangeByRank(String sortedSet, long start, long end);
/**
* 刪除指定范圍(按照索引,包前包后)的緩存
*/
10. jedis.zremrangeByScore(String sortedSet, double minScore, double maxScore);
/**
* 刪除指定范圍(按照分數(shù),包前包后)的緩存
*/
11.jedis.zcard(String sortedSet);
/**
* 獲取集合sortedSet的長度
*/
12.edis.zscore(sortedSet, value);
/**
* 獲取sortedSet中的value的權(quán)重score
*/
13. jedis.zincrby(String sortedSet,double score, String value);
/**
* 為sortedSet中的value的權(quán)重加上增量score
*/
Hash(hash工具類)
1.jedis.hset(String map, String key, String value);
/**
* 添加單個緩存key-value到map中
*/
2.jedis.hsetnx(String map, String key, String value);
/**
* 添加單個緩存key-value到map中
* 若已經(jīng)存在于指定key相同的key,那么就不操作
*/
3. jedis.hmset(String map, Map<String, String> key2value);
/**
* 在map中添加key2value的map,即一次性添加多條緩存
* @param map
* @param key2value
*/
4.jedis.hkeys(String map);//返回類型Set<String>
/**
* 獲取map中key的集合
* @param set
*/
5.jedis.hvals(String map)//返回類型List<String>
/**
* 獲取map中的所有key的value
*/
6.jedis.hmget(String map, String... keys) //返回類型List<String>
/**
* 從map中獲取多個key的value,并放在List集合中
*/
7.jedis.hgetAll(String map);//返回類型Map<String, String>
/**
* 從map中獲取全部的緩存key-value對
*/
8.jedis.hget(String map, String key);// 返回類型String
/**
* 從map中獲取相應(yīng)key的緩存value
*/
9. jedis.hdel(String map, String... keys);
/**
* 從map中刪除多個緩存
*/
10. jedis.hlen(map);
/**
* 獲取map中的key-value數(shù)
*/
11.jedis.hexists(String map, String key);
/**
* map中是否存在鍵為key的緩存
*/
總結(jié):
list
元素在list中的存放順序為:插入list的順序(從左邊插入在頭部,從右邊插入在尾部)
允許存放重復(fù)元素
可用作模擬隊列(queue)、堆棧(stack),支持雙向操作(L--首部或者R--尾部)
左邊入隊,相當于在隊頭插入元素,則之后的元素都要后移一位;而右邊入隊的話元素直接插在隊尾,之前的元素的索引不變(推薦使用右邊入隊,即隊尾入隊)
set
元素在set中的存放順序為:與插入set的先后書順序無關(guān)(即無序)
不允許存放重復(fù)元素
對于set而言,Jedis有交集、差集、并集運算,可是ShardJedis沒有
soretd set
元素在set中的存放順序為:根據(jù)score(權(quán)重)從小到大排列
不允許存放重復(fù)元素
相同點:
index
從0開始 -1表示結(jié)尾 -2表示倒數(shù)第二個
API中的 start end參數(shù)
都是包前也包后的
按key查找功能
list、set、sorted set沒有按key查找的功能
String、hash具有按key查找value的功能
直接的指定緩存過期的API
String有
list、set、sorted set、hash沒有,但是可以按例如如下的方式指定緩存過期時間
jedis.lpush(list, values);19 jedis.expire(list, expire);//為該list設(shè)置緩存過期時間
刪除整個元素
jedis.del(list):可用于五種結(jié)構(gòu)
二,Redis整理
1.redis是什么?
redis(remote dictionary server):是一個以key-value形式存儲于內(nèi)存中的數(shù)據(jù)庫.提供了 String / List / Set / Sort Set /Hash 五種數(shù)據(jù)結(jié)構(gòu)。服務(wù)器在斷電之后,仍然可以恢復(fù)到斷電之前的狀態(tài)(另外的解釋:集群是一個提供在多個Redis間節(jié)點間共享數(shù)據(jù)的程序集.)
2.redis特點?
線程模型:單線程-多路復(fù)用io模型
性能高:支持讀 11萬/秒 , 寫 8萬/秒
存儲: 內(nèi)存 ; RDB文件(二進制安全的真實數(shù)據(jù)) ; AOF文件(客戶端的命令集合)
事務(wù): 支持事務(wù)(每個客戶端串行執(zhí)行命令,其他客戶端處于阻塞狀態(tài))
3.redis數(shù)據(jù)類型
String:動態(tài)字符串(每個key都是一個String)
編碼方式:int / raw() /embstr
應(yīng)用場景:普通的string場景
List:列表結(jié)構(gòu),有序可重復(fù)的結(jié)構(gòu)。它擁有隊列的特性。
編碼方式:ziplist / linkedlist (如果數(shù)據(jù)量較小,且是數(shù)字或者字符串,則內(nèi)部結(jié)構(gòu)為 ziplist)
應(yīng)用場景:普通的集合數(shù)據(jù)
Set:集合結(jié)構(gòu),不重復(fù)的集合結(jié)構(gòu)。
編碼方式:intset(整數(shù)集合) / hashtable
應(yīng)用場景:普通的非重復(fù)集合數(shù)據(jù);支持取交集、取并集等操作
Sort Set:有序集合結(jié)構(gòu),和Set比較起來,它是有序的。
編碼方式:ziplist / skiplist
應(yīng)用場景:有序不重復(fù)的集合數(shù)據(jù)
Hash:哈希結(jié)構(gòu),存儲多個key:value的結(jié)構(gòu),此種結(jié)構(gòu)可以存儲對象 ; 如 HMSET user(key) username value1 password value2
編碼方式:ziplist / hashtable
應(yīng)用場景: 從關(guān)系型數(shù)據(jù)庫去出一條數(shù)據(jù),就可以讓入到此種結(jié)構(gòu)中
4.內(nèi)存優(yōu)化
redis提供內(nèi)存回收策略,根據(jù)使用的情況可以選擇適當?shù)幕厥詹呗?/p>
redis提供內(nèi)存共享策略,服務(wù)器啟動時,會自動創(chuàng)建0-9999的數(shù)字對象,其他地方使用,可以直接引用。
本質(zhì):對內(nèi)存的操作,其實是在每一個redis對象結(jié)構(gòu)內(nèi)都有一個count的屬性,該屬性記錄了這個對象被引用的次數(shù),如果為0,那么在內(nèi)存回收時將回收該空間。
save參數(shù)調(diào)整:當滿足條件時,觸發(fā)SAVE命令,持久化到RDB文件
appendonly參數(shù): 默認no ,若yes,則開啟AOF文件持久化; BGREWRITEAOF 命令 持久化。其中appendsync參數(shù)調(diào)整具體的持久化策略,默認為每秒
5.事務(wù)
單線程處理所有客戶端發(fā)來的請求,所以當有一個客戶端在執(zhí)行,其他客戶端只能處于阻塞態(tài)。只有當前客戶端請求完畢,其他客戶端才能請求
6.主從復(fù)制
功能:數(shù)據(jù)備份,讀寫分離(測試環(huán)境,主服務(wù)器寫,從服務(wù)器讀)
步驟:在從服務(wù)端器執(zhí)行: slaveof <masterip> <masterport> 即可維持關(guān)系;配置文件中也可以
特點:
1.master可以有多個slave
2.除了多個slave連到相同的master外,slave也可以連接其他slave形成圖狀結(jié)構(gòu)
3.主從復(fù)制不會阻塞master。也就是說當一個或多個slave與master進行初次同步數(shù)據(jù)時,master可以繼續(xù)處理client發(fā)來的請求。相反slave在初次同步數(shù)據(jù)時則會阻塞不能處理client的請求。
4.主從復(fù)制可以用來提高系統(tǒng)的可伸縮性,我們可以用多個slave 專門用于client的讀請求,比如sort操作可以使用slave來處理。也可以用來做簡單的數(shù)據(jù)冗余
5.可以在master禁用數(shù)據(jù)持久化,只需要注釋掉master 配置文件中的所有save配置,然后只在slave上配置數(shù)據(jù)持久化。
6.主服務(wù)器可以關(guān)閉持久化功能(注釋掉save參數(shù))
7.sentinel(監(jiān)測系統(tǒng))
本質(zhì):是一個運行在特殊模式下的redis服務(wù)器。
功能:監(jiān)控運行在多機上的主redis服務(wù)器,若有某一臺主服務(wù)器出現(xiàn)故障,將自動把其他正常的從服務(wù)器切換為主服務(wù)器,代替出現(xiàn)故障主服務(wù)器的工作。
特點:
1.不發(fā)揮數(shù)據(jù)庫的功能(所有對key以及數(shù)據(jù)類型操作的命令不能使用)
2.將會給監(jiān)控的主服務(wù)器以及主服務(wù)器所屬的從服務(wù)器發(fā)送命令,確認是否下線
3.會和監(jiān)控同一個主服務(wù)器的其他sentinel服務(wù)器通信,作用是在共同判斷所監(jiān)控的主服務(wù)器的狀態(tài)
4.根據(jù)多個sentinel判斷的主服務(wù)器狀態(tài),來決定是否要進行主從切換,故障轉(zhuǎn)移等
轉(zhuǎn)移:sentinel監(jiān)控的主服務(wù)器配置參數(shù)要在 sentinel.conf 文件中配置,啟動時加載
8.集群
功能:將眾多的key-value集合存在多個節(jié)點上,當某一個節(jié)點出現(xiàn)障礙,不影響整個集群的功能。
涉及到的關(guān)鍵詞:
節(jié)點:一個端口的redis服務(wù)便是一個節(jié)點
槽指派(集群將整個系統(tǒng)分為16384個hash槽):這16384個槽位要全部分布在集群中的主節(jié)點上。
重新分片:若某個主節(jié)點故障了,將該主節(jié)點的槽位分配到其他可以用的主節(jié)點上。
上線/下線狀態(tài): 是否全部的槽位都分布在節(jié)點上。
特點:
1.如果某個節(jié)點要集群,必須要設(shè)置cluster-enabled yes
2.每個節(jié)點都有這16384個槽位所屬的節(jié)點信息,如果值沒有正確進入槽位,那么該節(jié)點會提示系統(tǒng)將信息放入正確槽位。重定向的過程會出現(xiàn)一個面向客戶端隱藏的MOVED錯誤
3.集群在線狀態(tài)也可以進行重新分片
4.集群中的主節(jié)點用戶處理客戶端命令,從節(jié)點用于復(fù)制主節(jié)點的數(shù)據(jù),主節(jié)點下線時,從節(jié)點代替主節(jié)點的工作
//注意:目前官方提供的集群功能仍處于內(nèi)測版本。
9.redis基準
redis自帶的redis-benchmark 工具,支持各種參數(shù)進行性能測試
特點:
1.可以模擬多個客戶端處理任意個請求
2.可以測試僅僅少數(shù)使用的命令等
注意:測試發(fā)現(xiàn),linux環(huán)境下部署的redis服務(wù)器性能遠高于windows下部署的redis服務(wù)器性能, 不在一個層級上面
10.關(guān)系數(shù)據(jù)庫模型的轉(zhuǎn)換
關(guān)系型數(shù)據(jù)庫表結(jié)構(gòu):user表 (uid username password birthday )
在redis中可以這樣存在:
1.主鍵: SET user:uid 1 、 GET user:1
2.其他字段:SET user:uid:username GET user:5:username ( 5 是通過參數(shù)值傳進來的)
3.表數(shù)據(jù)也可以存在hash結(jié)構(gòu)中: HMSET user:uid username value1 password value2 birthday value3
11.管道
功能:客戶端一次可以傳送多個命令到服務(wù)器,減少往返時延。大大提高性能。
12.優(yōu)化
redis提供一些簡單的內(nèi)存優(yōu)化策略,如過期數(shù)據(jù)清除,內(nèi)存數(shù)據(jù)共享。