549
技術社區[雲棲]
Jedis介紹及常見問題分析
Jedis介紹
Jedis是一個開源的Redis數據庫客戶端,兼容Redis 2.8.x和3.xx,Jedis提供了以下特性:
- 排序
- 鏈接管理
- 不同類型的value的命令處理
- String類型的命令處理
- Hashes類型的命令處理
- Lists類型的命令處理
- Sets類型的命令處理
- Sorted Sets類型的命令處理
- 事務
- 批量命令處理
- 訂閱/發布
- 持久化的控製命令
- 遠程控製命令
- 分片(MD5,MurmurHash)
- 集群的Key-tags功能
- 集群的批量命令處理
- 腳本的批量命令處理
- Redis集群支持
如何使用
- 下載官方最新編譯的穩定版本代碼: https://github.com/xetorthio/jedis/releases
- 直接在maven工程裏麵配置依賴如下:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
直連模式
import redis.clients.jedis.Jedis;
public class jedistest {
public static void main(String[] args) {
try {
String host = "xx.kvstore.aliyuncs.com";//控製台顯示訪問地址
int port = 6379;
Jedis jedis = new Jedis(host, port);
//鑒權信息
jedis.auth("password");//password
String key = "redis";
String value = "aliyun-redis";
//select db默認為0
jedis.select(1);
//set一個key
jedis.set(key, value);
System.out.println("Set Key " + key + " Value: " + value);
//get 設置進去的key
String getvalue = jedis.get(key);
System.out.println("Get Key " + key + " ReturnValue: " + getvalue);
jedis.quit();
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
連接池模式
JedisPoolConfig config = new JedisPoolConfig();
//最大空閑連接數, 應用自己評估,不要超過ApsaraDB for Redis每個實例最大的連接數
config.setMaxIdle(200);
//最大連接數, 應用自己評估,不要超過ApsaraDB for Redis每個實例最大的連接數
config.setMaxTotal(300);
config.setTestOnBorrow(false);
config.setTestOnReturn(false);
String host = "*.aliyuncs.com";
String password = "密碼";
JedisPool pool = new JedisPool(config, host, 6379, 3000, password);
Jedis jedis = null;
try {
jedis = pool.getResource();
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
jedis.zadd("sose", 0, "car");
jedis.zadd("sose", 0, "bike");
Set<String> sose = jedis.zrange("sose", 0, -1);
} finally {
if (jedis != null) {
jedis.close();
}
}
/// ... when closing your application:
pool.destroy();
常見出錯問題排查
連接池錯誤
使用Jedis連接池模式的時候容易出現的錯誤是無法獲取連接池
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
對於這類問題的原因有幾類,可以根據以下一一進行排查
網絡檢查
首先檢查是否網絡問題,可以通過telnet host 6379進行簡單測試,連上之後auth 密碼回車查看是否返回+OK\r\n,如果能夠正確返回繼續檢查ping請求或者讀寫請求是否正常返回,操作多次排查網絡問題影響。
JedisPool連接數設置檢查
JedisPool使用的時候需要進行連接池的設置,用戶在超過MaxTotal連接數的時候也會出現獲取不到連接池的情況,這個時候可以在訪問客戶端上通過netstat -an | grep 6379 | grep EST | wc -l 查看鏈接的客戶端鏈接數目,並且比較這個數目和JedisPool配置的MaxTotal的值,如果沒有明顯超過或者接近就可以排除JedisPool連接池配置的影響。
JedisPool連接池代碼檢查
對於JedisPool連接池的操作,每次getResource之後需要調用returnResource或者close進行歸還,可以查看代碼是否有正確使用,代碼sample可以參考上麵的
檢查是否發生nf_conntrack丟包
通過dmesg檢查客戶端是否有異常
nf_conntrack: table full, dropping packet
如果發生nf_conntract丟包可以通過修改設置sysctl -w net.netfilter.nf_conntrack_max=120000
檢查是否TIME_WAIT問題
通過ss -s 查看time wait鏈接是否過多
如果TIME_WAIT過多可以修改以下參數
sysctl -w net.ipv4.tcp_max_tw_buckets=180000
sysctl -w net.ipv4.tcp_tw_recycle=1
檢查是否DNS問題
通過在/etc/hosts文件直接綁定host地址,綁定完成之後查看問題是否還存在,如果還存在則不是DNS解析問題
192.168.1.1 *.redis.rds.aliyuncs.com
總結
如果按照上麵排查之後還有問題可以通過抓包並將報錯時間點,報錯信息,抓包文件發送給阿裏雲售後同學進行分析。抓包命令為sudo tcpdump -i eth0 tcp and port 6379 -n -nn -s 74 -w redis.cap。
最後更新:2017-04-20 11:31:14