在对Redis进行性能优化时,一直想对Redis进行读写分离。但由于项目底层采用spring-data-redis对redis进行操作,参考spring官网却发现spring-data-redis目前(1.7.0.RELEASE)及以前的版本并不支持读写分离。
一、源码分析
spring-data-redis中关于JedisConnectionFactory的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <bean id="redisSentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> <property name="master"> <bean class="org.springframework.data.redis.connection.RedisNode"> <property name="name" value="mymaster"/> <constructor-arg name="host" value="${redis.master.host}"></constructor-arg> <constructor-arg name="port" value="${redis.master.port}"></constructor-arg> </bean> </property> <property name="sentinels"> <set> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.sentinel1.host}"></constructor-arg> <constructor-arg name="port" value="${redis.sentinel1.port}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.sentinel2.host}"></constructor-arg> <constructor-arg name="port" value="${redis.sentinel2.port}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="${redis.sentinel3.host}"></constructor-arg> <constructor-arg name="port" value="${redis.sentinel3.port}"></constructor-arg> </bean> </set> </property> </bean> <!-- 连接池配置 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.pool.maxActive}" /> <property name="maxIdle" value="${redis.pool.maxIdle}" /> <!-- <property name="maxWait" value="${redis.pool.maxWait}" /> --> <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> <property name="testOnReturn" value="${redis.pool.testOnReturn}" /> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="poolConfig" ref="jedisPoolConfig"></property> <constructor-arg ref="redisSentinelConfiguration"/> </bean> <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/> </beans>
查看JedisConnectionFactory源码发现pool是Pool<Jedis>,而不是Pool<ShardedJedis>。因此我猜目前spring data redis是做不了读写分离的,stringRedisTemplate读写操作都是在master上。
二、读写分离改造
参考sentinel的主备选举机制对spring-data-redis的相关配置进行如下改造:
(1)Spring配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <context:property-placeholder location="classpath:redis/redis.properties" ignore-unresolvable="true" /> <bean id="poolConfig" class="redis.client.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxTotal" value="${redis.maxTotal}" /> <property name="maxWaitMillis" value="${redis.maxWait}" /> <property name="testOnBuorrow" value="${redis.testOnBorrow}" /> </bean> <bean id="redisSentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> <constructor-arg index="0"> <bean class="org.springframework.core.env.MapPropertySource"> <constructor-arg index="0" value="RedisSentinelConffiguration" /> <constructor-arg index="1"> <map> <entry key="spring.redis.sentinel.master" value="${redis.sentinel.master}"></entry> <entry key="spring.redis.sentinel.nodes" value="${redis.sentinel.nodes"}> </entry> </map> </constructor-arg> </bean> </constructor-arg> </bean> <bean id="connectionFactory" class="com.test.data.redis.connection.TWJedisConnectionFactory"> <constructor-arg index="0" ref="redisSentinelConfiguration" /> <constructor-arg index="1" ref="poolConfig" /> <property name="password" value="${redis.pass}" /> <property name="databse" value="7" /> </bean> <bean id="redisTemplate" class="com.test.data.redis.core.TWRedisTemplate" <property name="connectionFactory" ref="connectionFactory"/> </bean> </beans>
时间: 2024-12-16 19:30:46