Redis客户端简单封装

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

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

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"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans  
                           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"  
       default-autowire="byName">  
      
    <!-- 单个实例 -->  
    <bean id="singletonRedisClient" class="com.itlong.whatsmars.redis.client.singleton.SingletonRedisClient">  
        <property name="host" value="127.0.0.1"/>  
        <property name="port" value="6379" />  
        <property name="maxTotal" value="256"/>  
        <property name="maxIdle" value="8" />  
        <property name="maxWait" value="3000" />  
        <property name="timeout" value="3000" />  
        <property name="minIdle" value="2" />  
    </bean>  
    <!-- M-S读写分离 -->  
    <bean id="readWriteRedisClient" class="com.itlong.whatsmars.redis.client.readwrite.ReadWriteRedisClient">  
        <property name="hosts" value="127.0.0.1:6379,127.0.0.1:7379"/>  
        <property name="maxTotal" value="256"/>  
        <property name="maxIdle" value="8" />  
        <property name="maxWait" value="3000" />  
        <property name="timeout" value="3000" />  
        <property name="minIdle" value="2" />  
    </bean>  
    <!-- Cluster模式 -->  
    <bean id="redisClusterClient" class="com.itlong.whatsmars.redis.client.cluster.RedisClusterClient">  
        <property name="addresses" value="127.0.0.1:6379,127.0.01:7379,127.0.0.1:8379"/>  
        <property name="maxTotal" value="256"/>  
        <property name="maxIdle" value="8" />  
        <property name="maxWait" value="3000" />  
        <property name="timeout" value="3000" />  
        <property name="minIdle" value="2" />  
    </bean>  
  
    <!-- 客户端sharding模式,待进行 -->  
  
</beans>  

Java代码 收藏代码

package com.itlong.whatsmars.redis.client.singleton;  
  
import org.springframework.beans.factory.FactoryBean;  
import org.springframework.beans.factory.InitializingBean;  
import redis.clients.jedis.JedisPool;  
import redis.clients.jedis.JedisPoolConfig;  
  
/** 
 * Created by javahongxi on 2017/6/22. 
 */  
public class SingletonRedisClient implements FactoryBean<JedisPool>,InitializingBean {  
    private JedisPool jedisPool;  
  
    private int maxTotal = 128;  
  
    //最大空闲连接数  
    private int maxIdle = 2;  
  
    //最小空闲连接数  
    private int minIdle = 1;  
    //如果连接池耗尽,最大阻塞的时间,默认为3秒  
    private long maxWait = 3000;//单位毫秒  
    private String host;  
    private int port;  
    private int database = 0;//选择数据库,默认为0  
    private int timeout = 3000;//connectionTimeout,soTimeout,默认为3秒  
  
    private boolean testOnBorrow = true;  
    private boolean testOnReturn = true;  
  
    private String password;  
  
    public void setMaxTotal(int maxTotal) {  
        this.maxTotal = maxTotal;  
    }  
  
    public void setMaxIdle(int maxIdle) {  
        this.maxIdle = maxIdle;  
    }  
  
    public void setMinIdle(int minIdle) {  
        this.minIdle = minIdle;  
    }  
  
    public void setMaxWait(long maxWait) {  
        this.maxWait = maxWait;  
    }  
  
    public void setHost(String host) {  
        this.host = host;  
    }  
  
    public void setPort(int port) {  
        this.port = port;  
    }  
  
    public void setDatabase(int database) {  
        this.database = database;  
    }  
  
    public void setTimeout(int timeout) {  
        this.timeout = timeout;  
    }  
  
    public void setTestOnBorrow(boolean testOnBorrow) {  
        this.testOnBorrow = testOnBorrow;  
    }  
  
    public void setTestOnReturn(boolean testOnReturn) {  
        this.testOnReturn = testOnReturn;  
    }  
  
    public void setPassword(String password) {  
        this.password = password;  
    }  
  
    protected JedisPoolConfig buildConfig() {  
        JedisPoolConfig config = new JedisPoolConfig();  
        config.setMinIdle(minIdle);  
        config.setMaxIdle(maxIdle);  
        config.setMaxTotal(maxTotal);  
        config.setTestOnBorrow(testOnBorrow);  
        config.setTestOnReturn(testOnReturn);  
        config.setBlockWhenExhausted(true);  
        config.setMaxWaitMillis(maxWait);  
        config.setFairness(false);  
  
        return config;  
    }  
  
    @Override  
    public void afterPropertiesSet() throws Exception {  
        JedisPoolConfig config = buildConfig();  
        jedisPool = new JedisPool(config,host,port,timeout, password, database,null);  
    }  
  
