Redis 單點模式和叢集模式程式碼測試及問題記錄
阿新 • • 發佈:2018-12-25
前言:Redis的測試有一些講究,如果你是先安裝叢集再來測試會出現很多意想不到的問題。單個redis-server測試很簡單 就是照著API搞就行,但是如果是先搭建叢集環境而使用叢集節點(單個IP和埠)來操作就不適用了。叢集的特點就是分擔服務端的壓力,此時採用Redis一般的操作API就不適用了,因為叢集節點會發生轉移(MOVED)到另一個節點上去,所以API操作要對應模式——叢集應當使用與cluster API進行操作。Redis訪問是建立的c/s模式的socket連線,所以不同的節點要麼主機(Host)IP不同要麼埠(port)不同,redis以此繫結(bind)IP和port (ip:port)。
1.單點模式RedisServer操作示例
1.1普通操作驗證:
Connection
package com.boonya.redis.samles; import redis.clients.jedis.Jedis; public class RedisTest { public static void main(String[] args) { //Connecting to Redis server on 192.168.28.194 Jedis jedis = new Jedis("192.168.28.194",6379,1000); System.out.println("Connection to server sucessfully"); //check whether server is running or not System.out.println("Server is running: "+jedis.ping()); jedis.quit(); jedis.disconnect(); } }
Key
package com.boonya.redis.samles; import java.util.Iterator; import java.util.Set; import redis.clients.jedis.Jedis; public class RedisKeyTest { public static void main(String[] args) { // Connecting to Redis server on 192.168.28.194 Jedis jedis = new Jedis("192.168.28.194",6379,1000); System.out.println("Connection to server sucessfully"); // store data in redis list // Get the stored data and print it Set<String> set = jedis.keys("*"); Iterator<String> it=set.iterator(); while (it.hasNext()) { String key = it.next(); System.out.println("List of stored keys:: " + key); } System.out.println("It's ready to work."); jedis.quit(); jedis.disconnect(); } }
List
package com.boonya.redis.samles;
import java.util.List;
import redis.clients.jedis.Jedis;
public class RedisListTest {
public static void main(String[] args) {
// Connecting to Redis server on 192.168.28.194
Jedis jedis = new Jedis("192.168.28.194",6379,1000);
System.out.println("Connection to server sucessfully");
// store data in redis list
jedis.lpush("tutorial-list", "Redis");
jedis.lpush("tutorial-list", "Mongodb");
jedis.lpush("tutorial-list", "Mysql");
// Get the stored data and print it
List<String> list = jedis.lrange("tutorial-list", 0, 5);
for (int i = 0; i < list.size(); i++) {
System.out.println("Stored string in redis:: " + list.get(i));
}
System.out.println("It's ready to work.");
jedis.quit();
jedis.disconnect();
}
}
String
package com.boonya.redis.samles;
import redis.clients.jedis.Jedis;
public class RedisStringTest {
public static void main(String[] args) {
// Connecting to Redis server on 192.168.28.194
Jedis jedis = new Jedis("192.168.28.194", 6379, 1000);
System.out.println("Connection to server sucessfully");
// set the data in redis string
jedis.set("tutorial-name", "Redis tutorial");
// Get the stored data and print it
System.out.println("Stored string in redis:: "
+ jedis.get("tutorial-name"));
jedis.quit();
jedis.disconnect();
}
}
Server/client
package com.boonya.redis.samles;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
public class RedisServerTest {
private Jedis jedis;
@Before
public void testBeforeClass(){
jedis = new Jedis("192.168.28.194",6379,1000);
jedis.clientSetname("boonya-pc");
jedis.flushAll();
}
@After
public void release(){
jedis.quit();
jedis.disconnect();
}
@Test
public void testKillClient(){
String clientGetname=jedis.clientGetname();
System.out.println("clientGetname="+clientGetname);
String clientList=jedis.clientList();
System.out.println("clientList="+clientList);
}
}
1.2客戶端測試示例一:
package com.boonya.redis.singlenode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.Transaction;
public class RedisClient {
private String host="192.168.28.194";
private Jedis jedis;// 非切片額客戶端連線
private JedisPool jedisPool;// 非切片連線池
private ShardedJedis shardedJedis;// 切片額客戶端連線
private ShardedJedisPool shardedJedisPool;// 切片連線池
private ShardedJedis sharded;
public RedisClient() {
initialPool();
initialShardedPool();
shardedJedis = shardedJedisPool.getResource();
jedis = jedisPool.getResource();
System.out.println("initial completed!");
}
/**
* 初始化非切片池
*/
private void initialPool() {
// 池基本配置
JedisPoolConfig config = new JedisPoolConfig();
// config.setMaxActive(20);
config.setMaxIdle(5);
// config.setMaxWait(1000l);
config.setMaxWaitMillis(1000);
config.setTestOnBorrow(false);
jedisPool = new JedisPool(config, host, 6379);
}
/**
* 初始化切片池
*/
private void initialShardedPool() {
// 池基本配置
JedisPoolConfig config = new JedisPoolConfig();
// config.setMaxActive(20);
config.setMaxIdle(5);
// /config.setMaxWait(1000l);
config.setMaxWaitMillis(1000);
config.setTestOnBorrow(false);
// slave連結
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shards.add(new JedisShardInfo(host, 6379, "master"));
// socket模式測試物件初始化
sharded=new ShardedJedis(shards);
// 構造池
shardedJedisPool = new ShardedJedisPool(config, shards);
}
private void KeyOperate() {
System.out
.println("======================key==========================");
// 清空資料
System.out.println("清空庫中所有資料:" + jedis.flushDB());
// 判斷key否存在
System.out.println("判斷key999鍵是否存在:" + shardedJedis.exists("key999"));
System.out.println("新增key001,value001鍵值對:"
+ shardedJedis.set("key001", "value001"));
System.out.println("判斷key001是否存在:" + shardedJedis.exists("key001"));
// 輸出系統中所有的key
System.out.println("新增key002,value002鍵值對:"
+ shardedJedis.set("key002", "value002"));
System.out.println("系統中所有鍵如下:");
Set<String> keys = jedis.keys("*");
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String key = it.next();
System.out.println(key);
}
// 刪除某個key,若key不存在,則忽略該命令。
System.out.println("系統中刪除key002: " + jedis.del("key002"));
System.out.println("判斷key002是否存在:" + shardedJedis.exists("key002"));
// 設定 key001的過期時間
System.out.println("設定 key001的過期時間為5秒:" + jedis.expire("key001", 5));
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
// 檢視某個key的剩餘生存時間,單位【秒】.永久生存或者不存在的都返回-1
System.out.println("檢視key001的剩餘生存時間:" + jedis.ttl("key001"));
// 移除某個key的生存時間
System.out.println("移除key001的生存時間:" + jedis.persist("key001"));
System.out.println("檢視key001的剩餘生存時間:" + jedis.ttl("key001"));
// 檢視key所儲存的值的型別
System.out.println("檢視key所儲存的值的型別:" + jedis.type("key001"));
/*
* 一些其他方法:1、修改鍵名:jedis.rename("key6", "key0");
* 2、將當前db的key移動到給定的db當中:jedis.move("foo", 1)
*/
}
private void StringOperate() {
System.out
.println("======================String_1==========================");
// 清空資料
System.out.println("清空庫中所有資料:" + jedis.flushDB());
System.out.println("=============增=============");
jedis.set("key001", "value001");
jedis.set("key002", "value002");
jedis.set("key003", "value003");
System.out.println("已新增的3個鍵值對如下:");
System.out.println(jedis.get("key001"));
System.out.println(jedis.get("key002"));
System.out.println(jedis.get("key003"));
System.out.println("=============刪=============");
System.out.println("刪除key003鍵值對:" + jedis.del("key003"));
System.out.println("獲取key003鍵對應的值:" + jedis.get("key003"));
System.out.println("=============改=============");
// 1、直接覆蓋原來的資料
System.out.println("直接覆蓋key001原來的資料:"
+ jedis.set("key001", "value001-update"));
System.out.println("獲取key001對應的新值:" + jedis.get("key001"));
// 2、直接覆蓋原來的資料
System.out.println("在key002原來值後面追加:"
+ jedis.append("key002", "+appendString"));
System.out.println("獲取key002對應的新值" + jedis.get("key002"));
System.out.println("=============增,刪,查(多個)=============");
/**
* mset,mget同時新增,修改,查詢多個鍵值對 等價於: jedis.set("name","ssss");
* jedis.set("jarorwar","xxxx");
*/
System.out.println("一次性新增key201,key202,key203,key204及其對應值:"
+ jedis.mset("key201", "value201", "key202", "value202",
"key203", "value203", "key204", "value204"));
System.out.println("一次性獲取key201,key202,key203,key204各自對應的值:"
+ jedis.mget("key201", "key202", "key203", "key204"));
System.out.println("一次性刪除key201,key202:"
+ jedis.del(new String[] { "key201", "key202" }));
System.out.println("一次性獲取key201,key202,key203,key204各自對應的值:"
+ jedis.mget("key201", "key202", "key203", "key204"));
System.out.println();
// jedis具備的功能shardedJedis中也可直接使用,下面測試一些前面沒用過的方法
System.out
.println("======================String_2==========================");
// 清空資料
System.out.println("清空庫中所有資料:" + jedis.flushDB());
System.out.println("=============新增鍵值對時防止覆蓋原先值=============");
System.out.println("原先key301不存在時,新增key301:"
+ shardedJedis.setnx("key301", "value301"));
System.out.println("原先key302不存在時,新增key302:"
+ shardedJedis.setnx("key302", "value302"));
System.out.println("當key302存在時,嘗試新增key302:"
+ shardedJedis.setnx("key302", "value302_new"));
System.out.println("獲取key301對應的值:" + shardedJedis.get("key301"));
System.out.println("獲取key302對應的值:" + shardedJedis.get("key302"));
System.out.println("=============超過有效期鍵值對被刪除=============");
// 設定key的有效期,並存儲資料
System.out.println("新增key303,並指定過期時間為2秒"
+ shardedJedis.setex("key303", 2, "key303-2second"));
System.out.println("獲取key303對應的值:" + shardedJedis.get("key303"));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("3秒之後,獲取key303對應的值:" + shardedJedis.get("key303"));
System.out.println("=============獲取原值,更新為新值一步完成=============");
System.out.println("key302原值:"
+ shardedJedis.getSet("key302", "value302-after-getset"));
System.out.println("key302新值:" + shardedJedis.get("key302"));
System.out.println("=============獲取子串=============");
System.out.println("獲取key302對應值中的子串:"
+ shardedJedis.getrange("key302", 5, 7));
}
private void ListOperate() {
System.out
.println("======================list==========================");
// 清空資料
System.out.println("清空庫中所有資料:" + jedis.flushDB());
System.out.println("=============增=============");
shardedJedis.lpush("stringlists", "vector");
shardedJedis.lpush("stringlists", "ArrayList");
shardedJedis.lpush("stringlists", "vector");
shardedJedis.lpush("stringlists", "vector");
shardedJedis.lpush("stringlists", "LinkedList");
shardedJedis.lpush("stringlists", "MapList");
shardedJedis.lpush("stringlists", "SerialList");
shardedJedis.lpush("stringlists", "HashList");
shardedJedis.lpush("numberlists", "3");
shardedJedis.lpush("numberlists", "1");
shardedJedis.lpush("numberlists", "5");
shardedJedis.lpush("numberlists", "2");
System.out.println("所有元素-stringlists:"
+ shardedJedis.lrange("stringlists", 0, -1));
System.out.println("所有元素-numberlists:"
+ shardedJedis.lrange("numberlists", 0, -1));
System.out.println("=============刪=============");
// 刪除列表指定的值 ,第二個引數為刪除的個數(有重複時),後add進去的值先被刪,類似於出棧
System.out.println("成功刪除指定元素個數-stringlists:"
+ shardedJedis.lrem("stringlists", 2, "vector"));
System.out.println("刪除指定元素之後-stringlists:"
+ shardedJedis.lrange("stringlists", 0, -1));
// 刪除區間以外的資料
System.out.println("刪除下標0-3區間之外的元素:"
+ shardedJedis.ltrim("stringlists", 0, 3));
System.out.println("刪除指定區間之外元素後-stringlists:"
+ shardedJedis.lrange("stringlists", 0, -1));
// 列表元素出棧
System.out.println("出棧元素:" + shardedJedis.lpop("stringlists"));
System.out.println("元素出棧後-stringlists:"
+ shardedJedis.lrange("stringlists", 0, -1));
System.out.println("=============改=============");
// 修改列表中指定下標的值
shardedJedis.lset("stringlists", 0, "hello list!");
System.out.println("下標為0的值修改後-stringlists:"
+ shardedJedis.lrange("stringlists", 0, -1));
System.out.println("=============查=============");
// 陣列長度
System.out
.println("長度-stringlists:" + shardedJedis.llen("stringlists"));
System.out
.println("長度-numberlists:" + shardedJedis.llen("numberlists"));
// 排序
/*
* list中存字串時必須指定引數為alpha,如果不使用SortingParams,而是直接使用sort("list"),
* 會出現"ERR One or more scores can't be converted into double"
*/
SortingParams sortingParameters = new SortingParams();
sortingParameters.alpha();
sortingParameters.limit(0, 3);
System.out.println("返回排序後的結果-stringlists:"
+ shardedJedis.sort("stringlists", sortingParameters));
System.out.println("返回排序後的結果-numberlists:"
+ shardedJedis.sort("numberlists"));
// 子串: start為元素下標,end也為元素下標;-1代表倒數一個元素,-2代表倒數第二個元素
System.out.println("子串-第二個開始到結束:"
+ shardedJedis.lrange("stringlists", 1, -1));
// 獲取列表指定下標的值
System.out.println("獲取下標為2的元素:" + shardedJedis.lindex("stringlists", 2)
+ "\n");
}
private void SetOperate() {
System.out
.println("======================set==========================");
// 清空資料
System.out.println("清空庫中所有資料:" + jedis.flushDB());
System.out.println("=============增=============");
System.out.println("向sets集合中加入元素element001:"
+ jedis.sadd("sets", "element001"));
System.out.println("向sets集合中加入元素element002:"
+ jedis.sadd("sets", "element002"));
System.out.println("向sets集合中加入元素element003:"
+ jedis.sadd("sets", "element003"));
System.out.println("向sets集合中加入元素element004:"
+ jedis.sadd("sets", "element004"));
System.out.println("檢視sets集合中的所有元素:" + jedis.smembers("sets"));
System.out.println();
System.out.println("=============刪=============");
System.out.println("集合sets中刪除元素element003:"
+ jedis.srem("sets", "element003"));
System.out.println("檢視sets集合中的所有元素:" + jedis.smembers("sets"));
/*
* System.out.println("sets集合中任意位置的元素出棧:"+jedis.spop("sets"));//注:出棧元素位置居然不定
* ?--無實際意義
* System.out.println("檢視sets集合中的所有元素:"+jedis.smembers("sets"));
*/
System.out.println();
System.out.println("=============改=============");
System.out.println();
System.out.println("=============查=============");
System.out.println("判斷element001是否在集合sets中:"
+ jedis.sismember("sets", "element001"));
System.out.println("迴圈查詢獲取sets中的每個元素:");
Set<String> set = jedis.smembers("sets");
Iterator<String> it = set.iterator();
while (it.hasNext()) {
Object obj = it.next();
System.out.println(obj);
}
System.out.println();
System.out.println("=============集合運算=============");
System.out.println("sets1中新增元素element001:"
+ jedis.sadd("sets1", "element001"));
System.out.println("sets1中新增元素element002:"
+ jedis.sadd("sets1", "element002"));
System.out.println("sets1中新增元素element003:"
+ jedis.sadd("sets1", "element003"));
System.out.println("sets1中新增元素element002:"
+ jedis.sadd("sets2", "element002"));
System.out.println("sets1中新增元素element003:"
+ jedis.sadd("sets2", "element003"));
System.out.println("sets1中新增元素element004:"
+ jedis.sadd("sets2", "element004"));
System.out.println("檢視sets1集合中的所有元素:" + jedis.smembers("sets1"));
System.out.println("檢視sets2集合中的所有元素:" + jedis.smembers("sets2"));
System.out.println("sets1和sets2交集:" + jedis.sinter("sets1", "sets2"));
System.out.println("sets1和sets2並集:" + jedis.sunion("sets1", "sets2"));
System.out.println("sets1和sets2差集:" + jedis.sdiff("sets1", "sets2"));// 差集:set1中有,set2中沒有的元素
}
private void SortedSetOperate() {
System.out
.println("======================zset==========================");
// 清空資料
System.out.println(jedis.flushDB());
System.out.println("=============增=============");
System.out.println("zset中新增元素element001:"
+ shardedJedis.zadd("zset", 7.0, "element001"));
System.out.println("zset中新增元素element002:"
+ shardedJedis.zadd("zset", 8.0, "element002"));
System.out.println("zset中新增元素element003:"
+ shardedJedis.zadd("zset", 2.0, "element003"));
System.out.println("zset中新增元素element004:"
+ shardedJedis.zadd("zset", 3.0, "element004"));
System.out
.println("zset集合中的所有元素:" + shardedJedis.zrange("zset", 0, -1));// 按照權重值排序
System.out.println();
System.out.println("=============刪=============");
System.out.println("zset中刪除元素element002:"
+ shardedJedis.zrem("zset", "element002"));
System.out
.println("zset集合中的所有元素:" + shardedJedis.zrange("zset", 0, -1));
System.out.println();
System.out.println("=============改=============");
System.out.println();
System.out.println("=============查=============");
System.out.println("統計zset集合中的元素中個數:" + shardedJedis.zcard("zset"));
System.out.println("統計zset集合中權重某個範圍內(1.0——5.0),元素的個數:"
+ shardedJedis.zcount("zset", 1.0, 5.0));
System.out.println("檢視zset集合中element004的權重:"
+ shardedJedis.zscore("zset", "element004"));
System.out.println("檢視下標1到2範圍內的元素值:"
+ shardedJedis.zrange("zset", 1, 2));
}
private void HashOperate() {
System.out
.println("======================hash==========================");
// 清空資料
System.out.println(jedis.flushDB());
System.out.println("=============增=============");
System.out.println("hashs中新增key001和value001鍵值對:"
+ shardedJedis.hset("hashs", "key001", "value001"));
System.out.println("hashs中新增key002和value002鍵值對:"
+ shardedJedis.hset("hashs", "key002", "value002"));
System.out.println("hashs中新增key003和value003鍵值對:"
+ shardedJedis.hset("hashs", "key003", "value003"));
System.out.println("新增key004和4的整型鍵值對:"
+ shardedJedis.hincrBy("hashs", "key004", 4l));
System.out.println("hashs中的所有值:" + shardedJedis.hvals("hashs"));
System.out.println();
System.out.println("=============刪=============");
System.out.println("hashs中刪除key002鍵值對:"
+ shardedJedis.hdel("hashs", "key002"));
System.out.println("hashs中的所有值:" + shardedJedis.hvals("hashs"));
System.out.println();
System.out.println("=============改=============");
System.out.println("key004整型鍵值的值增加100:"
+ shardedJedis.hincrBy("hashs", "key004", 100l));
System.out.println("hashs中的所有值:" + shardedJedis.hvals("hashs"));
System.out.println();
System.out.println("=============查=============");
System.out.println("判斷key003是否存在:"
+ shardedJedis.hexists("hashs", "key003"));
System.out.println("獲取key004對應的值:"
+ shardedJedis.hget("hashs", "key004"));
System.out.println("批量獲取key001和key003對應的值:"
+ shardedJedis.hmget("hashs", "key001", "key003"));
System.out.println("獲取hashs中所有的key:" + shardedJedis.hkeys("hashs"));
System.out.println("獲取hashs中所有的value:" + shardedJedis.hvals("hashs"));
System.out.println();
}
private void simpleSetGet() {
jedis.set("key001", "value001");
jedis.set("key002", "value002");
jedis.set("key003", "value003");
System.out.println("已新增的3個鍵值對如下:");
System.out.println(jedis.get("key001"));
System.out.println(jedis.get("key002"));
System.out.println(jedis.get("key003"));
}
@SuppressWarnings("deprecation")
public void show() {
simpleSetGet();
KeyOperate();
StringOperate();
ListOperate();
SetOperate();
SortedSetOperate();
HashOperate();
jedisPool.returnResource(jedis);
shardedJedisPool.returnResource(shardedJedis);
}
/************************************Socket模式連線測試******************開始**************/
private void test1Normal() {
// 設定值
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
jedis.set("k" + i, "v" + i);
}
long end = System.currentTimeMillis();
System.out.println("Simple SET: " + ((end - start) / 1000.0)
+ " seconds");
// 獲取值
for (int i = 0; i < 10; i++) {
String result = jedis.get("n" + i);
System.out.println("Simple GET: " + "k" + i + "=" + result);
}
}
private void test2Trans() {
long start = System.currentTimeMillis();
Transaction tx = jedis.multi();
for (int i = 0; i < 10; i++) {
tx.set("t" + i, "t" + i);
}
// System.out.println(tx.get("t1000").get());
@SuppressWarnings("unused")
List<Object> results = tx.exec();
long end = System.currentTimeMillis();
System.out.println("Transaction SET: " + ((end - start) / 1000.0)
+ " seconds");
}
private void test3Pipelined() {
Pipeline pipeline = jedis.pipelined();
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
pipeline.set("p" + i, "p" + i);
}
// System.out.println(pipeline.get("p1000").get());
@SuppressWarnings("unused")
List<Object> results = pipeline.syncAndReturnAll();
long end = System.currentTimeMillis();
System.out.println("Pipelined SET: " + ((end - start) / 1000.0)
+ " seconds");
}
private void test4combPipelineTrans() {
long start = System.currentTimeMillis();
Pipeline pipeline = jedis.pipelined();
pipeline.multi();
for (int i = 0; i < 10; i++) {
pipeline.set("" + i, "" + i);
}
pipeline.exec();
@SuppressWarnings("unused")
List<Object> results = pipeline.syncAndReturnAll();
long end = System.currentTimeMillis();
System.out.println("Pipelined transaction: " + ((end - start) / 1000.0)
+ " seconds");
}
@SuppressWarnings("unused")
private void test5shardNormal() {
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
String result = sharded.set("sn" + i, "n" + i);
}
long end = System.currentTimeMillis();
System.out.println("[email protected] SET: " + ((end - start) / 1000.0)
+ " seconds");
}
@SuppressWarnings("unused")
private void test6shardpipelined() {
ShardedJedisPipeline pipeline = sharded.pipelined();
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
pipeline.set("sp" + i, "p" + i);
}
List<Object> results = pipeline.syncAndReturnAll();
long end = System.currentTimeMillis();
System.out.println("[email protected] SET: " + ((end - start) / 1000.0)
+ " seconds");
}
@SuppressWarnings("deprecation")
private void test7shardSimplePool() {
ShardedJedis one = shardedJedisPool.getResource();
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
@SuppressWarnings("unused")
String result = one.set("spn" + i, "n" + i);
}
long end = System.currentTimeMillis();
shardedJedisPool.returnResource(one);
System.out.println("[email protected] SET: " + ((end - start) / 1000.0)
+ " seconds");
}
@SuppressWarnings("deprecation")
private void test8shardPipelinedPool() {
ShardedJedis one = shardedJedisPool.getResource();
ShardedJedisPipeline pipeline = one.pipelined();
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
pipeline.set("sppn" + i, "n" + i);
}
@SuppressWarnings("unused")
List<Object> results = pipeline.syncAndReturnAll();
long end = System.currentTimeMillis();
shardedJedisPool.returnResource(one);
System.out.println("[email protected] SET: " + ((end - start) / 1000.0)
+ " seconds");
}
public void testSockets(){
test1Normal();
test2Trans();
test3Pipelined();
test4combPipelineTrans();
test5shardNormal();
test6shardpipelined();
test7shardSimplePool();
test8shardPipelinedPool();
}
/************************************Socket模式連線測試******************結束**************/
public static void main(String[] args) {
RedisClient client = new RedisClient();
client.show();
client.testSockets();
}
}
1.3客戶端測試示例二:
Test
package com.boonya.redis.singlenode;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import com.boonya.redis.util.RedisPoolUtil;
import redis.clients.jedis.Jedis;
public class RedisTest {
private Jedis jedis;
@Before
public void setup() {
// 連線redis伺服器,192.168.28.194:6379
jedis = new Jedis("192.168.28.194", 6379,1000);
// 許可權認證
// jedis.auth("boonya");
}
@Test
public void testStringSetAndGet() {
jedis.set("name", "boonya");
System.out.println("name=" + jedis.get("name"));
}
/**
* redis儲存字串
*/
@Test
public void testString() {
// -----新增資料----------
jedis.set("name", "niuniu");
System.out.println(jedis.get("name"));
jedis.append("name", " is my lover"); // 拼接
System.out.println(jedis.get("name"));
jedis.del("name"); // 刪除某個鍵
System.out.println(jedis.get("name"));
// 設定多個鍵值對
jedis.mset("name", "boonya", "age", "23", "qq", "476777XXX");
jedis.incr("age"); // 進行加1操作
System.out.println(jedis.get("name") + "-" + jedis.get("age") + "-"
+ jedis.get("qq"));
}
/**
* redis操作Map
*/
@Test
public void testMap() {
// -----新增資料----------
Map<String, String> map = new HashMap<String, String>();
map.put("name", "niuniu");
map.put("age", "22");
map.put("qq", "123456");
jedis.hmset("user", map);
// 取出user中的name,執行結果:[minxr]-->注意結果是一個泛型的List
// 第一個引數是存入redis中map物件的key,後面跟的是放入map中的物件的key,後面的key可以跟多個,是可變引數
List<String> rsmap = jedis.hmget("user", "name", "age", "qq");
System.out.println(rsmap);
// 刪除map中的某個鍵值
jedis.hdel("user", "age");
System.out.println(jedis.hmget("user", "age")); // 因為刪除了,所以返回的是null
System.out.println(jedis.hlen("user")); // 返回key為user的鍵中存放的值的個數2
System.out.println(jedis.exists("user"));// 是否存在key為user的記錄 返回true
System.out.println(jedis.hkeys("user"));// 返回map物件中的所有key
System.out.println(jedis.hvals("user"));// 返回map物件中的所有value
Iterator<String> iter = jedis.hkeys("user").iterator();
while (iter.hasNext()) {
String key = iter.next();
System.out.println(key + ":" + jedis.hmget("user", key));
}
}
/**
* jedis操作List
*/
@Test
public void testList() {
// 開始前,先移除所有的內容
jedis.del("java framework");
System.out.println(jedis.lrange("java framework", 0, -1));
// 先向key java framework中存放三條資料
jedis.lpush("java framework", "spring");
jedis.lpush("java framework", "struts");
jedis.lpush("java framework", "hibernate");
// 再取出所有資料jedis.lrange是按範圍取出,
// 第一個是key,第二個是起始位置,第三個是結束位置,jedis.llen獲取長度 -1表示取得所有
System.out.println(jedis.lrange("java framework", 0, -1));
jedis.del("java framework");
jedis.rpush("java framework", "spring");
jedis.rpush("java framework", "struts");
jedis.rpush("java framework", "hibernate");
System.out.println(jedis.lrange("java framework", 0, -1));
}
/**
* jedis操作Set
*/
@Test
public void testSet() {
// 新增
jedis.sadd("user", "boonya");
jedis.sadd("user", "niuniu");
jedis.sadd("user", "ling");
jedis.sadd("user", "guoniuniu");
jedis.sadd("user", "who");
// 移除noname
jedis.srem("user", "who");
System.out.println(jedis.smembers("user"));// 獲取所有加入的value
System.out.println(jedis.sismember("user", "who"));// 判斷 who
// 是否是user集合的元素
System.out.println(jedis.srandmember("user"));
System.out.println(jedis.scard("user"));// 返回集合的元素個數
}
@Test
public void test() throws InterruptedException {
// jedis 排序
// 注意,此處的rpush和lpush是List的操作。是一個雙向連結串列(但從表現來看的)
jedis.del("a");// 先清除資料,再加入資料進行測試
jedis.rpush("a", "1");
jedis.lpush("a", "6");
jedis.lpush("a", "3");
jedis.lpush("a", "9");
System.out.println(jedis.lrange("a", 0, -1));// [9, 3, 6, 1]
System.out.println(jedis.sort("a")); // [1, 3, 6, 9] //輸入排序後結果
System.out.println(jedis.lrange("a", 0, -1));
}
@Test
public void testRedisPool() {
RedisPoolUtil.getJedis().set("username", "boonya");
System.out.println(RedisUtil.getJedis().get("username"));
}
}
RedisPoolUtil
package com.boonya.redis.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @packge com.boonya.redis.util.RedisUtil
* @date 2015年10月27日 下午2:13:12
* @author wlyd
* @comment Redis工具類
* @update
*/
public class RedisPoolUtil {
//Redis伺服器IP
private static String ADDR = "192.168.28.194";
//Redis的埠號(用於單個redis節點而非叢集模式)
private static int PORT = 6379;
//訪問密碼,Redis預設沒有密碼
private static String AUTH = "";
//可用連線例項的最大數目,預設值為8;
//如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis例項,則此時pool的狀態為exhausted(耗盡)。
private static int MAX_ACTIVE = 1024;
//控制一個pool最多有多少個狀態為idle(空閒的)的jedis例項,預設值也是8。
private static int MAX_IDLE = 200;
//等待可用連線的最大時間,單位毫秒,預設值為-1,表示永不超時。如果超過等待時間,則直接丟擲JedisConnectionException;
private static int MAX_WAIT = 10000;
private static int TIMEOUT = 10000;
//在borrow一個jedis例項時,是否提前進行validate操作;如果為true,則得到的jedis例項均是可用的;
private static boolean TEST_ON_BORROW = true;
private static JedisPool jedisPool = null;
/**
* 初始化Redis連線池
*/
static {
try {
JedisPoolConfig config = new JedisPoolConfig();
//config.setMaxActive(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
//config.setMaxWait(MAX_WAIT);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT);//, AUTH);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲取Jedis例項
* @return
*/
public synchronized static Jedis getJedis() {
try {
if (jedisPool != null) {
Jedis resource = jedisPool.getResource();
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 釋放jedis資源
* @param jedis
*/
@SuppressWarnings("deprecation")
public static void returnResource(final Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}
}
2.叢集模式操作示例
package com.boonya.redis.cluster;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import junit.framework.TestCase;
/**
*
* @packge com.boonya.redis.RedisClusterTest
* @date 2015年10月21日 下午2:31:38
* @author pengjunlin
* @comment jedis客戶端的坑.
1)cluster環境下redis的slave不接受任何讀寫操作,
2)client端不支援keys批量操作,不支援select dbNum操作,只有一個db:select 0
3)JedisCluster 的info()等單機函式無法呼叫,返回(No way to dispatch this command to Redis Cluster)錯誤,.
* @update
* @from http://blog.csdn.net/myrainblues/article/details/25881535
*/
public class ClusterTest extends TestCase {
private static String host="192.168.28.194";
private static JedisCluster cluster;
static {
// 只給叢集裡一個例項就可以
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
jedisClusterNodes.add(new HostAndPort(host, 7000));
jedisClusterNodes.add(new HostAndPort(host, 7001));
jedisClusterNodes.add(new HostAndPort(host, 7002));
jedisClusterNodes.add(new HostAndPort(host, 7003));
jedisClusterNodes.add(new HostAndPort(host, 7004));
jedisClusterNodes.add(new HostAndPort(host, 7005));
cluster = new JedisCluster(jedisClusterNodes);
}
@Test
public void testSetString(){
cluster.set("username", "boonya");
System.out.println("set username "+cluster.get("username"));
}
@Test
public void testAppendString(){
cluster.append("username", " peng");
System.out.println("append username "+cluster.get("username"));
}
@Test
public void testDelString(){
cluster.set("username", "boonya xnn");
System.out.println("del-get username "+cluster.get("username"));
cluster.del("username");
System.out.println("del-did username "+cluster.get("username"));
}
@Test
public void testMap(){
// -----新增資料----------
Map<String, String> map = new HashMap<String, String>();
map.put("name", "boonya");
map.put("age", "88");
map.put("qq", "123456");
cluster.hmset("user", map);
// 第一個引數是存入redis中map物件的key,後面跟的是放入map中的物件的key,後面的key可以跟多個,是可變引數
List<String> rsmap = cluster.hmget("user", "name", "age", "qq");
System.out.println(rsmap);
// 刪除map中的某個鍵值
cluster.hdel("user", "age");
System.out.println(cluster.hmget("user", "age")); // 因為刪除了,所以返回的是null
System.out.println(cluster.hlen("user")); // 返回key為user的鍵中存放的值的個數2
System.out.println(cluster.exists("user"));// 是否存在key為user的記錄 返回true
System.out.println(cluster.hkeys("user"));// 返回map物件中的所有key
System.out.println(cluster.hvals("user"));// 返回map物件中的所有value
Iterator<String> iter = cluster.hkeys("user").iterator();
while (iter.hasNext()) {
String key = iter.next();
System.out.println(key + ":" + cluster.hmget("user", key));
}
}
@Test
public void testList() {
// 開始前,先移除所有的內容
cluster.del("java framework");
System.out.println(cluster.lrange("java framework", 0, -1));
// 先向key java framework中存放三條資料
cluster.lpush("java framework", "spring");
cluster.lpush("java framework", "struts");
cluster.lpush("java framework", "hibernate");
// 再取出所有資料jedis.lrange是按範圍取出,
// 第一個是key,第二個是起始位置,第三個是結束位置,jedis.llen獲取長度 -1表示取得所有
System.out.println(cluster.lrange("java framework", 0, -1));
cluster.del("java framework");
cluster.rpush("java framework", "spring");
cluster.rpush("java framework", "struts");
cluster.rpush("java framework", "hibernate");
System.out.println(cluster.lrange("java framework", 0, -1));
}
@Test
public void testSet() {
// 新增
cluster.sadd("user","boonya");
cluster.sadd("user", "niuniu");
cluster.sadd("user", "ling");
cluster.sadd("user", "guoniuniu");
cluster.sadd("user", "who");
//cluster.sadd("user",new String []{ "boonya","niuniu","ling","guoniuniu","who"});
// 移除noname
cluster.srem("user", "who");
System.out.println(cluster.smembers("user"));// 獲取所有加入的value
System.out.println(cluster.sismember("user", "who"));// 判斷 who
// 是否是user集合的元素
System.out.println(cluster.srandmember("user"));
System.out.println(cluster.scard("user"));// 返回集合的元素個數
}
@Test
public void testUserSession(){
// -----新增資料----------
Map<String, String> map = new HashMap<String, String>();
map.put("zhangsan", "zhangsan-v");
map.put("lisi", "lisi-v");
map.put("wangwu", "wangwu-v");
cluster.hmset("usersession", map);
// 第一個引數是存入redis中map物件的key,後面跟的是放入map中的物件的key,後面的key可以跟多個,是可變引數
List<String> rsmap = cluster.hmget("usersession","zhangsan","lisi");
System.out.println(rsmap);
}
}
注:此處testSet報redis.clients.jedis.exceptions.JedisDataException: WRONGTYPE Operation against a key holding the wrong kind of value異常,這個應該是redis的問題。另外,redis配置檔案預設Slave節點只可讀不可寫。
3.測試過程中遇到的問題
3.1提示許可權驗證失敗
錯誤棧內資訊:
redis.clients.jedis.exceptions.JedisDataException: ERR Client sent AUTH, but no password is set
at redis.clients.jedis.Protocol.processError(Protocol.java:117)
at redis.clients.jedis.Protocol.process(Protocol.java:151)
at redis.clients.jedis.Protocol.read(Protocol.java:205)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:196)
at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:85)
at redis.clients.jedis.Connection.sendCommand(Connection.java:100)
at redis.clients.jedis.Connection.sendCommand(Connection.java:91)
at redis.clients.jedis.BinaryClient.auth(BinaryClient.java:538)
at redis.clients.jedis.BinaryJedis.auth(BinaryJedis.java:2012)
at com.boonya.redis.MyJedisTest.setup(MyJedisTest.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
因為redis預設沒有設定密碼,所以在訪問的時候可以不設定auth.若要使用密碼方式訪問,需要在redis.conf中設定requirepass yourpass.
3.2叢集宕機提示
redis.clients.jedis.exceptions.JedisClusterException: CLUSTERDOWN The cluster is down
當叢集不可用時,所有對叢集的操作做都不可用,收到CLUSTERDOWN The cluster is down錯誤,一般可以認為是叢集節點掛掉了,另外一種原因是API呼叫錯誤。
3.3節點訪問轉移錯誤
Exception in thread "main" redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 5474 192.168.28.194:7001
at redis.clients.jedis.Protocol.processError(Protocol.java:108)
at redis.clients.jedis.Protocol.process(Protocol.java:151)
at redis.clients.jedis.Protocol.read(Protocol.java:205)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:196)
at redis.clients.jedis.Jedis.hmset(Jedis.java:644)
at com.boonya.redis.samles.RedisMapJava.main(RedisMapJava.java:19)
MOVED indicates that you're using Redis Cluster. ShardedJedis is not for Redis Cluster, so you should use JedisCluster instead. 不應該呼叫叢集節點,API呼叫方式錯誤。From:http://stackoverflow.com/questions/30150704/jedismoveddataexception-when-using-sadd-with-pipeline
3.4錯誤的資料型別
redis.clients.jedis.exceptions.JedisDataException: WRONGTYPE Operation against a key holding the wrong kind of value
at redis.clients.jedis.Protocol.processError(Protocol.java:117)
at redis.clients.jedis.Protocol.process(Protocol.java:151)
at redis.clients.jedis.Protocol.read(Protocol.java:205)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297)
at redis.clients.jedis.Connection.getIntegerReply(Connection.java:222)
at redis.clients.jedis.Jedis.sadd(Jedis.java:1048)
at redis.clients.jedis.JedisCluster$49.execute(JedisCluster.java:559)
at redis.clients.jedis.JedisCluster$49.execute(JedisCluster.java:556)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:56)
at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:29)
at redis.clients.jedis.JedisCluster.sadd(JedisCluster.java:556)
at com.boonya.redis.cluster.ClusterTest.testSet(ClusterTest.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
這是操作set sadd出現的問題,設定資料型別和方式並沒有錯,但是redis提示錯誤,後期使用中有待關注。