Spring之redis主从复制(非哨兵模式)

看了好几天redis了,公司从刚开始的redisluster变成了redis主从,原因是rediscluster不可控,其实是我水平没到,万一出点啥事,我这个负责人都解决不了,那就完了!大数据平台下,如果缓存崩了,所有操作提前全都干到数据库,很能造成数据库的崩溃,所以改用简单的主从复制模式,这样即可控,又直观,下面我将自己这几天整理的代码整理如下:

注意:使用该代码前提是:成功安装redis并已经启动redis主从服务,否则拒绝连接,那是很。。。的

工程目录:

本人习惯:按目录顺序一次往下帖代码

1、创建加载连接池工具

package com.test.connection;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class ClientConnect {

//主库
     private JedisPool masterJedisPool;  
     //从库
     private JedisPool slaveJedisPool;

//设置主库
     public void setMasterJedisPool(JedisPool masterJedisPool) {
         this.masterJedisPool = masterJedisPool;
     }
     //设置从库
     public void setSlaveJedisPool(JedisPool slaveJedisPool) {    
          this.slaveJedisPool = slaveJedisPool;
     }  
    
     //获取主库
     public Jedis getMasterJedisPool() {
        return masterJedisPool.getResource();
    }
    
     //获取从库
    public Jedis getSlaveJedisPool() {
        return slaveJedisPool.getResource();
    }
    
    //关闭主库
    public void masterClose(JedisPool masterJedisPool){
        masterJedisPool.close();
    }
    
    //关闭从库
     public void slaveClose(JedisPool slaveJedisPool){
        
         slaveJedisPool.close();
     }
}

2、为了好看和隐私性强,创建加载路径

package com.test.constant;

public class SysConstants {

public static final String PATH = "classpath:/context/applicationContext.xml";
    public static final String BEAN="clientConnect";
}

3、创建实体类

package com.test.entities;

public class User {

protected String companyId;
    public String getCompanyId() {
        return companyId;
    }
    public void setCompanyId(String companyId) {
        this.companyId = companyId;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getTell() {
        return tell;
    }
    public void setTell(String tell) {
        this.tell = tell;
    }
    protected String id;
    protected String name;
    protected String age;
    protected String address;
    protected String tell;
}

4、创建操作主数据库的工具方法:
package com.test.Impl;

import java.util.List;

import com.test.entities.User;

import redis.clients.jedis.Jedis;
/**
 *
 * @author root
 *操作主库,实现增、删、改功能
 */
public class MasterRedisImpl {

Jedis jedis;
    public MasterRedisImpl(Jedis jedis){
        this.jedis=jedis;
    }
    
    /**
     * 添加
     * @param list
     */
    public void INSERT(List<User> list) {
        
        for(int i=0;i<list.size();i++){
            User user=list.get(i);

//主键
            String key = "user:userId:"+user.getId();
            //值1
            String field1 = "name:";  
            String value1 = user.getName();
            jedis.hset(key, field1, value1);
            
            //值2
            String field2 = "age:";  
            String value2 = user.getAge();  
            jedis.hset(key, field2, value2);

//值3
            String field3 = "address:";  
            String value3 = user.getAddress();  
            jedis.hset(key, field3, value3);
            
            
            //值4
            String field4 = "tell:";  
            String value4 = user.getTell();  
            jedis.hset(key, field4, value4);    
            
            
            
            /**
             * 添加键值list
             * key1=user:userId:    
             * value1=1,2,3,4,5,6
             *
             * key2=user:name:
             * value2=zhao,hai,dong
             *
             * key3=user:age
             * value3=11,12 ,12,13
             */
            //id->list
            String listKey="user:userId:";
            String listValue="user:userId:"+user.getId();
            
            jedis.lpush(listKey, listValue);
            //name->list
            String listKey1="user:name:";
            String listValue1="user:name:"+user.getName()+":"+user.getId();
            
            jedis.rpush(listKey1, listValue1);
            
            
//            添加外键
            
            jedis.sadd("user:userId:"+user.getId()+":companyId:", user.getCompanyId());
        }
        
        
        
    }
    
    /**
     * 删除hash表中指定key的n个指定字段
     *
     * @param key
     * @param fields
     */
    public void DELETE(String key,String []fields){
        String field=null;
        for(int i=0;i<fields.length;i++){
            field=fields[i];
            jedis.hdel(key, field); //删除xjj.h1中的f1和f2  
        }
    }
    
    /**
     * 删除hash表中指定key的所有字段
     */
    public void DELETEVALUE(String key){  
        jedis.del(key);  
    }
    
    /**
     * 移除集合中一个或多个成员
     */
    public void DELETESET(String key,String []fields){
    
        String field=null;
        for(int i=0;i<fields.length;i++){
            field=fields[i];  
            jedis.srem(key, field);
        }
        
    }
    
