redis 主從模式的配置

redis單例提供了一種數據緩存方式和豐富的數據操作api,但是將數據完全存儲在單個redis中主要存在兩個問題:數據備份和數據體量較大造成的性能降低。這裏redis的主從模式爲這兩個問題提供了一個較好的解決方案。

主從模式指的是使用一個redis實例作爲主機,其餘的實例作爲備份機。主機和從機的數據完全一致,主機支持數據的寫入和讀取等各項操作,而從機則只支持與主機數據的同步和讀取,也就是說,客戶端可以將數據寫入到主機,由主機自動將數據的寫入操作同步到從機。

主從模式很好的解決了數據備份問題,並且由於主從服務數據幾乎是一致的,因而可以將寫入數據的命令發送給主機執行,
而讀取數據的命令發送給不同的從機執行,從而達到讀寫分離的目的。如下所示主機redis-A分別有redis-B、redis-C、redis-D、redis-E四個從機:

在這裏插入圖片描述
一:搭建Redis的主從模式環境:
redis主從模式的配置可以理解爲多個不同的redis實例通過一定的配置告知其相互之間的主從關係。

而前面已經介紹,每個redis實例都會佔用一個本機的端口號,主從模式的配置主要的配置點有兩個:當前實例端口號和當前實例是主機還是從機,是從機的話其主機的ip和端口是什麼。一般的redis目錄下的redis.conf保存的是默認配置,儘量不要對其進行修改,這裏我們複製三份redis.conf文件,分別命名爲6379.conf,6380.conf和6381.conf,如下是端口爲6379的主機的主要配置:
每一個對應的配置如下,注意修改端口號和主機名稱

bind 127.0.0.1
port 6381
logfile "6381.log"
dbfilename "dump-6381.rdb"
slaveof 127.0.0.1 6379

依次修改配置後啓動:

./src/redis-server 6379.conf
./src/redis-server 6380.conf
./src/redis-server 6381.conf

分別在三個命令行工具中執行一個get命令,獲取鍵名爲msg的數據,如下所示:
在這裏插入圖片描述

客戶端連接:
採用Redission客戶端進行連接:
導入依賴如下:

 <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>2.6.0</version>
        </dependency>
package com.ishangjie.config;

import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.client.codec.Codec;
import org.redisson.codec.CodecProvider;
import org.redisson.config.Config;
import org.redisson.liveobject.provider.ResolverProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * redisson分佈式鎖解決方案
 * @author liuty
 *
 */
@Configuration
public class RedissonProxy implements RedissonClient{

	@Value("${redis.hostname}")
	private String hostName;

	@Value("${redis.port}")
	private String port;


	private String password;

	@Value("${redis.connectionMinimumIdleSize}")
	private int connectionMinimumIdleSize;

	@Value("${redis.connectionPoolSize}")
	private int connectionPoolSize;

	private int connectTimeout = 10000;

	/**
	 * Redis server response timeout. Starts to countdown when Redis command was succesfully sent.
	 * Value in milliseconds.
	 *
	 */
	private int timeout = 3000;
	
	private RedissonClient delegateRedissonClient;
	
	public String getHostName() {
		return hostName;
	}

	public void setHostName(String hostName) {
		this.hostName = hostName;
	}

	public String getPort() {
		return port;
	}

