1.1.Redis集羣的搭建
Redis集羣中至少應該有三個節點。要保證集羣的高可用,需要每個節點有一個備份機。
Redis集羣至少需要6臺服務器。
搭建僞分佈式。可以使用一臺虛擬機運行6個redis實例。需要修改redis的端口號7001-7006
1.1.1.集羣搭建環境
1、使用ruby腳本搭建集羣。需要ruby的運行環境。
安裝ruby
yum install ruby
yum install rubygems
分享 redis-3.0.0.gem文件到虛擬機
2、安裝ruby腳本運行使用的包。
[root@localhost ~]# gem install redis-3.0.0.gem
Successfully installed redis-3.0.0
1 gem installed
Installing ri documentation for redis-3.0.0...
Installing RDoc documentation for redis-3.0.0...
[root@localhost ~]#
[root@localhost ~]# cd redis-3.0.0/src
[root@localhost src]# ll *.rb
-rwxrwxr-x. 1 root root 48141 Apr 1 2015 redis-trib.rb
1.1.2.搭建步驟
需要6臺redis服務器。搭建僞分佈式。
需要6個redis實例。
需要運行在不同的端口7001-7006
第一步:創建6個redis實例,每個實例運行在不同的端口。需要修改redis.conf配置文件。配置文件中還需要把cluster-enabled yes前的註釋去掉。
第二步:啓動每個redis實例。
創建批處理啓動文件 vim start-all.sh,文件內容如下:
cd redis01
./redis-server redis.conf
cd ..
cd redis02
./redis-server redis.conf
cd ..
cd redis03
./redis-server redis.conf
cd ..
cd redis04
./redis-server redis.conf
cd ..
cd redis05
./redis-server redis.conf
cd ..
cd redis06
./redis-server redis.conf
cd ..
給start-all.sh文件授權
chmod u+x start-all.sh
第三步:將redis-3.0.0/src目錄下的 redis-trib.rb文件複製到redis集羣目錄下
創建關閉集羣的腳本:
[root@localhost redis-cluster]# vim shutdow-all.sh
redis01/redis-cli -p 7001 shutdown
redis02/redis-cli -p 7002 shutdown
redis03/redis-cli -p 7003 shutdown
redis04/redis-cli -p 7004 shutdown
redis05/redis-cli -p 7005 shutdown
redis06/redis-cli -p 7006 shutdown
[root@localhost redis-cluster]# chmod u+x shutdow-all.sh
第四步:使用ruby腳本搭建集羣。
./redis-trib.rb create –replicas 1 192.168.25.153:7001 192.168.25.153:7002 192.168.25.153:7003 192.168.25.153:7004 192.168.25.153:7005 192.168.25.153:7006
[root@localhost redis-cluster]# ./redis-trib.rb create --replicas 1 192.168.25.153:7001 192.168.25.153:7002 192.168.25.153:7003 192.168.25.153:7004 192.168.25.153:7005 192.168.25.153:7006
1.2.集羣的使用
1.2.1.Redis-cli連接集羣。
[root@localhost redis-cluster]# redis01/redis-cli -p 7002 -c
1.2.2.使用Jedis
編寫Jedis工具類(接口+單機版實現類+集羣版實現類)
public interface JedisClient {
String set(String key, String value);
String get(String key);
Boolean exists(String key);
Long expire(String key, int seconds);
Long ttl(String key);
Long incr(String key);
Long hset(String key, String field, String value);
String hget(String key, String field);
Long hdel(String key, String...field);
}
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class JedisClientPool implements JedisClient {
private JedisPool jedisPool;
public JedisPool getJedisPool() {
return jedisPool;
}
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String result = jedis.set(key, value);
jedis.close();
return result;
}
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String result = jedis.get(key);
jedis.close();
return result;
}
@Override
public Boolean exists(String key) {
Jedis jedis = jedisPool.getResource();
Boolean result = jedis.exists(key);
jedis.close();
return result;
}
@Override
public Long expire(String key, int seconds) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.expire(key, seconds);
jedis.close();
return result;
}
@Override
public Long ttl(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.ttl(key);
jedis.close();
return result;
}
@Override
public Long incr(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.incr(key);
jedis.close();
return result;
}
@Override
public Long hset(String key, String field, String value) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hset(key, field, value);
jedis.close();
return result;
}
@Override
public String hget(String key, String field) {
Jedis jedis = jedisPool.getResource();
String result = jedis.hget(key, field);
jedis.close();
return result;
}
@Override
public Long hdel(String key, String...field) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hdel(key, field);
jedis.close();
return result;
}
}
import redis.clients.jedis.JedisCluster;
public class JedisClientCluster implements JedisClient {
private JedisCluster jedisCluster;
public JedisCluster getJedisCluster() {
return jedisCluster;
}
public void setJedisCluster(JedisCluster jedisCluster) {
this.jedisCluster = jedisCluster;
}
@Override
public String set(String key, String value) {
return jedisCluster.set(key, value);
}
@Override
public String get(String key) {
return jedisCluster.get(key);
}
@Override
public Boolean exists(String key) {
return jedisCluster.exists(key);
}
@Override
public Long expire(String key, int seconds) {
return jedisCluster.expire(key, seconds);
}
@Override
public Long ttl(String key) {
return jedisCluster.ttl(key);
}
@Override
public Long incr(String key) {
return jedisCluster.incr(key);
}
@Override
public Long hset(String key, String field, String value) {
return jedisCluster.hset(key, field, value);
}
@Override
public String hget(String key, String field) {
return jedisCluster.hget(key, field);
}
@Override
public Long hdel(String key, String...field) {
return jedisCluster.hdel(key, field);
}
}
在spring配置文件中配置
<!-- 單機方式 -->
<!-- 註冊jedis連接池 -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="192.168.25.128"/>
<constructor-arg name="port" value="6379"/>
</bean>
<!-- 註冊jedis連接池 -->
<bean id="jedisClient" class="cn.e3maill.commonjedis.JedisClientPool">
<property name="jedisPool" ref="jedisPool"/>
</bean>
<!-- 集羣方式 -->
<!-- 註冊JedisClientCluster -->
<!-- <bean id="jedisClientCluster" class="cn.e3maill.commonjedis.JedisClientCluster">
<property name="jedisCluster" ref="jedisCluster"/>
</bean> -->
<!-- 註冊 -->
<!-- <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128"/>
<constructor-arg name="port" value="7001"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128"/>
<constructor-arg name="port" value="7002"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128"/>
<constructor-arg name="port" value="7003"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128"/>
<constructor-arg name="port" value="7004"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128"/>
<constructor-arg name="port" value="7005"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.128"/>
<constructor-arg name="port" value="7006"/>
</bean>
</set>
</constructor-arg>
</bean> -->
</beans>
在代碼中實現
public List<Content> findContentListByCid(Long cid) {
// 查詢緩存
try {
String json = jedisClient.hget(CONTENT_LIST, cid + "");
if (StringUtils.isNotBlank(json)) {
// 存在,直接返回
return JsonUtils.jsonToList(json, Content.class);
}
} catch (Exception e) {
e.printStackTrace();
}
// 不存在,查詢數據庫
// 設置查詢條件
ContentExample example = new ContentExample();
Criteria criteria = example.createCriteria();
criteria.andCategoryIdEqualTo(cid);
// 執行查詢
List<Content> contents = contentMapper.selectByExampleWithBLOBs(example);
try {
// 將集合保存到緩存中
jedisClient.hset(CONTENT_LIST, cid + "", JsonUtils.objectToJson(contents));
} catch (Exception e) {
e.printStackTrace();
}
return contents;
}
添加刪除時的緩存同步
刪除緩存中的key(省略)