    /**
     * LPOP key:移出并获取列表的第一个元素
     * @param key
     */
    public String DELETELIST(String key){
        
        return jedis.lpop(key);
    }  
}
5、创建操作从数据库的工具方法:
package com.test.Impl;

import java.util.List;
import java.util.Set;

import redis.clients.jedis.Jedis;

/**
 *
 * @author root
 *读取从库读数据
 */
public class SlaveRedisImpl {

Jedis jedis;
    public SlaveRedisImpl(Jedis slaveJedis) {
        this.jedis=slaveJedis;
    }

/**
     * 查询
     * 返回哈希表 key中给定域 field的值
     */
    public String SELECT(String key,String field){
        
        return jedis.hget(key, field);
        
    }
    public String SELECT(String key){
        
        return jedis.get(key);
        
    }
    
    /**
     * 查询list,获取指定位置的元素
     * @param key
     * @return
     */
    public List<String> SELECTLIST(String key,int start,int end){
        
        return jedis.lrange(key, start, end);
        
        
    }

/**
     * 在set中获取key对应所有的vlaue
     * @param key
     * @return
     */
    public Set<String> SELECTSET(String key){
        return jedis.smembers(key);
    }
    
}
6、创建applicationContext.xml
<?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"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd              
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
 
   <context:property-placeholder location="classpath:/property/redis.properties" />
        <!-- 连接池配置 -->
        <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
            <property name="maxIdle" value="${redis.maxIdle}" />  
            <property name="maxTotal" value="${redis.maxTotal}" />  
            <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />  
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
        </bean>
       <!-- 连接池 -->
      <bean id="masterJedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg index="0" ref="poolConfig"/>
        <constructor-arg index="1" value="127.0.0.1" type="java.lang.String"/>
        <constructor-arg index="2" value="6379" type="int"/>
    </bean>

<bean id="slaveJedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg index="0" ref="poolConfig"/>
        <constructor-arg index="1" value="127.0.0.1" type="java.lang.String"/>
        <constructor-arg index="2" value="6380" type="int"/>
    </bean>

<bean id="clientConnect" class="com.test.connection.ClientConnect">
        <property name="masterJedisPool" ref="masterJedisPool"/>
        <property name="slaveJedisPool" ref="slaveJedisPool"/>
    </bean>
      
     
</beans>

连接池配置文件redis.properties:
    redis.maxIdle=300  
    redis.maxTotal=600  
    redis.maxWaitMillis=1000  
    redis.testOnBorrow=true 

下来当然是测试了:

package com.test.main;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.Impl.MasterRedisImpl;
import com.test.Impl.SlaveRedisImpl;
import com.test.connection.ClientConnect;
import com.test.constant.SysConstants;
import com.test.entities.User;

import redis.clients.jedis.Jedis;

public class Test {

/**
     * 节点信息
     * [email protected]
     * [email protected]
     * @param args
     */
    
