当前位置:   article > 正文

Jedis常见异常汇总_caused by: redis.clients.jedis.exceptions.jedisdat

caused by: redis.clients.jedis.exceptions.jedisdataexception: err max number

Jedis虽然使用起来比较简单,但是如果不能根据使用场景设置合理的参数(例如连接池参数),不合理的使用一些功能(例如Lua和事务)也会产生很多问题,本文对这些问题逐个说明:

详细目录:

  • 一、redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
  • 二、redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream
  • 三、redis.clients.jedis.exceptions.JedisDataException: ERR illegal address
  • 四、redis.clients.jedis.exceptions.JedisDataException: ERR max number of clients reached
  • 五、redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
  • 六、redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required
  • 七、redis.clients.jedis.exceptions.JedisDataException: EXECABORT Transaction discarded because of previous errors
  • 八、java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.List
  • 九、redis.clients.jedis.exceptions.JedisDataException: WRONGTYPE Operation against a key holding the wrong kind of value
  • 十、redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when used memory > 'maxmemory'
  • 十一、redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the dataset in memory
  • 十二、redis.clients.jedis.exceptions.JedisDataException: BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
  • 十三、redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out
  • 十四、UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE command.
  • 十五、java.lang.NoClassDefFoundError
  • 十六、redis.clients.jedis.exceptions.JedisDataException: ERR unknown command
  • 十七、redis.clients.jedis.exceptions.JedisDataException: Please close pipeline or multi block before calling this method.
  • 十八、redis.clients.jedis.exceptions.JedisDataException: ERR command role not support for normal user.

一.无法从连接池获取到Jedis连接

1.异常堆栈

(1) 连接池参数blockWhenExhausted = true(默认)

如果连接池没有可用Jedis连接,会等待maxWaitMillis(毫秒),依然没有获取到可用Jedis连接,会抛出如下异常:

  1. redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
  2. Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
  3. at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)

(2) 连接池参数blockWhenExhausted = false

设置如果连接池没有可用Jedis连接,立即抛出异常:

  1. redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
  2. Caused by: java.util.NoSuchElementException: Pool exhausted
  3. at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)
2.异常描述

1

上述异常是客户端没有从连接池(最大maxTotal个)拿到可用Jedis连接造成的,具体可能有如下原因:

(1) 连接泄露 (较为常见)

JedisPool默认的maxTotal=8,下面的代码从JedisPool中借了8次Jedis,但是没有归还,当第9次(jedisPool.getResource().ping())

  1. GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
  2. JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
  3. //向JedisPool借用8次连接,但是没有执行归还操作。
  4. for (int i = 0; i < 8; i++) {
  5. Jedis jedis = null;
  6. try {
  7. jedis = jedisPool.getResource();
  8. jedis.ping();
  9. } catch (Exception e) {
  10. logger.error(e.getMessage(), e);
  11. }
  12. }
  13. jedisPool.getResource().ping();

所以推荐使用的代码规范是:

  1. 执行命令如下:
  2. Jedis jedis = null;
  3. try {
  4. jedis = jedisPool.getResource();
  5. //具体的命令
  6. jedis.executeCommand()
  7. } catch (Exception e) {
  8. //如果命令有key最好把key也在错误日志打印出来,对于集群版来说通过key可以帮助定位到具体节点。
  9. logger.error(e.getMessage(), e);
  10. } finally {
  11. //注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
  12. if (jedis != null)
  13. jedis.close();
  14. }

(2) 业务并发量大,maxTotal确实设置小了。

举个例子:

  • 一次命令时间(borrow|return resource + Jedis执行命令(含网络) )的平均耗时约为1ms,一个连接的QPS大约是1000
  • 业务期望的QPS是50000

那么理论上需要的资源池大小是50000 / 1000 = 50个,实际maxTotal可以根据理论值进行微调。

(3) Jedis连接还的太慢

例如Redis发生了阻塞(例如慢查询等原因),所有连接在超时时间范围内等待,并发量较大时,会造成连接池资源不足。

(4) 其他问题

例如丢包、DNS、客户端TCP参数配置,具体可以参考:Jedis介绍及常见问题分析

3.解决方法:

可以看到这个问题稍微复杂一些,不要被异常的表象所迷惑,简单地认为连接池不够就盲目加大maxTotal,要具体问题具体分析。

