赞
踩
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的值也发生了变化:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。