Redis客户端之Jedis使用介绍

Jedis是Redis官方推荐的Java连接开发工具。
Redis 默认是单机环境使用的。 数据量较大时需要shard(多机环境),这个时候要用ShardedJedis。 ShardedJedis是基于一致性哈希算法实现的分布式Redis集群客户端。

一、Jedis的使用
1、添加maven依赖

<dependency>
     <groupId>redis.clients</groupId>
     <artifactId>jedis</artifactId>
     <version>2.9.0</version>
</dependency>

2、Jedis使用方式
方式一:Redis单节点 + Jedis单例 (Redis单节点压力过重, Jedis单例存在并发瓶颈 ,不可用于线上!)

	Jedis jedis = new Jedis(host, port);
	jedis.auth(password);

方式二:Redis单节点 + JedisPool单节点连接池, (Redis单节点压力过重,负载和容灾比较差)

	JedisPoolConfig poolConfig = new JedisPoolConfig();
	poolConfig.setMaxTotal(30);// 最大连接数,连接全部用完,进行等待
	poolConfig.setMinIdle(5); // 最小空余数
	poolConfig.setMaxIdle(20); // 最大空余数
	poolConfig.setMaxWaitMillis(10000);         // 获取连接时的最大等待毫秒数(如果设置为阻塞时							BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
    poolConfig.setTestOnBorrow(true);           // 在获取连接的时候检查有效性, 默认false
    poolConfig.setTestOnReturn(false);          // 调用returnObject方法时,是否进行有效检查
    poolConfig.setTestWhileIdle(true);          // Idle时进行连接扫描
    poolConfig.setTimeBetweenEvictionRunsMillis(30000);     // 表示idle object evitor两次扫描之间要sleep的毫秒数
    poolConfig.setNumTestsPerEvictionRun(10);               // 表示idle object evitor每次扫描的最多的对象数
    poolConfig.setMinEvictableIdleTimeMillis(60000);        // 表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
    
	JedisPool pool = new JedisPool(poolConfig, host, port);
	Jedis jedis = pool.getResource();
	jedis.auth(password);

方式三: Redis分片(通过client端集群,一致性哈希方式实现) + Jedis多节点连接池,(Redis集群,负载和容灾较好, ShardedJedisPool一致性哈希分片,读写均匀,动态扩充)

	JedisPoolConfig poolConfig = new JedisPoolConfig();
	poolConfig.setMaxTotal(30);// 最大连接数,连接全部用完,进行等待
	poolConfig.setMinIdle(5); // 最小空余数
	poolConfig.setMaxIdle(20); // 最大空余数
	
	List<JedisShardInfo> jedisShardInfos = new LinkedList<JedisShardInfo>();
	JedisShardInfo jedisShardInfo = new JedisShardInfo(host);
	jedisShardInfos.add(jedisShardInfo);
	
	ShardedJedisPool shardedJedisPool = new ShardedJedisPool(poolConfig, jedisShardInfos);
	ShardedJedis shardedJedis = shardedJedisPool.getResource();
	shardedJedis .auth(password);

方式四:Redis集群;new JedisCluster(jedisClusterNodes);

3、jedis常见操作

(1) 对DB的操作

		jedis.select(0);   //切换到DB0

(2) 对key的操作

		jedis.flushDB();   //清除数据
        jedis.exists(key);   //判断某个键是否存在
        jedis.set(key, value);   //新增键值对
        jedis.keys("*").toString();   //查看系统中所有的键
        jedis.del(key);    //删除键
        jedis.expire(key, 5);   //设置键的过期时间(单位:秒)
        jedis.ttl(key);   //查看键的剩余生存时间
        jedis.persist(key);   //移除键的生存时间
        jedis.type(key);    //查看键所存储的值的类型
        jedis.get(key);    //查看键的值

(3) 对字符串的操作

		jedis.del(key);    //删除键
        jedis.get(key);    //获取键
        jedis.set(key, newValue));    //修改键的值
        jedis.append(key, value));    //在键 c后面加入值
        jedis.mset(key1, value1, key2, value2);    //增加多个键值对
        jedis.del(new String[]{key1, key2});    //删除多个键值对
        jedis.mget(key1, key2);    //获取多个键值对
        jedis.setnx(key, value001);     //新增键值对防止覆盖原先值
        jedis.setex(key, 2, value);     //新增键值对并设置有效时间
        jedis.getSet(key, value);    //获取原值,更新为新值
        jedis.getrange(key, 2, 5));    //截取key的值的字符串
        
        //整型和浮点型以字符串类型存储,但相对于普通的字符串类型数据会多一些特有的操作
		jedis.get(key);    //获取键的值
        jedis.incr(key);    //将键的值+1
        jedis.decr(key);    //将键的值-1
        jedis.incrBy(key, 2));    //将键的值加上整数2
        jedis.decrBy(key, 2));    //将键的值减去整数2

(4)对Hash的操作
(5)对list列表的操作
(6)对set集合的操作
(7)对zset(sorted set)有序集合的操作

未完待续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Jedis使用总结 前段时间细节的了解了Jedis使用Jedisredis的java版本的客户端实现。 本文做个总结,主要分享如下内容: 【pipeline】【分布式的id生成器】【分布式锁【watch】【multi】】【redis分布式】 好了,一个一个来。 一、 Pipeline 官方的说明是:starts a pipeline,which is a very efficient way to send lots of command and read all the responses when you finish sending them。简单点说pipeline适用于批处理。当有大量的操作需要一次性执行的时候,可以用管道。 示例: Jedis jedis = new Jedis(String, int); Pipeline p = jedis.pipelined(); p.set(key,value);//每个操作都发送请求给redis-server p.get(key,value); p.sync();//这段代码获取所有的response 这里我进行了20w次连续操作(10w读,10w写),不用pipeline耗时:187242ms,用pipeline耗时:1188ms,可见使用管道后的性能上了一个台阶。看了代码了解到,管道通过一次性写入请求,然后一次性读取响应。也就是说jedis是:request response,request response,...;pipeline则是:request request... response response的方式。这样无需每次请求都等待server端的响应。 二、 跨jvm的id生成器 谈到这个话题,首先要知道redis-server端是单线程来处理client端的请求的。 这样来实现一个id生成器就非常简单了,只要简单的调用jdeis.incr(key);就搞定了。 你或许会问,incr是原子操作吗,能保证不会出现并发问题吗,不是说了吗,server端是单线程处理请求的。 三、 【跨jvm的锁实现【watch】【multi】】 首先说下这个问题的使用场景,有些时候我们业务逻辑是在不同的jvm进程甚至是不同的物理机上的jvm处理的。这样如何来实现不同jvm上的同步问题呢,其实我们可以基于redis来实现一个锁。 具体事务和监听请参考文章:redis学习笔记之事务 暂时找到三种实现方式: 1. 通过jedis.setnx(key,value)实现 import java.util.Random; import org.apache.commons.pool.impl.GenericObjectPool.Config; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.Transaction; /** * @author Teaey */ public class RedisLock { //加锁标志 public static final String LOCKED = "TRUE"; public static final long ONE_MILLI_NANOS = 1000000L; //默认超时时间(毫秒) public static final long DEFAULT_TIME_OUT = 3000; public static JedisPool pool; public static final Random r = new Random(); //锁的超时时间(秒),过期删除 public static final int EXPIRE = 5 * 60; static { pool = new JedisPool(new Config(), "host", 6379); } private Jedis jedis; private String key; //锁状态标志 private boolean locked = false; public RedisLock(String key) { this.key = key; this.jedis = pool.getResource(); } public boolean lock(long timeout) { long nano = System.nanoTime(); timeout *= ONE_MILLI_NANOS; try { while ((System.nanoTime() - nano) < timeout) { if (jedis.setnx(key, LOCKED) == 1) { jedis.expire(key, EXPIRE); locked = true; return locked; } // 短暂休眠,nano避免出现活锁 Thread.sleep(3, r.nextInt(500)); } } catch (Exception e) { } return false; } public boolean lock() { return lock(DEFAULT_TIME_OUT); } // 无论是否加锁成功,必须调用 public void unlock() { try { if (locked) jedis.del(key); } finally { pool.returnResource(jedis); } } } 2. 通过事务(multi)实现 由于采纳第一张方法,第二种跟第三种实现只贴了关键代码,望谅解。^_^ public boolean lock_2(long timeout) { long nano = System.nanoTime(); timeout *= ONE_MILLI_NANOS; try { while ((System.nanoTime() - nano) < timeout) { Transaction t = jedis.multi(); // 开启事务,当server端收到multi指令 // 会将该client的命令放入一个队列,然后依次执行,知道收到exec指令 t.getSet(key, LOCKED); t.expire(key, EXPIRE); String ret = (String) t.exec().get(0); if (ret == null || ret.equals("UNLOCK")) { return true; } // 短暂休眠,nano避免出现活锁 Thread.sleep(3, r.nextInt(500)); } } catch (Exception e) { } return false; } 3. 通过事务+监听实现 public boolean lock_3(long timeout) { long nano = System.nanoTime(); timeout *= ONE_MILLI_NANOS; try { while ((System.nanoTime() - nano) < timeout) { jedis.watch(key); // 开启watch之后,如果key的值被修改,则事务失败,exec方法返回null String value = jedis.get(key); if (value == null || value.equals("UNLOCK")) { Transaction t = jedis.multi(); t.setex(key, EXPIRE, LOCKED); if (t.exec() != null) { return true; } } jedis.unwatch(); // 短暂休眠,nano避免出现活锁 Thread.sleep(3, r.nextInt(500)); } } catch (Exception e) { } return false; } 最终采用第一种实现,因为加锁只需发送一个请求,效率最高。 四、 【redis分布式】 最后一个话题,jedis的分布式。在jedis的源码里发现了两种hash算法(MD5,MURMUR Hash(默认)),也可以自己实现redis.clients.util.Hashing接口扩展。 List<JedisShardInfo> hosts = new ArrayList<JedisShardInfo>(); //server1 JedisShardInfo host1 = new JedisShardInfo("", 6380, 2000); //server2 JedisShardInfo host2 = new JedisShardInfo("", 6381, 2000); hosts.add(host1); hosts.add(host2); ShardedJedis jedis = new ShardedJedis(hosts); jedis.set("key", "");

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值