Redis master-Slave Implementation of read-write separation _redis

Source: Internet
Author: User
Tags aop redis

Objective

You may encounter this need in your work, that is, Redis read and write separation, the purpose is to disperse pressure. Below I will introduce the use of AWS Elb to achieve read-write separation, to write the main read from the example.

Realize

Referencing library files

  <!--redis client-->
  <dependency>
   <groupId>redis.clients</groupId>
   < artifactid>jedis</artifactid>
   <version>2.6.2</version>
  </dependency>

Way One, With the help of Plane

Jedispoolselector

The purpose of this class is to configure different annotations for reading and writing, to distinguish between the master and the From.

Package com.silence.spring.redis.readwriteseparation;

Import Java.lang.annotation.ElementType;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;

/**
 * Created by keysilence on 16/10/26.
 * *
@Retention (retentionpolicy.runtime)
@Target (elementtype.method) public
@interface Jedispoolselector {

  String value ();

}

Jedispoolaspect

The purpose of this class is to dynamically link pool provisioning for and from annotations, that is, the main use of the primary link pool, from the use of the connection pool.

Package com.silence.spring.redis.readwriteseparation;
Import Org.aspectj.lang.JoinPoint;
Import Org.aspectj.lang.annotation.Aspect;
Import Org.aspectj.lang.annotation.Before;
Import Org.aspectj.lang.annotation.Pointcut;
Import Org.aspectj.lang.reflect.MethodSignature;
Import org.springframework.beans.BeansException;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.ApplicationContextAware;

Import Redis.clients.jedis.JedisPool;
Import javax.annotation.PostConstruct;
Import Java.lang.reflect.Method;

Import Java.util.Date;
 /** * Created by keysilence on 16/10/26.

  * * @Aspect public class Jedispoolaspect implements Applicationcontextaware {private ApplicationContext ctx;
  @PostConstruct public void init () {System.out.println ("Jedis pool AspectJ started @" + new Date ());
  } @Pointcut ("Execution (* com.silence.spring.redis.readwriteseparation.util.*.* (..))") private void Allmethod () {} @Before ("Allmethod ()") public voidBefore (Joinpoint point) {Object target = Point.gettarget ();

    String method = Point.getsignature (). GetName ();

    Class classz = Target.getclass ();
    Class<?>[] Parametertypes = ((methodsignature) point.getsignature ()). GetMethod (). Getparametertypes ();
      try {method M = Classz.getmethod (method, parametertypes);
            if (M!= null && m.isannotationpresent (Jedispoolselector.class)) {Jedispoolselector data = m
        . Getannotation (Jedispoolselector.class);
        Jedispool Jedispool = (jedispool) Ctx.getbean (Data.value ());
      Dynamicjedispoolholder.putjedispool (Jedispool);
    } catch (Exception e) {e.printstacktrace (); } public void Setapplicationcontext (ApplicationContext applicationcontext) throws beansexception {This.ctx = a
  Pplicationcontext;

 }

}

Dynamicjedispoolholder

The purpose of this class is to store the Jedispool that is currently in use, that is, the result saved after the class assignment.

Package com.silence.spring.redis.readwriteseparation;

Import Redis.clients.jedis.JedisPool;

/**
 * Created by keysilence on 16/10/26.
 * * Public
class Dynamicjedispoolholder {public

  static final threadlocal<jedispool> holder = new Threadlocal<jedispool> ();

  public static void Putjedispool (Jedispool jedispool) {
    holder.set (jedispool);
  }

  public static Jedispool Getjedispool () {return
    holder.get ();
  }

}

Redisutils

The purpose of this class is to redis specific calls, which contain the use of the master or from the way called.

 package com.silence.spring.redis.readwriteseparation.util;
Import Com.silence.spring.redis.readwriteseparation.DynamicJedisPoolHolder;
Import Com.silence.spring.redis.readwriteseparation.JedisPoolSelector;
Import Org.slf4j.Logger;

Import Org.slf4j.LoggerFactory;
 /** * Created by keysilence on 16/10/26.

  * * Public class Redisutils {private static Logger Logger = Loggerfactory.getlogger (Redisutils.class); @JedisPoolSelector ("master") public String setstring (final string key, final string value) {String ret = Dynamicje
    Dispoolholder.getjedispool (). GetResource (). Set (key, value);

    System.out.println ("key:" + key + ", Value:" + Value + ", ret:" + ret);
  return ret; @JedisPoolSelector ("slave") public String get (final String key) {string ret = Dynamicjedispoolholder.getjedis
    Pool (). GetResource (). get (key);

    System.out.println ("key:" + key + ", ret:" + ret);
  return ret; }

}

Spring-datasource.xml

<?xml version= "1.0" encoding= "UTF-8"?> <beans "xmlns=" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xsi: schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ Spring-beans.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/ 
    Spring-aop.xsd "> <bean id=" poolconfig "class=" Redis.clients.jedis.JedisPoolConfig "> <!--maximum number of links in the pool--> <property name= "Maxtotal" value=/> <!--pool Maximum number of free links--> <property name= "Maxidle" value= "50" /> <!--pool minimum number of free links--> <property name= "minidle" value= "/>" <!--when the link is depleted in the pool, the caller is blocked for the maximum time, which will run out of the Often. (in milliseconds; the default is-1, which means never timeout)--> <property name= "Maxwaitmillis" value= "1000"/> <!--reference: Http://biasedbit.com/re dis-jedispool-configuration/--> <!--whether the current link validity is detected when the caller gets the link. is not valid from the link poolRemove and try to continue the fetch. (default to False)--> <property name= "Testonborrow" value= "true"/> <!--check link validity when returning links to a link pool. (the default is False)--> <property name= "Testonreturn" value= "true"/> < whether the idle timeout is detected when the caller gets the link. If timed out, it is removed (the default is False)--> <property name= "Testwhileidle" value= "true"/> <!--the idle link detection thread runs the detected number of links at a time
    ; <property name= "Numtestsperevictionrun" value= "ten"/> <!--idle links detect thread detection cycles. A negative value indicates that the detection thread is not running. (in milliseconds, the default is-1)--> <property name= "Timebetweenevictionrunsmillis" value= "60000"/> <!--link acquisition. Queues: false; Stack: True--> <!--<property name= "LIFO" Value= "false"/>--> </bean> <bean id= "Maste" R "class=" Redis.clients.jedis.JedisPool "> <constructor-arg index=" 0 "ref=" poolconfig "/> <constructor-a RG index= "1" value= "192.168.100.110" type= "java.lang.String"/> <constructor-arg index= "2" value= "6379" type= "in T "/> </bean> <bean id=" slave "class=" redis.clients.jeDis. Jedispool "> <constructor-arg index=" 0 "ref=" poolconfig "/> <!--where host is configured as ELB address--> <construct Or-arg index= "1" value= "192.168.100.110" type= "java.lang.String"/> "<constructor-arg" index= "2" value= "6380" type = "int"/> </bean> <bean id= "redisutils" class= " Com.silence.spring.redis.readwriteseparation.util.RedisUtils "> </bean> <bean id=" Jedispoolaspect " class= "Com.silence.spring.redis.readwriteseparation.JedisPoolAspect"/> <aop:aspectj-autoproxy

 Proxy-target-class= "true"/> </beans>

Test

Package com.silence.spring.redis.readwriteseparation;

Import Com.silence.spring.redis.readwriteseparation.util.RedisUtils;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by keysilence on 16/10/26.
 */Public
class Test {public

  static void Main (string[] args) {

    ApplicationContext ctx = new Classpathxmlappli Cationcontext ("Spring-datasource.xml");

    System.out.println (CTX);

    Redisutils redisutils = (redisutils) ctx.getbean ("Redisutils");
    Redisutils.setstring ("AAA", "a");

    System.out.println (Redisutils.get ("AAA"));
  }



mode two, Dependency Injection

Similar to the way a, but need to write the death of the specific use of the main pool or from the pool, ideas are as follows:
Discard the annotations by injecting the two-link pool directly into the concrete implementation class.

Redisutils

Package com.silence.spring.redis.readwriteseparation.util;
Import Com.silence.spring.redis.readwriteseparation.DynamicJedisPoolHolder;
Import Com.silence.spring.redis.readwriteseparation.JedisPoolSelector;
Import Org.slf4j.Logger;
Import Org.slf4j.LoggerFactory;

Import Redis.clients.jedis.JedisPool;
 /** * Created by keysilence on 16/10/26.

  * * Public class Redisutils {private static Logger Logger = Loggerfactory.getlogger (Redisutils.class);

  Private Jedispool Masterjedispool;

  Private Jedispool Slavejedispool;
  public void Setmasterjedispool (Jedispool masterjedispool) {this.masterjedispool = Masterjedispool;
  public void Setslavejedispool (Jedispool slavejedispool) {this.slavejedispool = Slavejedispool; public string setstring (final string key, final string value) {string ret = Masterjedispool.getresource (). Set (k
    EY, value);

    System.out.println ("key:" + key + ", Value:" + Value + ", ret:" + ret);
  return ret; Public String get (final STring key) {String ret = Slavejedispool.getresource (). get (key);

    System.out.println ("key:" + key + ", ret:" + ret);
  return ret;

 }

}

Spring-datasource.xml

<?xml version= "1.0" encoding= "UTF-8"?> <beans "xmlns=" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xsi: schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ Spring-beans.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/ 
    Spring-aop.xsd "> <bean id=" poolconfig "class=" Redis.clients.jedis.JedisPoolConfig "> <!--maximum number of links in the pool--> <property name= "Maxtotal" value=/> <!--pool Maximum number of free links--> <property name= "Maxidle" value= "50" /> <!--pool minimum number of free links--> <property name= "minidle" value= "/>" <!--when the link is depleted in the pool, the caller is blocked for the maximum time, which will run out of the Often. (in milliseconds; the default is-1, which means never timeout)--> <property name= "Maxwaitmillis" value= "1000"/> <!--reference: Http://biasedbit.com/re dis-jedispool-configuration/--> <!--whether the current link validity is detected when the caller gets the link. is not valid from the link poolRemove and try to continue the fetch. (default to False)--> <property name= "Testonborrow" value= "true"/> <!--check link validity when returning links to a link pool. (the default is False)--> <property name= "Testonreturn" value= "true"/> < whether the idle timeout is detected when the caller gets the link. If timed out, it is removed (the default is False)--> <property name= "Testwhileidle" value= "true"/> <!--the idle link detection thread runs the detected number of links at a time
    ; <property name= "Numtestsperevictionrun" value= "ten"/> <!--idle links detect thread detection cycles. A negative value indicates that the detection thread is not running. (in milliseconds, the default is-1)--> <property name= "Timebetweenevictionrunsmillis" value= "60000"/> <!--link acquisition. Queues: false; Stack: True--> <!--<property name= "LIFO" Value= "false"/>--> </bean> <bean id= "Maste" Rjedispool "class=" Redis.clients.jedis.JedisPool "> <constructor-arg index=" 0 "ref=" poolconfig "/> <cons Tructor-arg index= "1" value= "192.168.100.110" 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= "192.168.100.110" type= "java.lang.String"/> <constructor-arg index= "2" value= "6380" type= "int"/> </bean> <bean id= "redisutils" class= "Com.silence.spring.redis.readwriteseparation.util.RedisUtils" > & Lt;property name= "Masterjedispool" ref= "Masterjedispool"/> <property name= "Slavejedispool"

 Slavejedispool "/> </bean> </beans>

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.