搭建Redis集羣,Java操做redis(Demo:緩存數據庫查詢數據,當進行增刪改方法時,刪除緩存)

redis-cluster架構圖

架構細節:java

(1)全部的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬node

(2)節點的fail是經過投票機制即集羣中超過半數的節點檢測失效時才生效redis

(3)客戶端與redis節點直連,不須要中間proxy層.客戶端不須要鏈接集羣全部節點,鏈接集羣中任何一個可用節點便可算法

(4)redis-cluster把全部的物理節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->valuespring

Redis 集羣中內置了 16384 個哈希槽,當須要在 Redis 集羣中放置一個 key-value 時,redis 先對 key 使用 crc16 算法算出一個結果,而後把結果對 16384 求餘數,這樣每一個 key 都會對應一個編號在 0-16383 之間的哈希槽,redis 會根據節點數量大體均等的將哈希槽映射到不一樣的節點數據庫

Redis集羣的搭建

搭建資料編程

第一步:安裝redis

tar zxvf redis-3.2.5.tar.gz
  • 複製:推薦放到usr/local目錄下
sudo mv -r redis-3.2.3/* /usr/local/redis/
進入redis目錄
cd /usr/local/redis/
  • 生成
sudo make
  • 測試
sudo make test
這段運行時間會較長,能夠略過
  • 安裝:將redis的命令安裝到/usr/bin/目錄
sudo make install

第二步:搭建僞Redis集羣的準備工做

  • 使用命令生成可執行文件到指定目錄下(由於須要6個可執行的redis-server)

sudo make install PREFIX=/usr/local/redis-clusterjson

  • 將/usr/local/redis目錄下的redis.conf文件copy一份到剛生成的目錄中,並修改該配置文件

緩存

  • 書寫腳本運行全部6個redis

cd redis01
./redis-server redis.conf
cd ..ruby

第三步:安裝ruby和相關的包

  • 安裝

 sudo apt-get install ruby

  • 安裝redis-3.0.0.gem 

 sudo gem install redis-3.0.0.gem

  • 將/usr/local/redis/src目錄下的redis-trib.rb文件copy到任意位置
  •  執行命令運行起來redis集羣
./redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
真正創建redis集羣時,更改成運行redis主機們的ip地址(要關閉防火牆)

第四步:使用集羣

redis-cli -p 7002 -c  # -c表示操做的是集羣

Java操做redis

一、導入Jedis包

<!-- Redis客戶端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>

二、操做redis

1)直接操做版

@Test
public void JedisClient(){

    // 1.建立一個Jedis對象。須要指定服務端的ip及端口
    Jedis jedis = new Jedis("127.0.0.1", 6379);
    // 2.使用Jedis對象操做數據庫
    jedis.set("k1","v1");
    String k1 = jedis.get("k1");
    System.out.println(k1);
    // 3.關閉Jedis對象
    jedis.close();

}

2)鏈接池版

@Test
public void JedisPool(){

    // 1.建立一個JedisPool對象。須要指定服務端的ip及端口
    JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
    // 2.從JedisPool中得到Jedis對象
    Jedis jedis = jedisPool.getResource();
    // 3.使用Jedis操做redis服務器
    jedis.set("k2","v2");
    String k1 = jedis.get("k2");
    System.out.println(k1);
    // 4.操做完畢後關閉jedis對象,鏈接池回收資源
    jedis.close();
    // 5.關閉JedisPool對象
    jedisPool.close();

}

3)鏈接集羣版

@Test
// 集羣默認使用的就是鏈接池,因此不用咱們來配了
public void JedisCluster(){

    // 1.使用JedisCluster對象。須要一個Set<HostAndPort>參數。Redis節點的列表。
    Set<HostAndPort> nodes = new HashSet<>();
    nodes.add(new HostAndPort("127.0.0.1", 7001));
    nodes.add(new HostAndPort("127.0.0.1", 7002));
    nodes.add(new HostAndPort("127.0.0.1", 7003));
    nodes.add(new HostAndPort("127.0.0.1", 7004));
    nodes.add(new HostAndPort("127.0.0.1", 7005));
    nodes.add(new HostAndPort("127.0.0.1", 7006));

    // 2.直接使用JedisCluster對象操做redis。在系統中單例存在。
    JedisCluster jedisCluster = new JedisCluster(nodes);
    jedisCluster.set("k3", "v3");
    String result = jedisCluster.get("k3");
    System.out.println(result);
    // 3.系統關閉前,關閉JedisCluster對象。
    jedisCluster.close();

}

項目整合

緩存數據庫查詢數據,當進行增刪改方法時,刪除緩存;因爲咱們平時用單機版的就好了,項目發佈時在使用集羣版,因此咱們能夠採用面向接口編程;緩存是在service中配置的

 1 public interface JedisClient {
 2 
 3     String set(String key, String value);
 4     String get(String key);
 5     Boolean exists(String key);
 6     Long expire(String key, int seconds);
 7     Long ttl(String key);
 8     Long incr(String key);
 9     Long hset(String key, String field, String value);
10     String hget(String key, String field);
11     Long hdel(String key, String... field);
12     Boolean hexists(String key, String field);
13     List<String> hvals(String key);
14     Long del(String key);
15 }
Jedis操做的接口
  1 package cn.e3mall.common.jedis;
  2 
  3 import java.util.List;
  4 
  5 import redis.clients.jedis.Jedis;
  6 import redis.clients.jedis.JedisPool;
  7 
  8 public class JedisClientPool implements JedisClient {
  9     
 10     private JedisPool jedisPool;
 11 
 12     public JedisPool getJedisPool() {
 13         return jedisPool;
 14     }
 15 
 16     public void setJedisPool(JedisPool jedisPool) {
 17         this.jedisPool = jedisPool;
 18     }
 19 
 20     @Override
 21     public String set(String key, String value) {
 22         Jedis jedis = jedisPool.getResource();
 23         String result = jedis.set(key, value);
 24         jedis.close();
 25         return result;
 26     }
 27 
 28     @Override
 29     public String get(String key) {
 30         Jedis jedis = jedisPool.getResource();
 31         String result = jedis.get(key);
 32         jedis.close();
 33         return result;
 34     }
 35 
 36     @Override
 37     public Boolean exists(String key) {
 38         Jedis jedis = jedisPool.getResource();
 39         Boolean result = jedis.exists(key);
 40         jedis.close();
 41         return result;
 42     }
 43 
 44     @Override
 45     public Long expire(String key, int seconds) {
 46         Jedis jedis = jedisPool.getResource();
 47         Long result = jedis.expire(key, seconds);
 48         jedis.close();
 49         return result;
 50     }
 51 
 52     @Override
 53     public Long ttl(String key) {
 54         Jedis jedis = jedisPool.getResource();
 55         Long result = jedis.ttl(key);
 56         jedis.close();
 57         return result;
 58     }
 59 
 60     @Override
 61     public Long incr(String key) {
 62         Jedis jedis = jedisPool.getResource();
 63         Long result = jedis.incr(key);
 64         jedis.close();
 65         return result;
 66     }
 67 
 68     @Override
 69     public Long hset(String key, String field, String value) {
 70         Jedis jedis = jedisPool.getResource();
 71         Long result = jedis.hset(key, field, value);
 72         jedis.close();
 73         return result;
 74     }
 75 
 76     @Override
 77     public String hget(String key, String field) {
 78         Jedis jedis = jedisPool.getResource();
 79         String result = jedis.hget(key, field);
 80         jedis.close();
 81         return result;
 82     }
 83 
 84     @Override
 85     public Long hdel(String key, String... field) {
 86         Jedis jedis = jedisPool.getResource();
 87         Long result = jedis.hdel(key, field);
 88         jedis.close();
 89         return result;
 90     }
 91 
 92     @Override
 93     public Boolean hexists(String key, String field) {
 94         Jedis jedis = jedisPool.getResource();
 95         Boolean result = jedis.hexists(key, field);
 96         jedis.close();
 97         return result;
 98     }
 99 
100     @Override
101     public List<String> hvals(String key) {
102         Jedis jedis = jedisPool.getResource();
103         List<String> result = jedis.hvals(key);
104         jedis.close();
105         return result;
106     }
107 
108     @Override
109     public Long del(String key) {
110         Jedis jedis = jedisPool.getResource();
111         Long result = jedis.del(key);
112         jedis.close();
113         return result;
114     }
115 
116 }
Jedis操做單機版的實現類
 1 package cn.e3mall.common.jedis;
 2 
 3 import java.util.List;
 4 
 5 import redis.clients.jedis.JedisCluster;
 6 
 7 public class JedisClientCluster implements JedisClient {
 8     
 9     private JedisCluster jedisCluster;
10     
11 
12     public JedisCluster getJedisCluster() {
13         return jedisCluster;
14     }
15 
16     public void setJedisCluster(JedisCluster jedisCluster) {
17         this.jedisCluster = jedisCluster;
18     }
19 
20     @Override
21     public String set(String key, String value) {
22         return jedisCluster.set(key, value);
23     }
24 
25     @Override
26     public String get(String key) {
27         return jedisCluster.get(key);
28     }
29 
30     @Override
31     public Boolean exists(String key) {
32         return jedisCluster.exists(key);
33     }
34 
35     @Override
36     public Long expire(String key, int seconds) {
37         return jedisCluster.expire(key, seconds);
38     }
39 
40     @Override
41     public Long ttl(String key) {
42         return jedisCluster.ttl(key);
43     }
44 
45     @Override
46     public Long incr(String key) {
47         return jedisCluster.incr(key);
48     }
49 
50     @Override
51     public Long hset(String key, String field, String value) {
52         return jedisCluster.hset(key, field, value);
53     }
54 
55     @Override
56     public String hget(String key, String field) {
57         return jedisCluster.hget(key, field);
58     }
59 
60     @Override
61     public Long hdel(String key, String... field) {
62         return jedisCluster.hdel(key, field);
63     }
64 
65     @Override
66     public Boolean hexists(String key, String field) {
67         return jedisCluster.hexists(key, field);
68     }
69 
70     @Override
71     public List<String> hvals(String key) {
72         return jedisCluster.hvals(key);
73     }
74 
75     @Override
76     public Long del(String key) {
77         return jedisCluster.del(key);
78     }
79 
80 }
集羣版實現類

application-redis.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
	
	<!-- 鏈接redis單機版 -->
	<bean id="jedisClientPool" class="cn.e3mall.common.jedis.JedisClientPool">
		<property name="jedisPool" ref="jedisPool"></property>
	</bean>
	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
		<constructor-arg name="host" value="127.0.0.1"/>
		<constructor-arg name="port" value="6379"/>
	</bean>
	
	<!-- 鏈接redis集羣 -->
	<bean id="jedisClientCluster" class="cn.e3mall.common.jedis.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="127.0.0.1"/>
					<constructor-arg name="port" value="7001"/>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="7002"/>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="7003"/>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="7004"/>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="7005"/>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="127.0.0.1"/>
					<constructor-arg name="port" value="7006"/>
				</bean> 
			</set>
		</constructor-arg>
	</bean>
</beans>

新增緩存後

@Service
@Transactional
public class ContentServiceImpl implements ContentService {

    @Autowired
    private TbContentMapper contentMapper;

    @Autowired
    private JedisClient jedisClient;


    @Value("${CONTENT_LIST}")
    private String CONTENT_LIST;

    /**
     * 保存(大廣告..)內容
     * @param content
     * @return
     */
    @Override
    public E3Result save(TbContent content) {

        // 1.封裝參數
        content.setCreated(new Date());
        content.setCreated(new Date());

        // 2.插入
        contentMapper.insert(content);

        try {
            jedisClient.hdel(CONTENT_LIST,content.getCategoryId().toString());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 3.返回
        return E3Result.ok();
    }

    /**
     * 根據分類id,取出各個分類的數據
     * @param i
     * @return
     */
    @Override
    public List<TbContent> findByCategoryId(Long i) {

        try{
            // 1)先從redis緩存中獲取,須要的是字符串格式
            String json = jedisClient.hget(CONTENT_LIST, i + "");
            // 2)轉成list
            if(StringUtils.isNotBlank(json)){
                List<TbContent> list = JsonUtils.jsonToList(json, TbContent.class);
                return list;
            }
        } catch (Exception ex){
            ex.printStackTrace();
        }

        // 1.設置查詢條件
        TbContentExample example = new TbContentExample();
        TbContentExample.Criteria criteria = example.createCriteria();
        criteria.andCategoryIdEqualTo(i);
        // 2.執行查詢並返回
        List<TbContent> list = contentMapper.selectByExampleWithBLOBs(example);

        try {
            // 1)將list轉成字符串
            String json = JsonUtils.objectToJson(list);
            // 2)設置到redis中
            jedisClient.hset(CONTENT_LIST,i+"",json);

        }catch (Exception ex){
            ex.printStackTrace();
        }

        return list;
    }
}
相關文章
相關標籤/搜索