    public static void main(String[] args) {
        @SuppressWarnings("resource")
        ApplicationContext ctx = new ClassPathXmlApplicationContext(SysConstants.PATH);
        ClientConnect redisUtils = (ClientConnect) ctx.getBean(SysConstants.BEAN);
        
        List<User>list=new ArrayList<>();
        
        for(int i=0;i<10;i++){
            User user=new User();
            user.setId(i+"");
            user.setAddress("gansu"+i);
            user.setAge(i+"");
            user.setName("zhd"+i);
            user.setCompanyId("1010111"+i);
            user.setTell("15309853180");
            list.add(user);
        }
        
        
        //获取主redis库
        Jedis mastrJedis=redisUtils.getMasterJedisPool();
        //操作主redis库
        MasterRedisImpl mastedao=new MasterRedisImpl(mastrJedis);
        
        //添加数据
        mastedao.INSERT(list);
        
        //获取从redis库
        Jedis slaveJedis=redisUtils.getSlaveJedisPool();
        
        //操作从redis库
        SlaveRedisImpl slavedao=new SlaveRedisImpl(slaveJedis);
        //查询
        String keyHash="user:userId:5";
        String filed="name:";
        String keyList="user:name:";
        int start=0;
        int end=2;
        String keySet="user:userId:4:companyId:";
        
        
        String hashValue=slavedao.SELECT(keyHash,filed);
        System.out.println("hashValue:"+hashValue);
        
        List<String> listValue=slavedao.SELECTLIST(keyList, start,end);
        System.out.println("listValue:"+listValue.toString());
        
        Set<String> valueSet=slavedao.SELECTSET(keySet);
        
        Iterator<String> it = valueSet.iterator();  
        while (it.hasNext()) {  
          String str = it.next();  
          System.out.println("valueSet:"+str);  
        }
    }
}

以上代码,是我自己整理的,并且完全可以使用的代码,小菜鸟门完全可以复制粘帖;

时间: 2024-08-09 23:56:17

Spring之redis主从复制(非哨兵模式)的相关文章

redis学习三,Redis主从复制和哨兵模式

Redis主从复制 java架构师项目实战,高并发集群分布式,大数据高可用,视频教程 1.Master可以拥有多个slave 2.多个slave可以连接同一个Master外,还可以连接到其他的slave 3.主从复制不会阻塞Master在主从复制时,Master可以处理client请求. 4.提供系统的伸缩性. 主从复制的过程 1.slave与Master建立连接,发送sync同步命令. 也就是说当用户在Master写入一条命令后,他们之间会通过一些算法把数据同步到每一个slave上. 2.Ms

Redis主从复制、哨兵模式

1.部署主从 环境:主IP:10.0.0.15,端口6379;从IP:10.0.0.16,端口6379. 原理:基于RDB持久化的功能来实现主从复制的功能. a.linux-redis1(10.0.0.15) cd /usr/local/redis/ grep "^[a-Z]" redis.conf # 列出几个修改过的配置 bind 10.0.0.15 protected-mode no port 6379 daemonize yes loglevel notice logfile

Redis主从复制之哨兵模式(sentinel)

介绍:反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库 调整结构:6379带着80.81 自定义的/myredis目录下新建sentinel.conf文件,名字绝不能错 配置哨兵,填写内容,sentinel monitor 被监控数据库名字(自己起名字) 127.0.0.1 6379 1 ,上面最后一个数字1,表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机 启动哨兵 正常主从演示 主机master挂了 投票选取 选81为主机  问题:如果

redis的主从复制和哨兵模式

Redis主从复制是什么? 行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主 Redis主从复制能干些什么? (1)读写分离 (2)容灾恢复 Redis配置主从复制(1主2从) 知识注意: (1)配从(库)不配主(库) (2)从库配置:slaveof 主库IP 主库端口 (3)info replication查看当前redis节点信息(是主还是从等等) redis配置1主2从 开始配置: 这里

redis 主从同步&amp;哨兵模式&amp;codis

原文:redis 主从同步&哨兵模式&codis 主从同步 1.CPA原理 1. CPA原理是分布式存储理论的基石: C(一致性):   A(可用性):  P(分区容忍性); 2. 当主从网络无法连通时,修改操作无法同步到节点,所以"一致性"无法满足 3. 除非我们牺牲"可用性",也就是暂停分布式节点服务,不再提供修改数据功能,知道网络恢复 一句话概括CAP: 当网络分区发生时,一致性 和 可用性 两难全 2.redis主从同步介绍 1. 和MySQ

3台服务器Redis高可用哨兵模式

3台服务器Redis高可用哨兵模式 学习 redis 高可用 3台服务器Redis高可用哨兵模式 3.1 主redis配置 3.2 从redis配置 1. 介绍 2. redis程序安装 3. 哨兵模式配置 3.3 启动redis和哨兵 4. 总结 1. 介绍 Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务: 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常. 提醒(Notifi

Redis 主从复制与哨兵

原文:Redis 主从复制与哨兵 Redis 可以使用从属服务器来实现读写分离提高吞吐量或在主服务器故障时接替主服务器以提高可用性. 每个 Redis 服务器实例都可以配置多个 slave 节点,slave 服务器也可以拥有次级 slave 节点, 可以组织成复杂的树状结构(虽说生产环境下极少有人这么做). 配置主从复制 为了尝试配置主从复制,我们至少需要两个 redis 服务器实例.最简单的方法是在 redis 官网下载 redis-server 二进制可执行文件,分别放在 master 和

学习记录02 --- redis数据库的安装,以及主从复制和哨兵模式开启

emmmmmm,这个其实是28号老师布置下来的任务,但博客今天才开,思来想去还是把昨天的给补上吧,按住顺序来吧! 1.redis的安装 redis数据库的安装并不难,首先安装好依赖,因为redis是C语言编写,需要安装gcc来编译 yum install gcc-c++ -y(安装gcc) 执行上面的命令就安装完了gcc,接下来我们需要一个目录,用来安装redis 我是安装在/usr/local/redis里面的,所以直接执行下面的代码就可以创建一个目录 mkdir /usr/local/red

Redis篇6-replication主从复制与哨兵模式

概述 官方说明:https://redis.io/topics/replication 作用:读(Slave)写(Master)分离,容灾恢复 哨兵模式可以实现无人值守 缺点:主从复制无疑会带来延迟(Master机器同步到Slave机器),使用哨兵模式则延迟会更明显. 测试配置准备(一台主机两台备机) 拷贝多个配置文件分别命名区分 redis{port}.conf Master 端口6379 Slave1 端口6380 Slave2 端口6381 其他方便区别配置 使用后台方式启动服务 daem

Springboot2.x整合Redis以及连接哨兵模式/集群模式

依赖: <!--spirngboot版本为2.x--><!-- 加载spring boot redis包,springboot2.0中直接使用jedis或者lettuce配置连接池,默认为lettuce连接池,这里使用jedis连接池 --><!-- 加载spring boot redis包 --><dependency> <groupId>org.springframework.boot</groupId> <artifact