Redis Java客户端Jedis

目前Redis大概有3中基于Java语言的Client:

Jedis是官方提供的唯一Redis Client For Java Provider。

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

一、Jedis简单使用

package cn.slimsmart.redis.demo.jedis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import redis.clients.jedis.Jedis;

@SuppressWarnings("resource")
public class JedisTest {
	private static final String HASH_KEY = "key";

	public static void main(String[] args) {
		Jedis jedis = new Jedis("192.168.36.189", 6379);
		/**
		 * 存储String key-value
		 */
		jedis.set(HASH_KEY, "value");
		/**
		 * 如果已经存在key了,先删除掉
		 */
		if (jedis.exists(HASH_KEY)) {
			System.out.println(jedis.get(HASH_KEY));
			jedis.del(HASH_KEY);
		}

		/**
		 * 存入单个key-value
		 */
		jedis.hset(HASH_KEY, "username", "yourUsername");

		/**
		 * 存入多个key-value键值对
		 */
		Map<String, String> keyValueMap = new HashMap<String, String>();
		keyValueMap.put("password", "YourPassword");
		keyValueMap.put("age", "20");
		jedis.hmset(HASH_KEY, keyValueMap);

		/**
		 * 判断某个key是否在指定的Hash key中
		 */
		boolean existsUsernameKey = jedis.hexists(HASH_KEY, "username");
		// true
		System.out.println(existsUsernameKey);

		/**
		 * 获取某个hash中键值对的数量
		 */
		Long len = jedis.hlen(HASH_KEY);
		// 3
		System.out.println(len);

		/**
		 * 获取一个hash中的所有key
		 */
		Set<String> keys = jedis.hkeys(HASH_KEY);
		// [password, username, age]
		System.out.println(keys);

		/**
		 * 获取一个hash中的所有values
		 */
		List<String> values = jedis.hvals(HASH_KEY);
		// [yourUsername, YourPassword, 20]
		System.out.println(values);

		/**
		 * 获取指定hash的所有的键值对
		 */
		Map<String, String> allKVMap = jedis.hgetAll(HASH_KEY);
		// {username=yourUsername, age=20, password=YourPassword}
		System.out.println(allKVMap);

		/**
		 * 从一个hash中获取某个field的值
		 */
		String value = jedis.hget(HASH_KEY, "username");
		// yourUsername
		System.out.println(value);

		List<String> multValues = jedis.hmget(HASH_KEY, "username", "password");
		// [yourUsername, YourPassword]
		System.out.println(multValues);
	}

}
二、连接池的使用

Jedis使用commons-pool完成池化实现。
1.配置文件redis.properties

redis.pool.maxTotal=10
redis.pool.minIdle=2
redis.pool.maxIdle=10
redis.pool.maxWait=1000
redis.pool.testWhileIdle=true
redis.pool.testOnBorrow=true
redis.pool.testOnReturn=true
#IP
redis.ip=192.168.36.189
#Port
redis.port=6379
2.实例代码

package cn.slimsmart.redis.demo.jedis;

import java.util.ResourceBundle;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisPoolTest {
	public static void main(String[] args) {
		ResourceBundle bundle = ResourceBundle.getBundle("redis");
		if (bundle == null) {
			throw new IllegalArgumentException("[redis.properties] is not found!");
		}
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(Integer.valueOf(bundle.getString("redis.pool.maxTotal")));
		config.setMinIdle(Integer.valueOf(bundle.getString("redis.pool.minIdle")));
		config.setMaxIdle(Integer.valueOf(bundle.getString("redis.pool.maxIdle")));
		config.setMaxWaitMillis(Long.valueOf(bundle.getString("redis.pool.maxWait")));
		config.setTestWhileIdle(Boolean.valueOf(bundle.getString("redis.pool.testWhileIdle")));
		config.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow")));
		config.setTestOnReturn(Boolean.valueOf(bundle.getString("redis.pool.testOnReturn")));
		JedisPool pool = new JedisPool(config, bundle.getString("redis.ip"), Integer.valueOf(bundle.getString("redis.port")));

		// 从池中获取一个Jedis对象
		Jedis jedis = pool.getResource();
		String key = "key";
		// 删数据
		jedis.del(key);
		// 存数据
		jedis.set(key, "abc123");
		// 取数据
		String value = jedis.get(key);
		System.out.println(value);
		// 释放对象池
		pool.returnResource(jedis);
	}

}
三、一致性哈希

Memcached完全基于分布式集群,而Redis是Master-Slave,如果想把Reids,做成集群模式,无外乎多做几套Master-Slave,每套Master-Slave完成各自的容灾处理,通过Client工具,完成一致性哈希。Memcached是在Server端完成Sharding,Redis只能依靠各个Client做Sharding。在Redis 3.0系列支持Server端Sharding。

