Redis主从复制和主从切换

jopen 9年前

Redis的主从复制功能可以实现读写分离,一个主可以挂载多个从.从服务器只能实现读不可写.当主服务器挂掉之后,无法切换到从服务器写.通过Redis的Sentinel可以实现主从切换:当主服务器挂掉之后,自动将其中一个从服务器升级为主服务器


  1. 配置主从复制

    1. 建立从文件夹,譬如 /usr/local/slaves/下建立 6380 6381 两个文件夹(两个从服务器)

    2. 复制redis.conf到刚建立的两个文件夹中

    3. 修改redis.conf 中的

      1. port 6380

      2. slaveof 127.0.0.1 6379  ------ip表示主服务器的ip  端口表示主服务器端口

      3. 保存退出,另一个从服务器做同样修改,如果端口不是6380,修改断开即可,此处修改为6381

    4. 启动主服务器 redis-server redis.conf

    5. 进入从服务器文件夹,启动从服务器

    6. 查看主服务器信息:redis-cli -p 6379 info Replication,可以看到有两个从服务器

    7. redis-cli -p 6379 进去主服务器,存储数据 set key val

    8. 进入从服务器,redis-cli -p 6380 查看数据 get key  查看是否能取出数据

  2. 配置主从切换

    1. 新建文件 sentinel.conf

    2. 编辑文件

    3. ####master  sentinel.conf  ##sentinel实例之间的通讯端口  port 26379  ####sentinel需要监控的master信息:<mastername> <masterIP> <masterPort> <quorum>.  ####<quorum>应该小于集群中slave的个数,只有当至少<quorum>个sentinel实例提交"master失效" 才会认为master为ODWON("客观"失效) .  sentinel monitor mymaster 127.0.0.1 6381 1  sentinel down-after-milliseconds mymaster 1000  sentinel failover-timeout mymaster 180000  sentinel parallel-syncs mymaster 1
    4. 其他两个文件只需要修改端口即可

    5. 启动redis-sentinel sentinel.conf &

  3. 通过java读写主从服务器

    1. 需要添加Spring配置和其他两个jar包

    2. <properties>      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>      <springVersion>3.2.9.RELEASE</springVersion>  </properties>    <dependencies>      <dependency>          <groupId>org.apache.commons</groupId>          <artifactId>commons-pool2</artifactId>          <version>2.4.2</version>      </dependency>          <dependency>          <groupId>org.springframework.data</groupId>          <artifactId>spring-data-redis</artifactId>          <version>1.6.0.RELEASE</version>      </dependency>        <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-context</artifactId>          <version>${springVersion}</version>      </dependency>      <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-tx</artifactId>          <version>${springVersion}</version>      </dependency>      <dependency>          <groupId>org.springframework</groupId>          <artifactId>spring-context-support</artifactId>          <version>${springVersion}</version>      </dependency>      <dependency>          <groupId>cglib</groupId>          <artifactId>cglib-nodep</artifactId>          <version>3.1</version>      </dependency>          <dependency>          <groupId>org.apache.commons</groupId>          <artifactId>commons-lang3</artifactId>          <version>3.1</version>      </dependency>      <dependency>          <groupId>com.alibaba</groupId>          <artifactId>fastjson</artifactId>          <version>1.2.5</version>      </dependency>      <dependency>          <groupId>org.aspectj</groupId>          <artifactId>aspectjweaver</artifactId>          <version>1.8.2</version>      </dependency>        <dependency>          <groupId>junit</groupId>          <artifactId>junit</artifactId>          <version>4.8</version>          <scope>test</scope>      </dependency>      <dependency>          <groupId>net.sf.ehcache</groupId>          <artifactId>ehcache</artifactId>          <version>2.7.5</version>      </dependency>      <dependency>          <groupId>org.slf4j</groupId>          <artifactId>slf4j-api</artifactId>          <version>1.6.6</version>      </dependency>      <dependency>          <groupId>redis.clients</groupId>          <artifactId>jedis</artifactId>          <version>2.4.2</version>      </dependency>      <dependency>          <groupId>commons-pool</groupId>          <artifactId>commons-pool</artifactId>          <version>1.6</version>      </dependency>      <dependency>          <groupId>commons-logging</groupId>          <artifactId>commons-logging</artifactId>          <version>1.1.1</version>      </dependency>      <dependency>          <groupId>org.slf4j</groupId>          <artifactId>slf4j-log4j12</artifactId>          <version>1.7.10</version>          <scope>test</scope>      </dependency>  </dependencies>
    3. Spring配置

      1. <bean id="redisSentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">      <property name="master">          <bean class="org.springframework.data.redis.connection.RedisNode">              <property name="name" value="mymaster"/>          </bean>      </property>      <property name="sentinels">          <set>              <bean class="org.springframework.data.redis.connection.RedisNode">                  <constructor-arg name="host" value="127.0.0.1"></constructor-arg>                    <constructor-arg name="port" value="26479"></constructor-arg>              </bean>              <bean class="org.springframework.data.redis.connection.RedisNode">                  <constructor-arg name="host" value="127.0.0.1"></constructor-arg>                    <constructor-arg name="port" value="26579"></constructor-arg>              </bean>          </set>      </property>  </bean>    <bean id="jeidsConnectionFactory"          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">        <constructor-arg ref="redisSentinelConfiguration"/>    </bean>      <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">      <property name="connectionFactory" ref="jeidsConnectionFactory"/>  </bean>
    4. java测试

      1. import org.junit.Before;  import org.junit.Test;  import org.springframework.context.ApplicationContext;  import org.springframework.context.support.ClassPathXmlApplicationContext;  import org.springframework.dao.DataAccessException;  import org.springframework.data.redis.connection.RedisConnection;  import org.springframework.data.redis.core.RedisCallback;  import org.springframework.data.redis.core.RedisTemplate;    /**   * Created by vincent on 15-10-13.   */  public class CommonTest {        private ApplicationContext context ;        private RedisTemplate redisTemplate;      final String key ="key7";        @Before      public void init(){          context = new ClassPathXmlApplicationContext("applicationContext.xml");          redisTemplate= context.getBean("redisTemplate",RedisTemplate.class);      }        @Test      public void test1(){          redisTemplate.execute(new RedisCallback() {              @Override              public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {                   redisConnection.set(key.getBytes(),(System.currentTimeMillis()+"").getBytes());                  return 1L;              }          });      }        @Test      public void  test2(){          Object execute = redisTemplate.execute(new RedisCallback() {              @Override              public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {                  return redisConnection.get(key.getBytes());              }          });            System.out.println(new String((byte[])execute));        }  }


参考文档:

    http://redis.readthedocs.org/en/latest/topic/sentinel.html



来自:http://my.oschina.net/vincentzhao/blog/516245