连接池参数优化可以参考:JedisPool资源池优化

4.处理人

客户先确认,如解决不了,需要借助工单解决

还有一种情况是:从池子里拿连接,由于没有空闲连接,需要重新生成一个Jedis连接,但是连接被拒绝:

  1. redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
  2. at redis.clients.util.Pool.getResource(Pool.java:50)
  3. at redis.clients.jedis.JedisPool.getResource(JedisPool.java:99)
  4. at TestAdmin.main(TestAdmin.java:14)
  5. Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused
  6. at redis.clients.jedis.Connection.connect(Connection.java:164)
  7. at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:80)
  8. at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1676)
  9. at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:87)
  10. at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:861)
  11. at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435)
  12. at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
  13. at redis.clients.util.Pool.getResource(Pool.java:48)
  14. ... 2 more
  15. Caused by: java.net.ConnectException: Connection refused
  16. at java.net.PlainSocketImpl.socketConnect(Native Method)
  17. at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
  18. at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
  19. at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
  20. at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
  21. at java.net.Socket.connect(Socket.java:579)
  22. at redis.clients.jedis.Connection.connect(Connection.java:158)
  23. ... 9 more

可以从at redis.clients.jedis.Connection.connect(Connection.java:158)看到实际是一个Socket连接:

  1. socket.setSoLinger(true, 0); // Control calls close () method,
  2. // the underlying socket is closed
  3. // immediately
  4. // <-@wjw_add
  5. 158: socket.connect(new InetSocketAddress(host, port), connectionTimeout);

一般这种需要检查Redis的域名配置是否正确,排查该段时间网络是否正常

二、客户端缓冲区异常

1.异常堆栈
  1. redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
  2. at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:199)
  3. at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
  4. at redis.clients.jedis.Protocol.process(Protocol.java:151)
  5. ......
2.异常描述:

这个异常是客户端缓冲区异常,产生这个问题可能有三个原因:

(1) 常见原因:多个线程使用一个Jedis连接,正常的情况是一个线程使用一个Jedis连接,可以使用JedisPool管理Jedis连接,实现线程安全,防止出现这种情况,例如下面代码中两个线程用了一个Jedis连接:

  1. new Thread(new Runnable() {
  2. public void run() {
  3. for (int i = 0; i < 100; i++) {
  4. jedis.get("hello");
  5. }
  6. }
  7. }).start();
  8. new Thread(new Runnable() {
  9. public void run() {
  10. for (int i = 0; i < 100; i++) {
  11. jedis.hget("haskey", "f");
  12. }
  13. }
  14. }).start();

(2) 客户端缓冲区满了

Redis有三种客户端缓冲区:

  • 普通客户端缓冲区(normal):用于接受普通的命令,例如get、set、mset、hgetall、zrange等
  • slave客户端缓冲区(slave):用于同步master节点的写命令,完成复制。
  • 发布订阅缓冲区(pubsub):pubsub不是普通的命令,因此有单独的缓冲区。

客户端缓冲区

Redis的客户端缓冲区配置具体格式是:

client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

(a) class: 客户端类型:(a) normal、(b) slave、(c) pubsub

(b) hard limit: 如果客户端使用的输出缓冲区大于hard limit,客户端会被立即关闭。

(c) soft limit和soft seconds: 如果客户端使用的输出缓冲区超过了soft limit并且持续了soft limit秒,客户端会被立即关闭

例如下面是一份Redis缓冲区的配置,所以当条件满足时,客户端连接会被关闭,就会出现Unexpected end of stream。

  1. redis> config get client-output-buffer-limit
  2. 1) "client-output-buffer-limit"
  3. 2) "normal 524288000 0 0 slave 2147483648 536870912 480 pubsub 33554432 8388608 60"

(3) 长时间闲置连接被服务端主动断开,可以查询timeout配置的设置以及自身连接池配置是否需要做空闲检测。

3.解决方法和处理人:

客户:排查自身代码是否使用JedisPool管理Jedis连接,是否存在并发操作Jedis的情况。

工单: 排查(2)(3),阿里云Redis中timeout=0,也就是不会主动关闭空闲连接,缓冲区设置为0 0 0 也就是不会对客户端缓冲区进行限制,一般不会有问题

