This article will introduce to you a summary of common Redis client exceptions (Jedis article). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.
[Introduction] Jedis is the client implementation of the java version of Redis. During the use of the Redis client, whether the client is used improperly or there is a problem with the Redis server, the client will respond to some exceptions. This article analyzes common exceptions during the use of Jedis. [Related recommendations: Redis Video Tutorial]
1. Unable to obtain a connection from the connection pool
The number of Jedis objects in JedisPool is limited , the default is 8. It is assumed here that the default configuration is used. If 8 Jedis objects are occupied and not returned, if the caller wants to borrow Jedis from JedisPool, it will need to wait (for example, maxWaitMillis>0 is set). If it is still within the maxWaitMillis time, If the Jedis object cannot be obtained, the following exception will be thrown.
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool … Caused by: java.util.NoSuchElementException: Timeout waiting for idle object at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)
There is another situation, that is, if blockWhenExhausted=false is set, then when the caller finds that there are no resources in the pool, an exception will be thrown immediately without waiting. The following exception is the effect of blockWhenExhausted=false.
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool … Caused by: java.util.NoSuchElementException: Pool exhausted at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)
Regarding this issue, what needs to be discussed is why the connection pool has no resources. There are many possible reasons for the lack of resources.
1. Client: The connection pool has been set up under high concurrency. Small, supply exceeds demand, so the above error will occur, but under normal circumstances it only needs to be more than the default maximum number of connections (8), because under normal circumstances the processing efficiency of JedisPool and Jedis is high enough.
2. Client: The connection pool is not used correctly, for example, it is not released. For example, as shown in the following code: Define JedisPool and use the default connection pool configuration.
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379); //向JedisPool借用8次连接,但是没有执行归还操作。 for (int i = 0; i < 8; i++) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.ping(); } catch (Exception e) { e.printStackTrace(); } }
When the caller borrows Jedis from the connection pool (as follows), an exception will be thrown:
jedisPool.getResource().ping();
3. Client: There are slow query operations. The Jedis objects held by these slow queries will be returned slowly, causing the pool to be full.
4. Server: The client is normal, but the Redis server blocks the client command execution process for some reasons, which will also cause the client to throw this exception. It can be seen that there are many reasons for this exception. Don't be fooled by the appearance of the exception. There is no master key that can solve all problems. Development and operation and maintenance can only continuously strengthen their understanding of Redis and gradually find the problem by following the clues. location.
2. Client read and write timeout
When Jedis calls Redis, if a read and write timeout occurs, the following exception will appear:
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
The reasons for this exception are also as follows:
The read and write timeout is set too short.
The command itself is relatively slow.
The network between client and server is abnormal.
Redis itself is blocked.
3. Client connection timeout
When Jedis calls Redis, if a read and write timeout occurs, the following exception will appear:
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out
The reasons for this exception are also as follows:
The connection timeout is set too short.
Redis is blocked, causing tcp-backlog to be full, causing new connections to fail.
The network between client and server is abnormal.
4. Client buffer exception
When Jedis calls Redis, if a client data flow exception occurs, the following exception will occur.
redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
The reasons for this exception may be as follows:
1. The output buffer is full. For example, set the output buffer of a normal client to 1M 1M 60:
config set client-output-buffer-limit "normal 1048576 1048576 60 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
If you use the get command to obtain a bigkey (such as 3M), this exception will occur.
2. The long-term idle connection is actively disconnected by the server. You can check the timeout configuration settings and whether the own connection pool configuration requires idle detection.
3. Abnormal concurrent reading and writing: The Jedis object is concurrently operated by multiple threads at the same time, and the above exception may occur.
5. The Lua script is executing
If Redis is currently executing the Lua script and exceeds lua-time-limit, when Jedis calls Redis, it will receive to the exception below. How to deal with this kind of problem (Lua lua-time-limit configuration has been introduced in the previous chapter)
redis.clients.jedis.exceptions.JedisDataException: BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
6. Redis is loading the persistence file
Jedis calls Redis At this time, if Redis is loading the persistent file, you will receive the following exception.
redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the dataset in memory
7. The memory used by Redis exceeds the maxmemory configuration
When Jedis calls Redis to perform a write operation, if the memory used by Redis is greater than the maxmemory setting, you will receive the following Exception, you should adjust maxmemory at this time and find the cause of memory growth (maxmemory has been introduced in the previous chapter)
redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when used memory > 'maxmemory'.
8. The number of client connections is too large
If the number of client connections exceeds maxclients, the following exception will appear in the newly requested connection:
redis.clients.jedis.exceptions.JedisDataException: ERR max number of clients reached
At this time, if the new client connection executes any command, the return result will be as follows:
127.0.0.1:6379> get hello (error) ERR max number of clients reached
这个问题可能会比较棘手,因为此时无法执行Redis命令,一般来说可以从两个方面进行着手。
1.客户端:如果maxclients参数不是很小的话,应用方的客户端连接数基本不会超过maxclients,通常来看是由于应用方对于Redis客户端使用不当造成的。此时如果应用方是分布式结构的话,可以通过下线部分应用节点(例如占用连接较多的节点),使得Redis的连接数先降下来。从而让绝大部分节点可以正常运行,此时在再通过查找程序bug或者调整maxclients进行问题的修复。
2.服务端:如果此时客户端无法处理,而当前Redis为高可用模式(例如Redis Sentinel和Redis Cluster),可以考虑将当前Redis做故障转移。
此问题不存在确定的解决方式,但是无论从哪个方面进行处理,故障的快速恢复极为重要,当然更为重要的是找到问题的所在,否则一段时间后客户端连接数依然会超过maxclients。
附赠GenericObjectPoolConfig的重要属性
原文地址:https://mp.weixin.qq.com/s?__biz=MjM5NTk0MTM1Mw==&mid=2650650677&idx=1&sn=cbb1cb9fefdf9641a4a7c775660114e8&chksm=bef9c6b3898e4fa5a31ac6e572dca4c20a37d6c1dcb41004d831b34300c5c9ae0ed8c3a1bb45&scene=21#wechat_redirect 作者:付磊
更多编程相关知识,请访问:编程教学!!
The above is the detailed content of Common client exceptions when using Jedis (summary). For more information, please follow other related articles on the PHP Chinese website!