shared一致性哈希采用以下方案:
1.Redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)
2.将划分虚拟节点采用TreeMap存储
3.对每个Redis服务器的物理连接采用LinkedHashMap存储
4.对Key采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点
sharded采用的hash算法:MD5和MurmurHash两种;默认采用64位的MurmurHash算法。

1.配置文件redis.properties

redis.pool.maxTotal=10
redis.pool.minIdle=2
redis.pool.maxIdle=10
redis.pool.maxWait=1000
redis.pool.testWhileIdle=true
redis.pool.testOnBorrow=true
redis.pool.testOnReturn=true
#IP
redis1.ip=192.168.36.189
redis2.ip=192.168.36.54
#Port
redis.port=6379
2.实例代码

package cn.slimsmart.redis.demo.jedis;

import java.util.LinkedList;
import java.util.List;
import java.util.ResourceBundle;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

public class JedisShardInfoTest {

	public static void main(String[] args) {
		ResourceBundle bundle = ResourceBundle.getBundle("redis");
		if (bundle == null) {
			throw new IllegalArgumentException("[redis.properties] is not found!");
		}
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(Integer.valueOf(bundle.getString("redis.pool.maxTotal")));
		config.setMinIdle(Integer.valueOf(bundle.getString("redis.pool.minIdle")));
		config.setMaxIdle(Integer.valueOf(bundle.getString("redis.pool.maxIdle")));
		config.setMaxWaitMillis(Long.valueOf(bundle.getString("redis.pool.maxWait")));
		config.setTestWhileIdle(Boolean.valueOf(bundle.getString("redis.pool.testWhileIdle")));
		config.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow")));
		config.setTestOnReturn(Boolean.valueOf(bundle.getString("redis.pool.testOnReturn")));

		JedisShardInfo jedisShardInfo1 = new JedisShardInfo(bundle.getString("redis1.ip"), Integer.valueOf(bundle.getString("redis.port")));
		JedisShardInfo jedisShardInfo2 = new JedisShardInfo(bundle.getString("redis2.ip"), Integer.valueOf(bundle.getString("redis.port")));
		List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
		list.add(jedisShardInfo1);
		list.add(jedisShardInfo2);
		// 初始化ShardedJedisPool代替JedisPool
		ShardedJedisPool pool = new ShardedJedisPool(config, list);  
		// 从池中获取一个Jedis对象
		ShardedJedis jedis = pool.getResource();
		String keys = "key";
		String value = "abc123";
		// 删数据
		jedis.del(keys);
		// 存数据
		jedis.set(keys, value);
		// 取数据
		String v = jedis.get(keys);
		System.out.println(v);
		// 释放对象池
		pool.returnResource(jedis);
	}
}

通过以上方式,向redis进行set操作的key-value,会通过hash而均匀的分配到pool里的redis机器中。

四、Spring集成

如果有必要,可以用Spring封装初始化。

<context:property-placeholder location="classpath:redis.properties" />
<bean
	id="jedisPoolConfig"
	class="redis.clients.jedis.JedisPoolConfig">
	<property
		name="maxTotal"
		value="${redis.pool.maxTotal}" />
	<property
		name="minIdle"
		value="${redis.pool.minIdle}" />	
	<property
		name="maxIdle"
		value="${redis.pool.maxIdle}" />
	<property
		name="maxWait"
		value="${redis.pool.maxWait}" />
	<property
		name="testWhileIdle"
		value="${redis.pool.testWhileIdle}" />
	<property
		name="testOnBorrow"
		value="${redis.pool.testOnBorrow}" />
	<property
		name="testOnReturn"
		value="${redis.pool.testOnReturn}" />
</bean>
<bean
	id="shardedJedisPool"
	class="redis.clients.jedis.ShardedJedisPool">
	<constructor-arg
		index="0"
		ref="jedisPoolConfig" />
	<constructor-arg index="1">
		<list>
			<bean class="redis.clients.jedis.JedisShardInfo">
				<constructor-arg
					index="0"
					value="${redis1.ip}" />
				<constructor-arg
					index="1"
					value="${redis.port}"
					type="int" />
			</bean>
			<bean class="redis.clients.jedis.JedisShardInfo">
				<constructor-arg
					index="0"
					value="${redis2.ip}" />
				<constructor-arg
					index="1"
					value="${redis.port}"
					type="int" />
			</bean>
		</list>
	</constructor-arg>
</bean>
当然,Spring提供了对于Redis的专门支持: spring-data-redis

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值