三、非法客户端地址 (阿里云Redis提供客户端白名单功能)

1.异常堆栈
  1. Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR illegal address
  2. at redis.clients.jedis.Protocol.processError(Protocol.java:117)
  3. at redis.clients.jedis.Protocol.process(Protocol.java:151)
  4. at redis.clients.jedis.Protocol.read(Protocol.java:205)
  5. ......
2.异常描述:

Redis实例配置了白名单,但当前访问Redis的客户端(IP)不在白名单中。

3.解决方法:

添加该客户端(IP)的白名单

4.处理人

客户或者工单都可以

四、客户端连接数达到最大值

1.异常堆栈
redis.clients.jedis.exceptions.JedisDataException: ERR max number of clients reached
2.异常描述:

如果客户端连接数超过了Redis实例配置的最大maxclients

3.解决方法:

提工单帮助临时调大最大连接数,并让客户找到连接数暴涨的原因(因为上述调整只是临时调整),

4.处理人
  • 工单:临时调整最大连接数,协助定位问题
  • 客户:定位自身问题(可以定位连接最多的客户端),找到问题原因(例如连接池配置等)

五、客户端读写超时

1.异常堆栈
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
2.异常描述:

该问题原因可能有如下几种:
(1) 读写超时设置的过短。
(2) 有慢查询或者Redis发生阻塞。
(3) 网络不稳定。

3.解决方法:

客户提供读写超时时间,提交工单定位相关原因

4.处理人:

工单。

六、密码相关的异常

1.异常堆栈

Redis设置了密码,客户端请求没传密码:

  1. Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.
  2. at redis.clients.jedis.Protocol.processError(Protocol.java:127)
  3. at redis.clients.jedis.Protocol.process(Protocol.java:161)
  4. at redis.clients.jedis.Protocol.read(Protocol.java:215)

Redis没有设置密码,客户端传了密码:

  1. Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: ERR Client sent AUTH, but no password is set
  2. at redis.clients.jedis.Protocol.processError(Protocol.java:127)
  3. at redis.clients.jedis.Protocol.process(Protocol.java:161)
  4. at redis.clients.jedis.Protocol.read(Protocol.java:215)

客户端传了错误的密码:

  1. redis.clients.jedis.exceptions.JedisDataException: ERR invalid password
  2. at redis.clients.jedis.Protocol.processError(Protocol.java:117)
  3. at redis.clients.jedis.Protocol.process(Protocol.java:151)
  4. at redis.clients.jedis.Protocol.read(Protocol.java:205)
2.解决方法:弄清楚到底有没有密码,密码是否正确。

七、事务异常

1.异常堆栈
redis.clients.jedis.exceptions.JedisDataException: EXECABORT Transaction discarded because of previous errors
2.异常描述:

这个是Redis的事务异常:事务中包含了错误的命令,例如如下sett是个不存在的命令。

  1. 127.0.0.1:6379> multi
  2. OK
  3. 127.0.0.1:6379> sett key world
  4. (error) ERR unknown command 'sett'
  5. 127.0.0.1:6379> incr counter
  6. QUEUED
  7. 127.0.0.1:6379> exec
  8. (error) EXECABORT Transaction discarded because of previous errors.
3.解决方法和处理人:

客户修复自身代码错误。

八、类转换错误

1.异常堆栈
  1. java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.List
  2. at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:199)
  3. at redis.clients.jedis.Jedis.hgetAll(Jedis.java:851)
  4. at redis.clients.jedis.ShardedJedis.hgetAll(ShardedJedis.java:198)
  1. java.lang.ClassCastException: java.util.ArrayList cannot be cast to [B
  2. at redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:182)
  3. at redis.clients.jedis.Connection.getBulkReply(Connection.java:171)
  4. at redis.clients.jedis.Jedis.rpop(Jedis.java:1109)
  5. at redis.clients.jedis.ShardedJedis.rpop(ShardedJedis.java:258)
  6. .......
2.异常描述:

Jedis正确的使用方法是:一个线程操作一个Jedis,通常来讲产生该错误是由于没有使用JedisPool造成的,例如如下代码在两个线程并发使用了一个Jedis。(get、hgetAll返回类型也是不一样的)

  1. new Thread(new Runnable() {
  2. public void run() {
  3. for (int i = 0; i < 100; i++) {
  4. jedis.set("hello", "world");
  5. jedis.get("hello");
  6. }
  7. }
  8. }).start();
  9. new Thread(new Runnable() {
  10. public void run() {
  11. for (int i = 0; i < 100; i++) {
  12. jedis.hset("hashkey", "f", "v");
  13. jedis.hgetAll("hashkey");
  14. }
  15. }
  16. }).start();
3.解决方法和处理人:

客户排查自身代码是否存在上述问题

九、命令使用错误

1.异常堆栈
  1. Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: WRONGTYPE Operation against a key holding the wrong kind of value
  2. at redis.clients.jedis.Protocol.processError(Protocol.java:127)
  3. at redis.clients.jedis.Protocol.process(Protocol.java:161)
  4. at redis.clients.jedis.Protocol.read(Protocol.java:215)
  5. .....
2.异常描述:

例如key="hello"是字符串类型的键,而hgetAll是哈希类型的键,所以出现了错误。

  1. jedis.set("hello","world");
  2. jedis.hgetAll("hello");
3.解决方法和处理人:

请客户修改自身代码错误。

十、Redis使用的内存超过maxmemory配置

1.异常堆栈
redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when used memory > 'maxmemory'.
2.异常描述:

Redis节点(如果是集群,则是其中一个节点)使用大于该实例的内存规格(maxmemory配置)。

3.解决方法:

原因可能有以下几个:

  • 业务数据正常增加
  • 客户端缓冲区异常:例如使用了monitor、pub/sub使用不当等等
  • 纯缓存使用场景,但是maxmemory-policy配置有误(例如没有过期键的业务配置volatile-lru)

紧急处理,可以临时提工单帮助临时调整maxmeory,后续咨询用户是否升配或者调整配置。

4.处理人
  • 客户:找到内存增大的原因。
  • 工单:协助临时调整maxmeomry,如果客户需要,可以协助解决

十一、Redis正在加载持久化文件

1.异常堆栈
redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the dataset in memory
2.异常描述:

Jedis调用Redis时,如果Redis正在加载持久化文件,无法进行正常的读写。

3.解决方法:

正常情况下,阿里云Redis不会出现这种情况,如果出现,则提交工单处理。

4.处理人:

工单。

十二、Lua脚本超时

1.异常堆栈
redis.clients.jedis.exceptions.JedisDataException: BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
2.异常描述:

如果Redis当前正在执行Lua脚本,并且超过了lua-time-limit,此时Jedis调用Redis时,会收到下面的异常

3.解决方法:

按照异常提示:You can only call SCRIPT KILL or SHUTDOWN NOSAVE. (使用script kill:kill掉Lua脚本)

4.处理人:

最好客户自己处理,如果解决不了,值班人员可以协助操作。

十三 连接超时

1.异常堆栈
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out
2.异常描述:

可能产生的原因:

  • 连接超时设置的过短。
  • tcp-backlog满,造成新的连接失败。
  • 客户端与服务端网络不正常。
3.解决方法:

客户提供连接超时时间,提交工单定位相关原因。

4.处理人:

工单。

十四 Lua脚本写超时

1.异常堆栈
(error) UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE command.
2.异常描述:

如果Redis当前正在执行Lua脚本,并且超过了lua-time-limit,并且已经执行过写命令,此时Jedis调用Redis时,会收到上面的异常

3.解决方法:

提交工单做紧急处理,管理员要做重启或者切换Redis节点。

4.处理人:

工单。

十五、类加载错误

1.异常堆栈

例如找不到类和方法:

  1. Exception in thread "commons-pool-EvictionTimer" java.lang.NoClassDefFoundError: redis/clients/util/IOUtils
  2. at redis.clients.jedis.Connection.disconnect(Connection.java:226)
  3. at redis.clients.jedis.BinaryClient.disconnect(BinaryClient.java:941)
  4. at redis.clients.jedis.BinaryJedis.disconnect(BinaryJedis.java:1771)
  5. at redis.clients.jedis.JedisFactory.destroyObject(JedisFactory.java:91)
  6. at org.apache.commons.pool2.impl.GenericObjectPool.destroy(GenericObjectPool.java:897)
  7. at org.apache.commons.pool2.impl.GenericObjectPool.evict(GenericObjectPool.java:793)
  8. at org.apache.commons.pool2.impl.BaseGenericObjectPool$Evictor.run(BaseGenericObjectPool.java:1036)
  9. at java.util.TimerThread.mainLoop(Timer.java:555)
  10. at java.util.TimerThread.run(Timer.java:505)
  11. Caused by: java.lang.ClassNotFoundException: redis.clients.util.IOUtils
  12. ......
2.异常描述:

运行时,Jedis执行命令,抛出异常:某个类找不到。一般此类问题都是由于加载多个jedis版本(例如jedis 2.9.0和jedis 2.6),在编译期代码未出现问题,但类加载器在运行时加载了低版本的Jedis,造成运行时找不到类。

3.解决方法:

通常此类问题,可以将重复的jedis排除掉,例如利用maven的依赖树,把无用的依赖去掉或者exclusion掉。

4.处理人

客户排查自身代码

十六、服务端命令不支持

1.异常堆栈

例如客户端执行了geoadd命令,但是服务端返回不支持此命令

redis.clients.jedis.exceptions.JedisDataException: ERR unknown command 'GEOADD'
2.异常描述:

该命令不能被Redis端识别,有可能有两个原因:

  • 社区版的一些命令,阿里云Redis的不支持,或者只在某些小版本上支持(例如geoadd是Redis 3.2添加的地理信息api)。
  • 命令本身是错误的(不过对于Jedis来说还好,不支持直接组装命令,每个API都有固定的函数)。
3.解决方法:

咨询是否有Redis版本支持该命令,如支持可以让客户做小版本升级。

4.处理人
  • 管理员:确认版本是否支持该命令
  • 客户:确认后,做小版本升级

十七、pipeline错误使用

1.异常堆栈
redis.clients.jedis.exceptions.JedisDataException: Please close pipeline or multi block before calling this method.
2.异常描述:

在pipeline.sync()执行之前,通过response.get()获取值,在pipeline.sync()执行前,命令没有执行(可以通过monitor做验证),下面代码就会引起上述异常

  1. Jedis jedis = new Jedis("127.0.0.1", 6379);
  2. Pipeline pipeline = jedis.pipelined();
  3. pipeline.set("hello", "world");
  4. pipeline.set("java", "jedis");
  5. Response<String> pipeString = pipeline.get("java");
  6. //这个get必须在sync之后,如果是批量获取值建议直接用List<Object> objectList = pipeline.syncAndReturnAll();
  7. System.out.println(pipeString.get());
  8. //命令此时真正执行
  9. pipeline.sync();

Jedis中Reponse中get()方法,有个判断:如果set=false就会报错,而response中的set初始化为false.

  1. public T get() {
  2. // if response has dependency response and dependency is not built,
  3. // build it first and no more!!
  4. if (dependency != null && dependency.set && !dependency.built) {
  5. dependency.build();
  6. }
  7. if (!set) {
  8. throw new JedisDataException(
  9. "Please close pipeline or multi block before calling this method.");
  10. }
  11. if (!built) {
  12. build();
  13. }
  14. if (exception != null) {
  15. throw exception;
  16. }
  17. return response;
  18. }

pipeline.sync()会每个结果设置set=true。

  1. public void sync() {
  2. if (getPipelinedResponseLength() > 0) {
  3. List<Object> unformatted = client.getAll();
  4. for (Object o : unformatted) {
  5. generateResponse(o);
  6. }
  7. }
  8. }

其中generateResponse(o):

  1. protected Response<?> generateResponse(Object data) {
  2. Response<?> response = pipelinedResponses.poll();
  3. if (response != null) {
  4. response.set(data);
  5. }
  6. return response;
  7. }

其中response.set(data);

  1. public void set(Object data) {
  2. this.data = data;
  3. set = true;
  4. }
3.解决方法:

实际上对于批量结果的解析,建议使用pipeline.syncAndReturnAll()来实现,下面操作模拟了批量hgetAll

  1. /**
  2. * pipeline模拟批量hgetAll
  3. * @param keyList
  4. * @return
  5. */
  6. public Map<String, Map<String, String>> mHgetAll(List<String> keyList) {
  7. // 1.生成pipeline对象
  8. Pipeline pipeline = jedis.pipelined();
  9. // 2.pipeline执行命令,注意此时命令并未真正执行
  10. for (String key : keyList) {
  11. pipeline.hgetAll(key);
  12. }
  13. // 3.执行命令 syncAndReturnAll()返回结果
  14. List<Object> objectList = pipeline.syncAndReturnAll();
  15. if (objectList == null || objectList.isEmpty()) {
  16. return Collections.emptyMap();
  17. }
  18. // 4.解析结果
  19. Map<String,Map<String, String>> resultMap = new HashMap<String, Map<String,String>>();
  20. for (int i = 0; i < objectList.size(); i++) {
  21. Object object = objectList.get(i);
  22. Map<String, String> map = (Map<String, String>) object;
  23. String key = keyList.get(i);
  24. resultMap.put(key, map);
  25. }
  26. return resultMap;
  27. }
4.处理人:

修改业务代码。

十八、管理员命令,普通用户不能执行

1.异常堆栈

命令role不能被普通用户执行,可以参考暂未开放的Redis命令

redis.clients.jedis.exceptions.JedisDataException: ERR command role not support for normal user
2.异常描述:

改命令尚未开放

3.解决方法:

不能使用该命令,如果有需求或者疑问可以联系值班人员。

4.处理人

从文档中确认该命令是否开放

其他问题:

1.Jedis版本如何选择:

原则上选择最新的release版本,但最好选择release一段时间后的版本,因为jedis历史上出现过一次问题较大的release版本,目前来说2.9.0比较稳定。

  1. <dependency>
  2. <groupId>redis.clients</groupId>
  3. <artifactId>jedis</artifactId>
  4. <version>2.9.0</version>
  5. <type>jar</type>
  6. <scope>compile</scope>
  7. </dependency>
2.Jedis中的JedisCluster是阿里云Redis集群版的客户端吗?

答:不是,使用阿里云集群版的客户端,直接使用Jedis和JedisPool即可。因为官方集群和阿里云Redis集群是不同的架构,具体参考:redis4.0、codis、阿里云redis 3种redis集群对比分析

......其他待补充......

附赠连接池参数

1. 资源设置和使用
序号参数名含义默认值使用建议
1maxTotal资源池中最大连接数8设置建议见下节
2maxIdle资源池允许最大空闲的连接数8设置建议见下节
3minIdle资源池确保最少空闲的连接数0设置建议见下节
4blockWhenExhausted当资源池用尽后,调用者是否要等待。只有当为true时,下面的maxWaitMillis才会生效true建议使用默认值
5maxWaitMillis当资源池连接用尽后,调用者的最大等待时间(单位为毫秒)-1:表示永不超时不建议使用默认值
6testOnBorrow向资源池借用连接时是否做连接有效性检测(ping),无效连接会被移除false业务量很大时候建议设置为false(多一次ping的开销)。
7testOnReturn向资源池归还连接时是否做连接有效性检测(ping),无效连接会被移除false业务量很大时候建议设置为false(多一次ping的开销)。
8jmxEnabled是否开启jmx监控,可用于监控true建议开启,但应用本身也要开启
2.空闲资源监测

空闲Jedis对象检测,下面四个参数组合来完成,testWhileIdle是该功能的开关。

序号参数名含义默认值使用建议
1testWhileIdle是否开启空闲资源监测falsetrue
2timeBetweenEvictionRunsMillis空闲资源的检测周期(单位为毫秒)-1:不检测建议设置,周期自行选择,也可以默认也可以使用下面JedisPoolConfig中的配置
3minEvictableIdleTimeMillis资源池中资源最小空闲时间(单位为毫秒),达到此值后空闲资源将被移除1000 60 30 = 30分钟可根据自身业务决定,大部分默认值即可,也可以考虑使用下面JeidsPoolConfig中的配置
4numTestsPerEvictionRun做空闲资源检测时,每次的采样数3可根据自身应用连接数进行微调,如果设置为-1,就是对所有连接做空闲监测

参考来源:https://yq.aliyun.com/articles/236384?spm=a2c4e.11155435.0.0.e21e2612uQAVoW#cc1

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号