    @Override  
    public JedisPool getObject() throws Exception {  
        return jedisPool;  
    }  
  
    @Override  
    public Class<?> getObjectType() {  
        return JedisPool.class;  
    }  
  
    @Override  
    public boolean isSingleton() {  
        return true;  
    }  
}  

Java代码 收藏代码

package com.itlong.whatsmars.redis.client.readwrite;  
  
import org.springframework.beans.factory.InitializingBean;  
import redis.clients.jedis.Jedis;  
import redis.clients.jedis.JedisPool;  
import redis.clients.jedis.JedisPoolConfig;  
  
import java.util.ArrayList;  
import java.util.List;  
import java.util.Random;  
  
/** 
 * Created by javahongxi on 2017/6/22. 
 */  
public class ReadWriteRedisClient implements InitializingBean {  
    //master:port,slave:port,slave:port...  
    //master first  
    private String hosts;  
    private JedisPool master;  
    private List<JedisPool> slaves = new ArrayList<JedisPool>();  
  
    private int maxTotal = 128;  
  
    //最大空闲连接数  
    private int maxIdle = 2;  
  
    //最小空闲连接数  
    private int minIdle = 1;  
    //如果连接池耗尽,最大阻塞的时间,默认为3秒  
    private long maxWait = 3000;//单位毫秒  
    private int database = 0;//选择数据库,默认为0  
    private int timeout = 3000;//connectionTimeout,soTimeout,默认为3秒  
  
    private boolean testOnBorrow = true;  
    private boolean testOnReturn = true;  
  
    private String password;  
  
    private Random random = new Random();  
  
    public void setMaxTotal(int maxTotal) {  
        this.maxTotal = maxTotal;  
    }  
  
    public void setMaxIdle(int maxIdle) {  
        this.maxIdle = maxIdle;  
    }  
  
    public void setMinIdle(int minIdle) {  
        this.minIdle = minIdle;  
    }  
  
    public void setMaxWait(long maxWait) {  
        this.maxWait = maxWait;  
    }  
  
    public void setDatabase(int database) {  
        this.database = database;  
    }  
  
    public void setTimeout(int timeout) {  
        this.timeout = timeout;  
    }  
  
    public void setTestOnBorrow(boolean testOnBorrow) {  
        this.testOnBorrow = testOnBorrow;  
    }  
  
    public void setTestOnReturn(boolean testOnReturn) {  
        this.testOnReturn = testOnReturn;  
    }  
  
    public void setPassword(String password) {  
        this.password = password;  
    }  
  
    public void setHosts(String hosts) {  
        this.hosts = hosts;  
    }  
  
    protected JedisPoolConfig buildConfig() {  
        JedisPoolConfig config = new JedisPoolConfig();  
        config.setMinIdle(minIdle);  
        config.setMaxIdle(maxIdle);  
        config.setMaxTotal(maxTotal);  
        config.setTestOnBorrow(testOnBorrow);  
        config.setTestOnReturn(testOnReturn);  
        config.setBlockWhenExhausted(true);  
        config.setMaxWaitMillis(maxWait);  
        config.setFairness(false);  
  
        return config;  
    }  
  
    @Override  
    public void afterPropertiesSet() throws Exception {  
        JedisPoolConfig config = buildConfig();  
        String[] hostAndPorts = hosts.split(",");  
        String masterHP = hostAndPorts[0];  
        String[] ms = masterHP.split(":");  
        master = new JedisPool(config,ms[0],Integer.valueOf(ms[1]),timeout, password, database,null);  
        if(hostAndPorts.length > 1) {  
            for(int i = 1; i < hostAndPorts.length; i++) {  
                String[] ss = hostAndPorts[i].split(":");  
                JedisPool slave = new JedisPool(config,ss[0],Integer.valueOf(ss[1]),timeout, password, database,null);  
                slaves.add(slave);  
            }  
        }  
        slaves.add(master);  
    }  
  
