动态添加Redis密码认证

若是redis已在线上业务使用中,但没有添加密码认证,那么如何在不影响业务服务的前提下给redis添加密码认证,就是一个须要仔细考虑的问题。git

本文描述一种可行的方案,适用于客户端使用了jedis链接池,服务端使用了redis master-slave集群的状况。github

1.定制jedis

对redis返回的错误的处理,作两处修改:redis

忽略 (error) ERR Client sent AUTH, but no password is set。使配置了密码的jedis能够在没有配置密码redis上使用;apache

发生(error) NOAUTH Authentication required时,将当前connection置为broken,从而将链接踢出链接池。这样动态给redis添加上密码时,jedis会自动从新建立可用链接。服务器

我已经对jedis 2.8.x版本作好了以上修改。能够直接下载使用 。若是使用了更高的版本jedis,能够参考个人代码自行修改;若是使用了更低版本的,建议升级到2.8.x。maven

2.在项目代码中使用定制的jedis

修改maven配置。将原来的jedis依赖注释掉,添加对本地的定制jedis的依赖:ui

<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> <!-- 此处的systemPath是jedis-2.8.3所在的相对路径 -->
</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>
-->

由于把定制jedis经过本地jar包的形式提供,maven不会自动加载jedis的依赖,因此需额外添加对commons-pool2的依赖。加密

3.若是使用了低版本的jedis

老版本jedis的returnBrokenResource和returnResource这两个方法在新版本jedis中已经废弃,若是升级jedis版本的话,须要替换为close方法。code

替换前:server

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

替换后:

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

4.将使用定制jedis的项目代码上线

此时redis还没有添加密码,但定制jedis忽略了“ERR Client sent AUTH, but no password is set”,因此线上运行正常。

5.给redis server添加密码认证

动态添加密码会致使redis主从同步断开,为避免引发全量同步对业务形成较大影响。须要dba先调大redis master的client-output-buffer-limit和repl-backlog-size参数,再作配置密码操做。

给redis server添加密码的同时,观察业务代码的log,添加完密码后,log中会出现数次以下报错,随后恢复正常。报错次数是添加密码时,业务服务器的jedis链接池中与该redis server之间链接数量。

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

若是使用了shardedJedis,请逐个分片进行操做,最小化对业务服务的影响。

6.更换jedis为官方版本

定制jedis就是为了动态添加密码认证。添加完毕后,换回官方jedis,方便从此升级。

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.1</version>
</dependency>
相关文章
相关标签/搜索