	public void setPort(String port) {
		this.port = port;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	public int getConnectionPoolSize() {
		return connectionPoolSize;
	}

	public void setConnectionPoolSize(int connectionPoolSize) {
		this.connectionPoolSize = connectionPoolSize;
	}

	@PostConstruct
	public void init() {
		Config config = new Config();
		String address = hostName + ":" + port;
        config.useSingleServer()
        	  .setAddress(address)
        	  .setPassword(password)
				.setConnectionMinimumIdleSize(connectionMinimumIdleSize)
        	  .setConnectionPoolSize(connectionPoolSize)
                .setTimeout(timeout)
                .setConnectTimeout(connectTimeout);
        delegateRedissonClient = Redisson.create(config);
	}

	@Override
	public RBinaryStream getBinaryStream(String name) {
		return delegateRedissonClient.getBinaryStream(name);
	}

	@Override
	public <V> RGeo<V> getGeo(String name) {
		return delegateRedissonClient.getGeo(name);
	}

	@Override
	public <V> RGeo<V> getGeo(String name, Codec codec) {
		return delegateRedissonClient.getGeo(name, codec);
	}

	@Override
	public <V> RSetCache<V> getSetCache(String name) {
		return delegateRedissonClient.getSetCache(name);
	}

	@Override
	public <V> RSetCache<V> getSetCache(String name, Codec codec) {
		return delegateRedissonClient.getSetCache(name, codec);
	}

	@Override
	public <K, V> RMapCache<K, V> getMapCache(String name, Codec codec) {
		return delegateRedissonClient.getMapCache(name, codec);
	}

	@Override
	public <K, V> RMapCache<K, V> getMapCache(String name) {
		return delegateRedissonClient.getMapCache(name);
	}

	@Override
	public <V> RBucket<V> getBucket(String name) {
		return delegateRedissonClient.getBucket(name);
	}

	@Override
	public <V> RBucket<V> getBucket(String name, Codec codec) {
		return delegateRedissonClient.getBucket(name, codec);
	}

	@Override
	public RBuckets getBuckets() {
		return delegateRedissonClient.getBuckets();
	}

	@Override
	public RBuckets getBuckets(Codec codec) {
		return delegateRedissonClient.getBuckets(codec);
	}

	@Override
	public <V> RHyperLogLog<V> getHyperLogLog(String name) {
		return delegateRedissonClient.getHyperLogLog(name);
	}

	@Override
	public <V> RHyperLogLog<V> getHyperLogLog(String name, Codec codec) {
		return delegateRedissonClient.getHyperLogLog(name, codec);
	}

	@Override
	public <V> RList<V> getList(String name) {
		return delegateRedissonClient.getList(name);
	}

	@Override
	public <V> RList<V> getList(String name, Codec codec) {
		return delegateRedissonClient.getList(name, codec);
	}

	@Override
	public <K, V> RListMultimap<K, V> getListMultimap(String name) {
		
		return delegateRedissonClient.getListMultimap(name);
	}

	@Override
	public <K, V> RListMultimap<K, V> getListMultimap(String name, Codec codec) {
		
		return delegateRedissonClient.getListMultimap(name, codec);
	}

	@Override
	public <K, V> RListMultimapCache<K, V> getListMultimapCache(String name) {
		
		return delegateRedissonClient.getListMultimapCache(name);
	}

	@Override
	public <K, V> RListMultimapCache<K, V> getListMultimapCache(String name, Codec codec) {
		return delegateRedissonClient.getListMultimapCache(name, codec);
	}


	@Override
	public <K, V> RMap<K, V> getMap(String name) {
		return delegateRedissonClient.getMap(name);
	}

	@Override
	public <K, V> RMap<K, V> getMap(String name, Codec codec) {
		return delegateRedissonClient.getMap(name, codec);
	}

	@Override
	public <K, V> RSetMultimap<K, V> getSetMultimap(String name) {
		return delegateRedissonClient.getSetMultimap(name);
	}

	@Override
	public <K, V> RSetMultimap<K, V> getSetMultimap(String name, Codec codec) {
		return delegateRedissonClient.getSetMultimap(name, codec);
	}

	@Override
	public <K, V> RSetMultimapCache<K, V> getSetMultimapCache(String name) {
		return delegateRedissonClient.getSetMultimapCache(name);
	}

	@Override
	public <K, V> RSetMultimapCache<K, V> getSetMultimapCache(String name, Codec codec) {
		return delegateRedissonClient.getSetMultimapCache(name, codec);
	}

	@Override
	public RSemaphore getSemaphore(String name) {
		return delegateRedissonClient.getSemaphore(name);
	}

	@Override
	public RPermitExpirableSemaphore getPermitExpirableSemaphore(String name) {
		return delegateRedissonClient.getPermitExpirableSemaphore(name);
	}

	@Override
	public RLock getLock(String name) {
		return delegateRedissonClient.getLock(name);
	}

	@Override
	public RLock getFairLock(String name) {
		
		return delegateRedissonClient.getFairLock(name);
	}

	@Override
	public RReadWriteLock getReadWriteLock(String name) {
		
		return delegateRedissonClient.getReadWriteLock(name);
	}

	@Override
	public <V> RSet<V> getSet(String name) {
		
		return delegateRedissonClient.getSet(name);
	}

	@Override
	public <V> RSet<V> getSet(String name, Codec codec) {
		
		return delegateRedissonClient.getSet(name, codec);
	}

	@Override
	public <V> RSortedSet<V> getSortedSet(String name) {
		
		return delegateRedissonClient.getSortedSet(name);
	}

	@Override
	public <V> RSortedSet<V> getSortedSet(String name, Codec codec) {
		
		return delegateRedissonClient.getSortedSet(name, codec);
	}

	@Override
	public <V> RScoredSortedSet<V> getScoredSortedSet(String name) {
		
		return delegateRedissonClient.getScoredSortedSet(name);
	}

	@Override
	public <V> RScoredSortedSet<V> getScoredSortedSet(String name, Codec codec) {
		
		return delegateRedissonClient.getScoredSortedSet(name, codec);
	}

	@Override
	public RLexSortedSet getLexSortedSet(String name) {
		
		return delegateRedissonClient.getLexSortedSet(name);
	}

	@Override
	public <M> RTopic<M> getTopic(String name) {
		return delegateRedissonClient.getTopic(name);
	}

	@Override
	public <M> RTopic<M> getTopic(String name, Codec codec) {
		
		return delegateRedissonClient.getTopic(name, codec);
	}

	@Override
	public <M> RPatternTopic<M> getPatternTopic(String pattern) {
		return delegateRedissonClient.getPatternTopic(pattern);
	}

	@Override
	public <M> RPatternTopic<M> getPatternTopic(String pattern, Codec codec) {
		return delegateRedissonClient.getPatternTopic(pattern, codec);
	}

	
	@Override
	public <V> RQueue<V> getQueue(String name) {
		return delegateRedissonClient.getQueue(name);
	}

	
	@Override
	public <V> RQueue<V> getQueue(String name, Codec codec) {
		return delegateRedissonClient.getQueue(name, codec);
	}

	@Override
	public <V> RBlockingQueue<V> getBlockingQueue(String name) {
		return delegateRedissonClient.getBlockingDeque(name);
	}

	@Override
	public <V> RBlockingQueue<V> getBlockingQueue(String name, Codec codec) {
		return delegateRedissonClient.getBlockingQueue(name, codec);
	}

	@Override
	public <V> RBoundedBlockingQueue<V> getBoundedBlockingQueue(String name) {
		return delegateRedissonClient.getBoundedBlockingQueue(name);
	}

	@Override
	public <V> RBoundedBlockingQueue<V> getBoundedBlockingQueue(String name, Codec codec) {
		return delegateRedissonClient.getBoundedBlockingQueue(name, codec);
	}

	@Override
	public <V> RDeque<V> getDeque(String name) {
		return delegateRedissonClient.getDeque(name);
	}

	@Override
	public <V> RDeque<V> getDeque(String name, Codec codec) {
		return delegateRedissonClient.getDeque(name, codec);
	}

	@Override
	public <V> RBlockingDeque<V> getBlockingDeque(String name) {
		return delegateRedissonClient.getBlockingDeque(name);
	}

	@Override
	public <V> RBlockingDeque<V> getBlockingDeque(String name, Codec codec) {
		return delegateRedissonClient.getBlockingDeque(name, codec);
	}

	@Override
	public RAtomicLong getAtomicLong(String name) {
		return delegateRedissonClient.getAtomicLong(name);
	}

	@Override
	public RAtomicDouble getAtomicDouble(String name) {
		return delegateRedissonClient.getAtomicDouble(name);
	}

	@Override
	public RCountDownLatch getCountDownLatch(String name) {
		return delegateRedissonClient.getCountDownLatch(name);
	}

	@Override
	public RBitSet getBitSet(String name) {
		return delegateRedissonClient.getBitSet(name);
	}

	@Override
	public <V> RBloomFilter<V> getBloomFilter(String name) {
		return delegateRedissonClient.getBloomFilter(name);
	}

	@Override
	public <V> RBloomFilter<V> getBloomFilter(String name, Codec codec) {
		return delegateRedissonClient.getBloomFilter(name, codec);
	}

	@Override
	public RScript getScript() {
		return delegateRedissonClient.getScript();
	}

	@Override
	public RScheduledExecutorService getExecutorService(String name) {
		return delegateRedissonClient.getExecutorService(name);
	}

	@Override
	@Deprecated
	public RScheduledExecutorService getExecutorService(Codec codec, String name) {
		return delegateRedissonClient.getExecutorService(codec, name);
	}


	@Override
	public RRemoteService getRemoteService() {
		return delegateRedissonClient.getRemoteService();
	}

	@Override
	public RRemoteService getRemoteService(Codec codec) {
		return delegateRedissonClient.getRemoteService(codec);
	}

	@Override
	public RRemoteService getRemoteService(String name) {
		return delegateRedissonClient.getRemoteService(name);
	}

	@Override
	public RRemoteService getRemoteService(String name, Codec codec) {
		return delegateRedissonClient.getRemoteService(name, codec);
	}

	@Override
	public RBatch createBatch() {
		return delegateRedissonClient.createBatch();
	}

	@Override
	public RKeys getKeys() {
		return delegateRedissonClient.getKeys();
	}

	@Override
	public RLiveObjectService getLiveObjectService() {
		return delegateRedissonClient.getLiveObjectService();
	}

	@Override
	public void shutdown() {
		delegateRedissonClient.shutdown();
	}

	@Override
	public void shutdown(long quietPeriod, long timeout, TimeUnit unit) {
		delegateRedissonClient.shutdown(quietPeriod,timeout,unit);
	}

	@Override
	public Config getConfig() {
		return delegateRedissonClient.getConfig();
	}


	@Override
	public NodesGroup<Node> getNodesGroup() {
		return delegateRedissonClient.getNodesGroup();
	}

	@Override
	public ClusterNodesGroup getClusterNodesGroup() {
		return delegateRedissonClient.getClusterNodesGroup();
	}

	@Override
	public boolean isShutdown() {
		return delegateRedissonClient.isShutdown();
	}

	@Override
	public boolean isShuttingDown() {
		return delegateRedissonClient.isShuttingDown();
	}

	@Override
	public CodecProvider getCodecProvider() {
		return delegateRedissonClient.getCodecProvider();
	}

	@Override
	public <K, V> RLocalCachedMap<K, V> getLocalCachedMap(String key, LocalCachedMapOptions options) {
		return delegateRedissonClient.getLocalCachedMap(key, options);
	}

	@Override
	public <K, V> RLocalCachedMap<K, V> getLocalCachedMap(String key, Codec codec, LocalCachedMapOptions options) {
		return delegateRedissonClient.getLocalCachedMap(key, codec,options);
	}

	@Override
	public ResolverProvider getResolverProvider() {
		return delegateRedissonClient.getResolverProvider();
	}

	public int getConnectionMinimumIdleSize() {
		return connectionMinimumIdleSize;
	}

	public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) {
		this.connectionMinimumIdleSize = connectionMinimumIdleSize;
	}

