Dynamically add methods for Redis password authentication

  • 2020-05-24 06:26:45
  • OfStack

If redis is in online business use, but no password authentication is added, then how to add password authentication to redis without affecting business services is a problem to be considered carefully.

This article describes a possible scenario where the client USES an jedis connection pool and the server USES an redis master-slave cluster.

1. Customized jedis

To handle the error returned by redis, make two changes:

Ignore (error) ERR Client sent AUTH, but no password is set. Enable jedis with password configured to be used on redis without password configured;

When (error) NOAUTH Authentication required occurs, the current connection is set to broken, thus kicking the connection out of the connection pool. When you dynamically add a password to redis, jedis automatically recreates the available connection.

I have made the above modifications to jedis version 2.8.x. Can be downloaded directly to use. If you use a higher version of jedis, you can modify it by referring to my code. If you are using a lower version, it is recommended to upgrade to 2.8.x.

2. Use custom jedis in your project code

Modify the maven configuration. Comment out the original jedis dependency and add the local custom jedis dependency:


<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.3</version>
  <scope>system</scope>
  <systemPath>${project.basedir}/../libs/jedis-2.8.3.jar</systemPath> <!--  Here the systemPath is jedis-2.8.3 The relative path  -->
</dependency>
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-pool2</artifactId>
  <version>2.4.2</version>
</dependency>
<!--
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
</dependency>
-->

Since custom jedis is provided in the form of a local jar package, maven does not automatically load jedis dependencies, so an additional dependency on commons-pool2 needs to be added.

3. If you are using a lower version of jedis

The returnBrokenResource and returnResource methods of the old version of jedis have been abandoned in the new version of jedis. If you upgrade the jedis version, you need to replace the close method.

Replace before:


try {  
 // ... 
} catch (JedisException e) {
 // ...  
 pool.returnBrokenResource(jedis);  
}  
finally {  
 pool.returnResource(jedis);  
}

After the replacement:


try {  
 // ... 
} catch (JedisException e) {  
 // ...  
}  
finally {  
 jedis.close();
}

4. Bring the project code using custom jedis online

At this point, redis has not added a password, but custom jedis ignores "ERR Client sent AUTH, but no password is set", so it works fine online.

5. Add password authentication to redis server

Dynamic password addition will cause redis master/slave synchronization to be disconnected, so as to avoid causing a large impact on the business due to full synchronization. dba needs to first increase the client-output-buffer-limit and repl-backlog-size parameters of redis master, and then configure the password operation.

While adding the password to redis server, observe the log of the business code. After adding the password, the following error will appear in log several times, and then it will return to normal. The error number is the number of connections between the business server's jedis connection pool and that redis server when the password is added.


redis.clients.jedis.exceptions.JedisConnectionException: NOAUTH Authentication required.

If shardedJedis is used, shard it one by one to minimize the impact on business services.

6. Replace jedis with the official version

jedis is customized to dynamically add password authentication. After adding, change back to the official jedis for future upgrade.


<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
</dependency>

Related articles: