Redis客户端简单封装

来源:互联网 发布:国际投资净头寸数据 编辑:程序博客网 时间:2024/06/05 09:46

 Redis客户端简单封装并集成spring. spring-data-redis对redis有过度封装的嫌疑,而且也没有提供sharding模式,本文遂简单封装jedis。

 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.                            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"  
  6.        default-autowire="byName">  
  7.       
  8.     <!-- 单个实例 -->  
  9.     <bean id="singletonRedisClient" class="com.itlong.whatsmars.redis.client.singleton.SingletonRedisClient">  
  10.         <property name="host" value="127.0.0.1"/>  
  11.         <property name="port" value="6379" />  
  12.         <property name="maxTotal" value="256"/>  
  13.         <property name="maxIdle" value="8" />  
  14.         <property name="maxWait" value="3000" />  
  15.         <property name="timeout" value="3000" />  
  16.         <property name="minIdle" value="2" />  
  17.     </bean>  
  18.     <!-- M-S读写分离 -->  
  19.     <bean id="readWriteRedisClient" class="com.itlong.whatsmars.redis.client.readwrite.ReadWriteRedisClient">  
  20.         <property name="hosts" value="127.0.0.1:6379,127.0.0.1:7379"/>  
  21.         <property name="maxTotal" value="256"/>  
  22.         <property name="maxIdle" value="8" />  
  23.         <property name="maxWait" value="3000" />  
  24.         <property name="timeout" value="3000" />  
  25.         <property name="minIdle" value="2" />  
  26.     </bean>  
  27.     <!-- Cluster模式 -->  
  28.     <bean id="redisClusterClient" class="com.itlong.whatsmars.redis.client.cluster.RedisClusterClient">  
  29.         <property name="addresses" value="127.0.0.1:6379,127.0.01:7379,127.0.0.1:8379"/>  
  30.         <property name="maxTotal" value="256"/>  
  31.         <property name="maxIdle" value="8" />  
  32.         <property name="maxWait" value="3000" />  
  33.         <property name="timeout" value="3000" />  
  34.         <property name="minIdle" value="2" />  
  35.     </bean>  
  36.   
  37.     <!-- 客户端sharding模式,待进行 -->  
  38.   
  39. </beans>  

 

 

 

Java代码  收藏代码
  1. package com.itlong.whatsmars.redis.client.singleton;  
  2.   
  3. import org.springframework.beans.factory.FactoryBean;  
  4. import org.springframework.beans.factory.InitializingBean;  
  5. import redis.clients.jedis.JedisPool;  
  6. import redis.clients.jedis.JedisPoolConfig;  
  7.   
  8. /** 
  9.  * Created by javahongxi on 2017/6/22. 
  10.  */  
  11. public class SingletonRedisClient implements FactoryBean<JedisPool>,InitializingBean {  
  12.     private JedisPool jedisPool;  
  13.   
  14.     private int maxTotal = 128;  
  15.   
  16.     //最大空闲连接数  
  17.     private int maxIdle = 2;  
  18.   
  19.     //最小空闲连接数  
  20.     private int minIdle = 1;  
  21.     //如果连接池耗尽,最大阻塞的时间,默认为3秒  
  22.     private long maxWait = 3000;//单位毫秒  
  23.     private String host;  
  24.     private int port;  
  25.     private int database = 0;//选择数据库,默认为0  
  26.     private int timeout = 3000;//connectionTimeout,soTimeout,默认为3秒  
  27.   
  28.     private boolean testOnBorrow = true;  
  29.     private boolean testOnReturn = true;  
  30.   
  31.     private String password;  
  32.   
  33.     public void setMaxTotal(int maxTotal) {  
  34.         this.maxTotal = maxTotal;  
  35.     }  
  36.   
  37.     public void setMaxIdle(int maxIdle) {  
  38.         this.maxIdle = maxIdle;  
  39.     }  
  40.   
  41.     public void setMinIdle(int minIdle) {  
  42.         this.minIdle = minIdle;  
  43.     }  
  44.   
  45.     public void setMaxWait(long maxWait) {  
  46.         this.maxWait = maxWait;  
  47.     }  
  48.   
  49.     public void setHost(String host) {  
  50.         this.host = host;  
  51.     }  
  52.   
  53.     public void setPort(int port) {  
  54.         this.port = port;  
  55.     }  
  56.   
  57.     public void setDatabase(int database) {  
  58.         this.database = database;  
  59.     }  
  60.   
  61.     public void setTimeout(int timeout) {  
  62.         this.timeout = timeout;  
  63.     }  
  64.   
  65.     public void setTestOnBorrow(boolean testOnBorrow) {  
  66.         this.testOnBorrow = testOnBorrow;  
  67.     }  
  68.   
  69.     public void setTestOnReturn(boolean testOnReturn) {  
  70.         this.testOnReturn = testOnReturn;  
  71.     }  
  72.   
  73.     public void setPassword(String password) {  
  74.         this.password = password;  
  75.     }  
  76.   
  77.     protected JedisPoolConfig buildConfig() {  
  78.         JedisPoolConfig config = new JedisPoolConfig();  
  79.         config.setMinIdle(minIdle);  
  80.         config.setMaxIdle(maxIdle);  
  81.         config.setMaxTotal(maxTotal);  
  82.         config.setTestOnBorrow(testOnBorrow);  
  83.         config.setTestOnReturn(testOnReturn);  
  84.         config.setBlockWhenExhausted(true);  
  85.         config.setMaxWaitMillis(maxWait);  
  86.         config.setFairness(false);  
  87.   
  88.         return config;  
  89.     }  
  90.   
  91.     @Override  
  92.     public void afterPropertiesSet() throws Exception {  
  93.         JedisPoolConfig config = buildConfig();  
  94.         jedisPool = new JedisPool(config,host,port,timeout, password, database,null);  
  95.     }  
  96.   
  97.     @Override  
  98.     public JedisPool getObject() throws Exception {  
  99.         return jedisPool;  
  100.     }  
  101.   
  102.     @Override  
  103.     public Class<?> getObjectType() {  
  104.         return JedisPool.class;  
  105.     }  
  106.   
  107.     @Override  
  108.     public boolean isSingleton() {  
  109.         return true;  
  110.     }  
  111. }  

 

Java代码  收藏代码
  1. package com.itlong.whatsmars.redis.client.readwrite;  
  2.   
  3. import org.springframework.beans.factory.InitializingBean;  
  4. import redis.clients.jedis.Jedis;  
  5. import redis.clients.jedis.JedisPool;  
  6. import redis.clients.jedis.JedisPoolConfig;  
  7.   
  8. import java.util.ArrayList;  
  9. import java.util.List;  
  10. import java.util.Random;  
  11.   
  12. /** 
  13.  * Created by javahongxi on 2017/6/22. 
  14.  */  
  15. public class ReadWriteRedisClient implements InitializingBean {  
  16.     //master:port,slave:port,slave:port...  
  17.     //master first  
  18.     private String hosts;  
  19.     private JedisPool master;  
  20.     private List<JedisPool> slaves = new ArrayList<JedisPool>();  
  21.   
  22.     private int maxTotal = 128;  
  23.   
  24.     //最大空闲连接数  
  25.     private int maxIdle = 2;  
  26.   
  27.     //最小空闲连接数  
  28.     private int minIdle = 1;  
  29.     //如果连接池耗尽,最大阻塞的时间,默认为3秒  
  30.     private long maxWait = 3000;//单位毫秒  
  31.     private int database = 0;//选择数据库,默认为0  
  32.     private int timeout = 3000;//connectionTimeout,soTimeout,默认为3秒  
  33.   
  34.     private boolean testOnBorrow = true;  
  35.     private boolean testOnReturn = true;  
  36.   
  37.     private String password;  
  38.   
  39.     private Random random = new Random();  
  40.   
  41.     public void setMaxTotal(int maxTotal) {  
  42.         this.maxTotal = maxTotal;  
  43.     }  
  44.   
  45.     public void setMaxIdle(int maxIdle) {  
  46.         this.maxIdle = maxIdle;  
  47.     }  
  48.   
  49.     public void setMinIdle(int minIdle) {  
  50.         this.minIdle = minIdle;  
  51.     }  
  52.   
  53.     public void setMaxWait(long maxWait) {  
  54.         this.maxWait = maxWait;  
  55.     }  
  56.   
  57.     public void setDatabase(int database) {  
  58.         this.database = database;  
  59.     }  
  60.   
  61.     public void setTimeout(int timeout) {  
  62.         this.timeout = timeout;  
  63.     }  
  64.   
  65.     public void setTestOnBorrow(boolean testOnBorrow) {  
  66.         this.testOnBorrow = testOnBorrow;  
  67.     }  
  68.   
  69.     public void setTestOnReturn(boolean testOnReturn) {  
  70.         this.testOnReturn = testOnReturn;  
  71.     }  
  72.   
  73.     public void setPassword(String password) {  
  74.         this.password = password;  
  75.     }  
  76.   
  77.     public void setHosts(String hosts) {  
  78.         this.hosts = hosts;  
  79.     }  
  80.   
  81.     protected JedisPoolConfig buildConfig() {  
  82.         JedisPoolConfig config = new JedisPoolConfig();  
  83.         config.setMinIdle(minIdle);  
  84.         config.setMaxIdle(maxIdle);  
  85.         config.setMaxTotal(maxTotal);  
  86.         config.setTestOnBorrow(testOnBorrow);  
  87.         config.setTestOnReturn(testOnReturn);  
  88.         config.setBlockWhenExhausted(true);  
  89.         config.setMaxWaitMillis(maxWait);  
  90.         config.setFairness(false);  
  91.   
  92.         return config;  
  93.     }  
  94.   
  95.     @Override  
  96.     public void afterPropertiesSet() throws Exception {  
  97.         JedisPoolConfig config = buildConfig();  
  98.         String[] hostAndPorts = hosts.split(",");  
  99.         String masterHP = hostAndPorts[0];  
  100.         String[] ms = masterHP.split(":");  
  101.         master = new JedisPool(config,ms[0],Integer.valueOf(ms[1]),timeout, password, database,null);  
  102.         if(hostAndPorts.length > 1) {  
  103.             for(int i = 1; i < hostAndPorts.length; i++) {  
  104.                 String[] ss = hostAndPorts[i].split(":");  
  105.                 JedisPool slave = new JedisPool(config,ss[0],Integer.valueOf(ss[1]),timeout, password, database,null);  
  106.                 slaves.add(slave);  
  107.             }  
  108.         }  
  109.         slaves.add(master);  
  110.     }  
  111.   
  112.     public String get(String key) {  
  113.         Jedis jedis = fetchResource(true);  
  114.         try {  
  115.             return jedis.get(key);  
  116.         } finally {  
  117.             jedis.close();  
  118.         }  
  119.     }  
  120.   
  121.     public List<String> mget(String... keys) {  
  122.         Jedis jedis = fetchResource(true);  
  123.         try {  
  124.             return jedis.mget(keys);  
  125.         } finally {  
  126.             jedis.close();  
  127.         }  
  128.     }  
  129.   
  130.     public String setex(String key,int seconds,String value) {  
  131.         Jedis jedis = fetchResource(false);  
  132.         try {  
  133.             return jedis.setex(key,seconds,value);  
  134.         } finally {  
  135.             jedis.close();  
  136.         }  
  137.     }  
  138.   
  139.     public Long setnx(String key,String value) {  
  140.         Jedis jedis = fetchResource(false);  
  141.         try {  
  142.             return jedis.setnx(key,value);  
  143.         } finally {  
  144.             jedis.close();  
  145.         }  
  146.     }  
  147.   
  148.     public String set(String key,String value) {  
  149.         Jedis jedis = fetchResource(false);  
  150.         try {  
  151.             return jedis.set(key,value);  
  152.         } finally {  
  153.             jedis.close();  
  154.         }  
  155.     }  
  156.   
  157.     public Long del(String key) {  
  158.         Jedis jedis = fetchResource(false);  
  159.         try {  
  160.             return jedis.del(key);  
  161.         } finally {  
  162.             jedis.close();  
  163.         }  
  164.     }  
  165.   
  166.     public Long expire(String key,int seconds) {  
  167.         Jedis jedis = fetchResource(false);  
  168.         try {  
  169.             return jedis.expire(key,seconds);  
  170.         } finally {  
  171.             jedis.close();  
  172.         }  
  173.     }  
  174.   
  175.     public Boolean exists(String key) {  
  176.         Jedis jedis = fetchResource(false);  
  177.         try {  
  178.             return jedis.exists(key);  
  179.         } finally {  
  180.             jedis.close();  
  181.         }  
  182.     }  
  183.   
  184.     public Long exists(String... keys) {  
  185.         Jedis jedis = fetchResource(false);  
  186.         try {  
  187.             return jedis.exists(keys);  
  188.         } finally {  
  189.             jedis.close();  
  190.         }  
  191.     }  
  192.   
  193.     private Jedis fetchResource(boolean read) {  
  194.         if(slaves.isEmpty() || !read) {  
  195.             return master.getResource();  
  196.         }  
  197.         int size = slaves.size();  
  198.         int i = random.nextInt(size);  
  199.         return slaves.get(i).getResource();  
  200.     }  
  201.   
  202.   
  203.     public static void main(String[] args) throws Exception {  
  204.         String prefix = "_test_";  
  205.         ReadWriteRedisClient client = new ReadWriteRedisClient();  
  206.         client.setHosts("127.0.0.1:6379,127.0.0.1:6379");  
  207.   
  208.         client.afterPropertiesSet();  
  209.   
  210.         client.set(prefix + "10001","test");  
  211.         System.out.println(client.get(prefix + "10001"));  
  212.     }  
  213. }  

 

Java代码  收藏代码
  1. package com.itlong.whatsmars.redis.client.cluster;  
  2.   
  3. import org.springframework.beans.factory.FactoryBean;  
  4. import org.springframework.beans.factory.InitializingBean;  
  5. import redis.clients.jedis.HostAndPort;  
  6. import redis.clients.jedis.JedisCluster;  
  7. import redis.clients.jedis.JedisPoolConfig;  
  8.   
  9. import java.util.HashSet;  
  10. import java.util.Set;  
  11.   
  12. /** 
  13.  * Created by javahongxi on 2017/6/22. 
  14.  */  
  15. public class RedisClusterClient implements FactoryBean<JedisCluster>,InitializingBean {  
  16.     private JedisCluster jedisCluster;  
  17.   
  18.     private int maxTotal = 128;  
  19.   
  20.     //最大空闲连接数  
  21.     private int maxIdle = 6;  
  22.   
  23.     //最小空闲连接数  
  24.     private int minIdle = 1;  
  25.     //如果连接池耗尽,最大阻塞的时间,默认为3秒  
  26.     private long maxWait = 3000;//单位毫秒  
  27.   
  28.     private int timeout = 3000;//connectionTimeout,soTimeout,默认为3秒  
  29.   
  30.     private boolean testOnBorrow = true;  
  31.     private boolean testOnReturn = true;  
  32.   
  33.     private String addresses;//ip:port,ip:port  
  34.   
  35.     public void setMaxTotal(int maxTotal) {  
  36.         this.maxTotal = maxTotal;  
  37.     }  
  38.   
  39.     public void setMaxIdle(int maxIdle) {  
  40.         this.maxIdle = maxIdle;  
  41.     }  
  42.   
  43.     public void setMinIdle(int minIdle) {  
  44.         this.minIdle = minIdle;  
  45.     }  
  46.   
  47.     public void setMaxWait(long maxWait) {  
  48.         this.maxWait = maxWait;  
  49.     }  
  50.   
  51.     public void setTimeout(int timeout) {  
  52.         this.timeout = timeout;  
  53.     }  
  54.   
  55.     public void setTestOnBorrow(boolean testOnBorrow) {  
  56.         this.testOnBorrow = testOnBorrow;  
  57.     }  
  58.   
  59.     public void setTestOnReturn(boolean testOnReturn) {  
  60.         this.testOnReturn = testOnReturn;  
  61.     }  
  62.   
  63.     public void setAddresses(String addresses) {  
  64.         this.addresses = addresses;  
  65.     }  
  66.   
  67.     protected JedisPoolConfig buildConfig() {  
  68.         JedisPoolConfig config = new JedisPoolConfig();  
  69.   
  70.         config.setMinIdle(minIdle);  
  71.         config.setMaxIdle(maxIdle);  
  72.         config.setMaxTotal(maxTotal);  
  73.         config.setTestOnBorrow(testOnBorrow);  
  74.         config.setTestOnReturn(testOnReturn);  
  75.         config.setBlockWhenExhausted(true);  
  76.         config.setMaxWaitMillis(maxWait);  
  77.         config.setFairness(false);  
  78.   
  79.         return config;  
  80.     }  
  81.   
  82.     private Set<HostAndPort> buildHostAndPorts() {  
  83.         String[] hostPorts = addresses.split(",");  
  84.         Set<HostAndPort> hostAndPorts = new HashSet<HostAndPort>();  
  85.         for(String item : hostPorts) {  
  86.             String[] hostPort = item.split(":");  
  87.             HostAndPort hostAndPort = new HostAndPort(hostPort[0],Integer.valueOf(hostPort[1]));  
  88.             hostAndPorts.add(hostAndPort);  
  89.         }  
  90.         return hostAndPorts;  
  91.     }  
  92.   
  93.     @Override  
  94.     public void afterPropertiesSet() throws Exception {  
  95.         JedisPoolConfig config = buildConfig();  
  96.         Set<HostAndPort> hostAndPorts = buildHostAndPorts();  
  97.         jedisCluster = new JedisCluster(hostAndPorts,timeout,config);  
  98.     }  
  99.   
  100.     @Override  
  101.     public JedisCluster getObject() throws Exception {  
  102.         return jedisCluster;  
  103.     }  
  104.   
  105.     @Override  
  106.     public Class<?> getObjectType() {  
  107.         return JedisCluster.class;  
  108.     }  
  109.   
  110.     @Override  
  111.     public boolean isSingleton() {  
  112.         return true;  
  113.     }  
  114. }  

 

 

Java代码  收藏代码
  1. /** 
  2.  * Created by javahongxi on 2017/6/23. 
  3.  */  
  4. @RunWith(SpringJUnit4ClassRunner.class)  
  5. @ContextConfiguration(locations = "classpath:spring-redis.xml")  
  6. public class Demo {  
  7.   
  8.     @Autowired  
  9.     @Qualifier("singletonRedisClient")  
  10.     private JedisPool singletonRedisClient;  
  11.   
  12.     @Autowired  
  13.     private ReadWriteRedisClient readWriteRedisClient;  
  14.   
  15.     @Autowired  
  16.     @Qualifier("redisClusterClient")  
  17.     private JedisCluster jedisCluster;  
  18.   
  19.     @Test  
  20.     public void testSingleton() {  
  21.         Jedis jedis = singletonRedisClient.getResource();  
  22.         String cacheContent = null;  
  23.         try {  
  24.             cacheContent = jedis.get("hello_world");  
  25.         }finally {  
  26.             singletonRedisClient.close();  
  27.         }  
  28.         // 获取redis数据之后,立即释放连接,然后开始进行业务处理  
  29.         if(cacheContent == null) {  
  30.             // DB operation  
  31.         }  
  32.         // ..  
  33.     }  
  34.   
  35.     @Test  
  36.     public void testReadWrite() {  
  37.         String cacheContent = null;  
  38.         try {  
  39.             cacheContent = readWriteRedisClient.get("hello_world");  
  40.         } catch (Exception e) {  
  41.             //如果异常,你可以决定是否忽略  
  42.         }  
  43.         if(cacheContent == null) {  
  44.             //如果cache中不存在,或者redis异常  
  45.         }  
  46.     }  
  47.   
  48.     @Test  
  49.     public void testCluster() {  
  50.         String cacheContent = null;  
  51.         try {  
  52.             cacheContent = jedisCluster.get("hello_world");  
  53.         } catch (Exception e) {  
  54.             //如果异常,你可以决定是否忽略  
  55.         }  
  56.         if(cacheContent == null) {  
  57.             //如果cache中不存在,或者redis异常  
  58.         }  
  59.     }  
  60. }  

 

 

@基于M-S模式下读写分离

通常情况下,Slave只是作为数据备份,不提供read操作,这种考虑是为了避免slave提供stale数据而导致一些问题。 不过在很多场景下,即使slave数据有一定的延迟,我们仍然可以兼容或者正常处理,此时我们可以将slave提供read 服务,并在M-S集群中将read操作分流,此时我们的Redis集群将可以支撑更高的QPS。本实例中,仅仅提供了“读写分 离”的样板,尚未对所有的redis方法进行重写和封装,请开发者后续继续补充即可。此外,slave节点如果异常,我们 应该支持failover,这一部分特性后续再扩展。 

代码 https://github.com/javahongxi/whatsmars/tree/master/whatsmars-redis

原创粉丝点击