    public String get(String key) {  
        Jedis jedis = fetchResource(true);  
        try {  
            return jedis.get(key);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    public List<String> mget(String... keys) {  
        Jedis jedis = fetchResource(true);  
        try {  
            return jedis.mget(keys);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    public String setex(String key,int seconds,String value) {  
        Jedis jedis = fetchResource(false);  
        try {  
            return jedis.setex(key,seconds,value);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    public Long setnx(String key,String value) {  
        Jedis jedis = fetchResource(false);  
        try {  
            return jedis.setnx(key,value);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    public String set(String key,String value) {  
        Jedis jedis = fetchResource(false);  
        try {  
            return jedis.set(key,value);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    public Long del(String key) {  
        Jedis jedis = fetchResource(false);  
        try {  
            return jedis.del(key);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    public Long expire(String key,int seconds) {  
        Jedis jedis = fetchResource(false);  
        try {  
            return jedis.expire(key,seconds);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    public Boolean exists(String key) {  
        Jedis jedis = fetchResource(false);  
        try {  
            return jedis.exists(key);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    public Long exists(String... keys) {  
        Jedis jedis = fetchResource(false);  
        try {  
            return jedis.exists(keys);  
        } finally {  
            jedis.close();  
        }  
    }  
  
    private Jedis fetchResource(boolean read) {  
        if(slaves.isEmpty() || !read) {  
            return master.getResource();  
        }  
        int size = slaves.size();  
        int i = random.nextInt(size);  
        return slaves.get(i).getResource();  
    }  
  
  
    public static void main(String[] args) throws Exception {  
        String prefix = "_test_";  
        ReadWriteRedisClient client = new ReadWriteRedisClient();  
        client.setHosts("127.0.0.1:6379,127.0.0.1:6379");  
  
        client.afterPropertiesSet();  
  
        client.set(prefix + "10001","test");  
        System.out.println(client.get(prefix + "10001"));  
    }  
}  

Java代码 收藏代码

package com.itlong.whatsmars.redis.client.cluster;  
  
import org.springframework.beans.factory.FactoryBean;  
import org.springframework.beans.factory.InitializingBean;  
import redis.clients.jedis.HostAndPort;  
import redis.clients.jedis.JedisCluster;  
import redis.clients.jedis.JedisPoolConfig;  
  
import java.util.HashSet;  
import java.util.Set;  
  
/** 
 * Created by javahongxi on 2017/6/22. 
 */  
public class RedisClusterClient implements FactoryBean<JedisCluster>,InitializingBean {  
    private JedisCluster jedisCluster;  
  
    private int maxTotal = 128;  
  
    //最大空闲连接数  
    private int maxIdle = 6;  
  
    //最小空闲连接数  
    private int minIdle = 1;  
    //如果连接池耗尽,最大阻塞的时间,默认为3秒  
    private long maxWait = 3000;//单位毫秒  
  
    private int timeout = 3000;//connectionTimeout,soTimeout,默认为3秒  
  
    private boolean testOnBorrow = true;  
    private boolean testOnReturn = true;  
  
    private String addresses;//ip:port,ip:port  
  
    public void setMaxTotal(int maxTotal) {  
        this.maxTotal = maxTotal;  
    }  
  
    public void setMaxIdle(int maxIdle) {  
        this.maxIdle = maxIdle;  
    }  
  
    public void setMinIdle(int minIdle) {  
        this.minIdle = minIdle;  
    }  
  
    public void setMaxWait(long maxWait) {  
        this.maxWait = maxWait;  
    }  
  
    public void setTimeout(int timeout) {  
        this.timeout = timeout;  
    }  
  
    public void setTestOnBorrow(boolean testOnBorrow) {  
        this.testOnBorrow = testOnBorrow;  
    }  
  
    public void setTestOnReturn(boolean testOnReturn) {  
        this.testOnReturn = testOnReturn;  
    }  
  
    public void setAddresses(String addresses) {  
        this.addresses = addresses;  
    }  
  
    protected JedisPoolConfig buildConfig() {  
        JedisPoolConfig config = new JedisPoolConfig();  
  
        config.setMinIdle(minIdle);  
        config.setMaxIdle(maxIdle);  
        config.setMaxTotal(maxTotal);  
        config.setTestOnBorrow(testOnBorrow);  
        config.setTestOnReturn(testOnReturn);  
        config.setBlockWhenExhausted(true);  
        config.setMaxWaitMillis(maxWait);  
        config.setFairness(false);  
  
        return config;  
    }  
  
    private Set<HostAndPort> buildHostAndPorts() {  
        String[] hostPorts = addresses.split(",");  
        Set<HostAndPort> hostAndPorts = new HashSet<HostAndPort>();  
        for(String item : hostPorts) {  
            String[] hostPort = item.split(":");  
            HostAndPort hostAndPort = new HostAndPort(hostPort[0],Integer.valueOf(hostPort[1]));  
            hostAndPorts.add(hostAndPort);  
        }  
        return hostAndPorts;  
    }  
  
    @Override  
    public void afterPropertiesSet() throws Exception {  
        JedisPoolConfig config = buildConfig();  
        Set<HostAndPort> hostAndPorts = buildHostAndPorts();  
        jedisCluster = new JedisCluster(hostAndPorts,timeout,config);  
    }  
  
    @Override  
    public JedisCluster getObject() throws Exception {  
        return jedisCluster;  
    }  
  
    @Override  
    public Class<?> getObjectType() {  
        return JedisCluster.class;  
    }  
  
    @Override  
    public boolean isSingleton() {  
        return true;  
    }  
}  

Java代码 收藏代码

/** 
 * Created by javahongxi on 2017/6/23. 
 */  
@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = "classpath:spring-redis.xml")  
public class Demo {  
  
    @Autowired  
    @Qualifier("singletonRedisClient")  
    private JedisPool singletonRedisClient;  
  
    @Autowired  
    private ReadWriteRedisClient readWriteRedisClient;  
  
    @Autowired  
    @Qualifier("redisClusterClient")  
    private JedisCluster jedisCluster;  
  
    @Test  
    public void testSingleton() {  
        Jedis jedis = singletonRedisClient.getResource();  
        String cacheContent = null;  
        try {  
            cacheContent = jedis.get("hello_world");  
        }finally {  
            singletonRedisClient.close();  
        }  
        // 获取redis数据之后,立即释放连接,然后开始进行业务处理  
        if(cacheContent == null) {  
            // DB operation  
        }  
        // ..  
    }  
  
    @Test  
    public void testReadWrite() {  
        String cacheContent = null;  
        try {  
            cacheContent = readWriteRedisClient.get("hello_world");  
        } catch (Exception e) {  
            //如果异常,你可以决定是否忽略  
        }  
        if(cacheContent == null) {  
            //如果cache中不存在,或者redis异常  
        }  
    }  
  
    @Test  
    public void testCluster() {  
        String cacheContent = null;  
        try {  
            cacheContent = jedisCluster.get("hello_world");  
        } catch (Exception e) {  
            //如果异常,你可以决定是否忽略  
        }  
        if(cacheContent == null) {  
            //如果cache中不存在,或者redis异常  
        }  
    }  
}  

@基于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

原文链接:[http://wely.iteye.com/blog/2381049]

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
NoSQL Redis C++
VS2017的redis客户端实现
VS2017的redis客户端实现
|
4月前
|
NoSQL PHP Redis
PHP Redis 封装
PHP Redis 封装
17 0
|
1月前
|
JSON NoSQL Java
【Redis】2、Redis 的 Java 客户端(Jedis 和 SpringDataRedis)
【Redis】2、Redis 的 Java 客户端(Jedis 和 SpringDataRedis)
40 0
|
6月前
|
NoSQL 安全 Go
Golang 官方推荐使用的 Redis 客户端 redigo
Golang 官方推荐使用的 Redis 客户端 redigo
115 0
|
4月前
|
NoSQL 安全 Java
Redis基础篇:Redis的Java客户端
Redis基础篇:Redis的Java客户端
|
5月前
|
NoSQL 关系型数据库 MySQL
Docker-compose封装mysql和redis并初始化数据
Docker-compose封装mysql和redis并初始化数据
125 0
|
3月前
|
NoSQL Go Redis
Golang实现redis系列-(3)封装RESP协议
Golang实现redis系列-(3)封装RESP协议
34 0
|
22天前
|
NoSQL Redis
Netty实战:模拟Redis的客户端
Netty实战:模拟Redis的客户端
11 0
|
28天前
|
存储 缓存 Dragonfly
微软开抢年收入上亿美元的 Redis 饭碗?开源性能遥遥领先的 Garnet:无需修改,Redis 客户端可直接接入
微软开源了高性能缓存系统Garnet,旨在挑战 Redis 和 Dragonfly。Garnet 基于 .NET8,提供高吞吐量、低延迟和跨平台支持。它支持 RESP 协议,允许大部分 Redis 客户端无缝迁移。Garnet 的特性包括多连接批量处理以提升扩展性和吞吐量,以及更好的延迟稳定性。适合于需要高性能缓存层来降低成本和提高应用性能的场景。Garnet 的集群模式允许动态键迁移和分片管理,且支持 TLS 和自定义扩展。其网络层设计减少了线程切换开销,存储层则具备丰富的 API 和事务支持。在基准测试中,Garnet 在吞吐量和延迟上优于 Redis 和 KeyDB,展现出优秀的扩展性。
277 0
微软开抢年收入上亿美元的 Redis 饭碗?开源性能遥遥领先的 Garnet:无需修改,Redis 客户端可直接接入
|
29天前
|
缓存 NoSQL Java
springboot中集成redis,二次封装成工具类
springboot中集成redis,二次封装成工具类
162 0

热门文章

最新文章