Redis客户端简单封装

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]

时间: 2024-08-18 15:52:52

Redis客户端简单封装的相关文章

spring整合redis客户端及缓存接口设计(转)

一.写在前面 缓存作为系统性能优化的一大杀手锏,几乎在每个系统或多或少的用到缓存.有的使用本地内存作为缓存,有的使用本地硬盘作为缓存,有的使用缓存服务器.但是无论使用哪种缓存,接口中的方法都是差不多.笔者最近的项目使用的是memcached作为缓存服务器,由于memcached的一些限制,现在想换redis作为缓存服务器.思路就是把memached的客户端换成redis客户端,接口依然是原来的接口,这样对系统可以无损替换,接口不变,功能不变,只是客户端变了.本文不介绍缓存的用法,不介绍redis

redis实现简单队列_Redis

在工作中,时常会有用到队列的场景,比较常见的用rabbitMQ这些专业的组件,官网地址是:http://www.rabbitmq.com,重要的是官方有.net的客户端,但是如果对rabbitMQ不熟悉的话,建议使用第三方封装好的 EasyNetQ,rabbitMQ比较适合对安全性,稳定性要求较高的地方,但有时我们也会有对这方面要求不是很高的场景,比如:文章阅读数,实时性要求不是很高的地方,所以我想到了用redis来做队列. redis 的List结构本身就是一个链表 (双向链表),所以符合我们

利器OkHttp的使用以及简单封装

前言 Android开发中网络编程是必不可少的,不接入互联网的APP就没有盈利可言.废话不多说了,下面请先看Android中网络请求的进化图: HttpURLConnection,Apache HTTP Client,Volley到现在的OKHttp,可谓天外有天,人外有人.为什么OKHttp会这么火呢,相信下面的介绍会告诉你答案. OKHttp的简介 首先,给出OKHttp的项目地址:https://github.com/square/okhttp Android为我们提供了两种HTTP交互的

手把手教你编写入门级redis客户端

Redis是开源的.基于内存的数据结构存储系统,可用作数据库.缓存以及消息代理方面.Redis支持许多种数据结构,并内置了丰富的诸如冗余.脚本.事务.持久化等功能,深受业界喜爱,被各种业务系统广泛使用.为了方便使用,Redis官网推荐了针对各种编程语言的多种客户端,支持java.c#.python.c++等主流编程语言.那么大家会问,既然Redis客户端已经这么丰富了,为什么还要尝试自己编写客户端?我的看法是,知己知彼,自己尝试制作Redis客户端,不仅可以加深对Redis的了解,而且可以通晓R

功能强大的 C++ redis 客户端库增加至 acl 项目中

虽然 redis 开发库已有不少,但 C/C++ 的客户端库好用的并不多,虽然官方也提供了 C 版的客户端库,但易用性较差,而且不支持连接池功能,相对于 C/C++ 的库,JAVA 版的 jedis 要好用的多,jedis 提供了 redis 库的全命令实现,而 C/C++ 则只提供了协议级实现,使用者需要了解命令发送的格式,而且还得判断分析所接收数据的格式,使用起来非常繁琐,acl 库(跨平台网络通信与服务器框架)的作者在使用 C/C++ 版的 redis 库时也屡受摧残,于是其基于 acl

简单封装 HTTP 请求

2017-2-19 更新到第二版: 源码地址:http://git.oschina.net/sp42/ajaxjs/tree/master/ajaxjs-base/src/com/ajaxjs/net?dir=1&filepath=ajaxjs-base%2Fsrc%2Fcom%2Fajaxjs%2Fnet 和文件操作一样,其内部使用了链式风格的调用方式. GET/HEAD 请求 GET 请求用法参见下面的测试用例,包括普通 GET 请求.获取 302 重定向调转地址.获取资源文件体积大小.是否

WebService 的简单封装接口调用方法

  这篇文章主要介绍了WebService 的简单封装接口调用方法,主要是通过简单的sql语句来查询数据库,从而返回dataset,十分简单实用,有需要的小伙伴可以参考下. 此方法完成了简单WebService 的简单调用封装,实现了简单Webservice简单调用的统一操作,避免了每增加一个操作都必须增加一个接口方法 的囧状! ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 3

用原生JS对AJAX做简单封装的实例代码_javascript技巧

首先,我们需要xhr对象.这对我们来说不难,封装成一个函数. var createAjax = function() { var xhr = null; try { //IE系列浏览器 xhr = new ActiveXObject("microsoft.xmlhttp"); } catch (e1) { try { //非IE浏览器 xhr = new XMLHttpRequest(); } catch (e2) { window.alert("您的浏览器不支持ajax,请

&quot;Redis客户端连接数一直降不下来&quot;的有关问题解决 good

[线上问题] "Redis客户端连接数一直降不下来"的问题解决 前段时间,上线了新的 Redis缓存(Cache)服务,准备替换掉 Memcached.   为什么要将 Memcached 替换掉? 原因是 业务数据是压缩后的列表型数据,缓存中保存最新的3000条数据.对于新数据追加操作,需要拆解成[get + unzip + append + zip + set]这5步操作.若列表长度在O(1k)级别的,其耗时至少在50ms+.而在并发环境下,这样会存在"数据更新覆盖问题&