purely for notes, transferred from: http://blog.csdn.net/fachang/article/details/7984123
Redis was used in the recent project development, and the Java client Jedis recommended by the website was selected. Redis Common Command Learning: http://redis.io/commands
Redis Official recommendation Java Client Jedis (contains all Redis command implementations): Https://github.com/xetorthio/jedis
The Jedis use of the most common exception jedisconnectionexception sometimes does bring us a lot of confusion, this anomaly usually occurs in two make the scene.
One, when we execute the following Jedispool class instance GetResource () throws the can ' t get a resource exception.
The exception code is as follows:
Redis.clients.jedis.exceptions.JedisConnectionException:Could not get a resource from the pool
At Redis.clients.util.Pool.getResource (pool.java:22)
Analysis:
Redis.clients.util.Pool.getResource will return an available Redis connection from the Jedispool instance pool. Analysis source know Jedispool extends redis.clients.util.pool<jedis>. and pool<t> is through
Commons-pool the Org.apache.commons.pool.impl.GenericObjectPool in the Open Source Toolkit to implement the management of Jedis instances. So let's analyze genericobjectpool and maybe we can find the answer. First look at Common-pool's api:http://commons.apache.org/pool/apidocs/index.html?org/apache/commons/pool/impl/. Genericobjectpool.html.
Some of the three important properties are:
maxactive: Maximum number of available connection instances, with no limit for negative values.
maxidle: The maximum number of idle connection instances, with no limit for negative values. Idle instances are usually made available through the org.apache.commons.pool.basepoolableobjectfactory<t> Activateobject () method before they are used.
maxwait: The maximum number of milliseconds (million seconds) to wait for an available connection.
(Note: the Pool.getresource () method actually calls the Genericobjectpool class Borrowobject () method, which blocks the wait-aware timeout based on the value of the maxwait variable when there is no available connection (idle/active). See API for specific meanings. )
That is, when there is no active/idle connection in the connection pool, it waits for maxwait time, and if there is no available connection for the wait timeout, the could not get a resource from the pool exception is thrown. So to avoid such a mistake,
We should set the value of these three parameters reasonably according to the actual situation of the program, and we should handle this exception reasonably when we get a connected program method, and it may be a good choice to wait for a period of time when no connection is available.
Second, when we get the connection to the Redis operation, throw redis.clients.jedis.exceptions.JedisConnectionException: Java.net.SocketTimeoutException:Read timed out exception.
The exception code is as follows:
Redis.clients.jedis.exceptions.JedisConnectionException:java.net.SocketTimeoutException:Read timed out
At Redis.clients.jedis.Protocol.process (protocol.java:79)
At Redis.clients.jedis.Protocol.read (protocol.java:131)
At Redis.clients.jedis.Connection.getIntegerReply (connection.java:188)
At Redis.clients.jedis.Jedis.sismember (jedis.java:1266)
It was a rather troublesome anomaly that bothered me for a day's time. We all know that Redis is the memory operation, the speed should be in the millisecond level, this is our common understanding, so when the Redis operation has a few seconds time out, you can imagine it.
Let's analyze the source code of Jedis First, take sadd operation as an example:
Public Long Sadd (final string key, final string ... members) {checkisinmulti (); Client.sadd (keys, members); return CLIENT.G Etintegerreply (); The Client is an instance of Redis.clients.jedis.Client.java, and the following are the inheritance relationships:
public class Client extends binaryclient implements Commands;
public class Binaryclient extends Connection; Connection wrapper socket operation to Redis Server, command write operation via Socket.getoutputstream () The output stream sends command information to Redis server, and when the command is finished, the input stream to the Socket.getinputstream () is
The command execution results are returned, and there is bound to be a command execution to the delay time returned by the result, which is the time it took for a Jedis to invoke the Redis command operation.
It is necessary to note that Redis server is a single-threaded execution of all connections sent over the command, that is, regardless of how many clients in the concurrency in the Send command, the Redis-server side is single-threaded processing, and the default FIFO way to process the request,
This can be configured in the redis.conf configuration file. Detailed operating mechanism for Redis server see: Http://redis.io/documentation so Client.sadd (key, members); After the call, just send the command message to the Redis server side, Specifically there is no implementation to look at the load situation of Redis server. Then, by Client.getintegerreply (), Wait (Time out) to return the result.
Connection has several options for initializing the socket, where the socket time out method is set up as follows:
public void Rollbacktimeout () { & nbsp try { socket.setsotimeout (timeout), &NBSP ; socket.setkeepalive (FALSE); } catch (SocketException ex) { &NBSP;&NBSP;THRO W New Jedisexception (ex); } } by Redis.clients.jedis.Protocol.DEFAULT_TIMEOUT = 2000 we know that the default time-out is 2 seconds, and this time is already very long relative to the speed at which Redis operates the memory millisecond, so why do we still encounter the
Ava.net.SocketTimeoutException:Read timed out exception? Although Redis operating memory is average in milliseconds, it may not be so fast when the amount of data is large. I encountered a collection in my development process to
Tens the amount of data, one operation timeout is normal in the second level, and the machine performance is very good, not to mention that our native developed machine is slower than the production server. So when initializing the jedispool, it should be based on the actual
The connection pool parameters are set rationally by Redis.clients.jedis.JedisPoolConfig, and the time-out of the socket read input InputStream is set by Edispool construction method.
Pool = new Jedispool (config, host, port, 100000);
Note that the fourth parameter, time out, is set to the timeout that we can tolerate, in milliseconds. But I don't know why the parameter type is int instead of long, since the unit is milliseconds.
After setting the fourth parameter, I was working on the 40 million data volume collection for a maximum of about 5 seconds, and the problem was basically resolved.