	public int getConnectTimeout() {
		return connectTimeout;
	}

	public void setConnectTimeout(int connectTimeout) {
		this.connectTimeout = connectTimeout;
	}

	public int getTimeout() {
		return timeout;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}
}

application.yml 的配置信息如下

redis:
  hostname: 192.168.63.133
  port: 6379
  connectionMinimumIdleSize: 10
  connectTimeout: 1000
  timeout:  3000
  connectionPoolSize: 64

調用方式如下:

package com.ishangjie.controller;

import com.ishangjie.config.RedissonProxy;
import com.ishangjie.service.Aservice;
import org.redisson.api.RBucket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;

/**
 * @describe: 註冊功能
 * author: liutengyuan
 * @date: Created in 2019/2/27 16:19
 **/
@RestController
public class Acontroller {

    @Autowired
    private Aservice aservice;
    @Autowired
    RedissonProxy redissonProxy;

    public Acontroller() {
        System.out.println("Acontroller is been created, Aservice = " + aservice );
    }

    @PostConstruct
    public void init (){
        System.out.println("執行了postConstruct 方法");
    }

    @RequestMapping("/spring/A")
    public String getA(){
        RBucket<Object> key = redissonProxy.getBucket("key");
        key.set("aa");
        return (String) redissonProxy.getBucket("key").get();
    }
}

最後啓動Spring Boot 項目,在瀏覽器進行訪問URL:
在這裏插入圖片描述
而key的值也發生了變化:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章