이 문서에서는 일반적인 Redis 클라이언트 예외에 대한 요약을 소개합니다(Jedis 문서). 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
【소개】Jedis는 Java 버전 Redis의 클라이언트 구현입니다. Redis 클라이언트를 사용하는 동안 클라이언트가 부적절하게 사용되거나 Redis 서버에 문제가 있는지 여부에 관계없이 클라이언트는 몇 가지 예외에 응답합니다. 이 기사에서는 Jedis 사용 중 일반적인 예외를 분석합니다. [관련 권장 사항: Redis 동영상 튜토리얼]
1. 연결 풀에서 연결을 얻을 수 없습니다
JedisPool에 있는 Jedis 개체 수는 제한되어 있으며 기본값은 8입니다. 여기서는 기본 구성이 사용된다고 가정합니다. 8개의 Jedis 객체가 점유되어 반환되지 않은 경우 호출자가 JedisPool에서 Jedis를 빌리려면 기다려야 합니다(예를 들어 maxWaitMillis>0이 설정된 경우). 여전히 maxWaitMillis 시간 내에 Jedis 객체를 얻을 수 없으면 다음 예외가 발생합니다.
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)
또 다른 상황이 있습니다. 즉, blockWhenExhausted=false가 설정된 경우 호출자가 풀에 리소스가 없음을 발견하면 기다리지 않고 즉시 예외가 발생합니다. 다음 예외는 blockWhenExhausted=의 효과입니다. 거짓.
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)
이 문제에 대해 논의해야 할 것은 연결 풀에 리소스가 없는 이유입니다
1 클라이언트: 높은 동시성에서 연결 풀 설정이 너무 작고 공급이 부족합니다. 수요를 초과하므로 위의 오류가 발생하지만 일반적인 상황에서는 JedisPool 및 Jedis의 처리 효율성이 충분히 높기 때문에 기본 최대 연결 수(8)보다 많아야 합니다.
2. 클라이언트: 다음 코드와 같이 연결 풀이 올바르게 사용되지 않습니다. 예를 들어 해제되지 않습니다. JedisPool을 정의하고 기본 연결 풀 구성을 사용합니다.
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(); } }
호출자가 연결 풀에서 Jedis를 빌릴 때(다음과 같이) 예외가 발생합니다:
jedisPool.getResource().ping();
3. 클라이언트: 느린 쿼리 작업이 있으며 이러한 느린 쿼리에 의해 Jedis 개체의 반환 속도가 유지됩니다. 상대적으로 속도가 느려서 풀이 가득 찼습니다.
4. 서버: 클라이언트는 정상이지만 Redis 서버가 어떤 이유로 클라이언트 명령 실행 프로세스를 차단하여 클라이언트에서도 이 예외가 발생합니다. 예외가 발생하는 데에는 여러 가지 이유가 있다고 볼 수 있습니다. 모든 문제를 해결할 수 있는 마스터 키는 없습니다. Redis에 대한 이해를 지속적으로 강화할 수 있을 뿐입니다. 단서의 위치를 따라가면서 점차적으로 문제를 찾아보세요.
2. 클라이언트 읽기 및 쓰기 시간 초과
Jedis가 Redis를 호출할 때 읽기 및 쓰기 시간 초과가 발생하면 다음 예외가 나타납니다.
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
이 예외의 이유도 다음과 같습니다.
읽기 및 쓰기 시간 초과가 너무 짧게 설정되었습니다.
명령 자체가 상대적으로 느립니다.
클라이언트와 서버 간의 네트워크가 비정상적입니다.
Redis 자체가 차단되었습니다.
3. 클라이언트 연결 시간 초과
Jedis가 Redis를 호출할 때 읽기 및 쓰기 시간 초과가 발생하면 다음 예외가 나타납니다.
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out
이 예외에는 다음과 같은 이유도 있습니다.
연결 시간 초과 설정이 너무 그렇습니다. 짧은.
Redis가 차단되어 tcp-backlog가 가득 차서 새 연결이 실패합니다.
클라이언트와 서버 간의 네트워크가 비정상적입니다.
4. 클라이언트 버퍼 예외
Jedis가 Redis를 호출할 때 클라이언트 데이터 흐름 예외가 발생하면 다음 예외가 발생합니다.
redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
이 예외의 이유는 다음과 같습니다:
1 출력 버퍼가 가득 찼습니다. 예를 들어 일반 클라이언트의 출력 버퍼를 1M 1M 60으로 설정합니다.
config set client-output-buffer-limit "normal 1048576 1048576 60 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
get 명령을 사용하여 빅키(예: 3M)를 얻으면 이 예외가 발생합니다.
2. 오랫동안 유휴 상태였던 연결이 서버에 의해 적극적으로 연결 해제된 경우 시간 제한 구성 설정과 자체 연결 풀 구성에서 유휴 감지가 필요한지 여부를 확인할 수 있습니다.
3. 비정상적인 동시 읽기 및 쓰기: Jedis 객체가 여러 스레드에 의해 동시에 작동되며 위 예외가 발생할 수 있습니다.
5. Lua 스크립트가 실행 중입니다
Redis가 현재 Lua 스크립트를 실행하고 있고 lua-time-limit를 초과한 경우 Jedis가 Redis를 호출하면 다음 예외가 발생합니다. 이러한 문제를 해결하는 방법(Lua lua-time-limit 구성은 이전 장에서 소개했습니다)
redis.clients.jedis.exceptions.JedisDataException: BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
6. Redis가 영구 파일을 로드 중입니다
Jedis가 Redis를 호출할 때 Redis가 영구 파일을 로드하는 경우 파일을 삭제하면 다음 예외가 발생합니다.
redis.clients.jedis.exceptions.JedisDataException: LOADING Redis is loading the dataset in memory
7. Redis에서 사용하는 메모리가 maxmemory 구성을 초과합니다
Jedis가 쓰기 작업을 수행하기 위해 Redis를 호출할 때 Redis에서 사용하는 메모리가 maxmemory 설정보다 큰 경우 다음 예외가 발생합니다. time, maxmemory를 조정하고 문제를 일으키는 메모리를 찾아야 합니다. (maxmemory는 이전 장에서 소개했습니다.)
redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when used memory > 'maxmemory'.
8. 클라이언트 연결 수가 너무 많습니다
클라이언트 연결 수가 maxclients를 초과하면 새로 적용된 연결에 다음 예외가 나타납니다.
redis.clients.jedis.exceptions.JedisDataException: ERR max number of clients reached
이 때 새 클라이언트가 명령을 실행하기 위해 연결하면 반환되는 결과는 다음과 같습니다.
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 作者:付磊
更多编程相关知识,请访问:编程教学!!
위 내용은 Jedis 사용 시 일반적인 클라이언트 예외(요약)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!