redis 工具包
java通过jedis操作redis(从JedisPool到JedisCluster)
redis作为一个缓存数据库,在绝大多数java项目开发中是必须使用的,在web项目中,直接配合spring-redis,各种配置都直接在spring配置文件中做了,一般都是使用redis连接池。在非web项目中,通常也是使用的redis连接池。
根据redis的机器数量和集群方式,又分为以下三种方式:普通单机版的redis,多机器的分片集群,多机器的cluster集群方式(redis3版本以上)。
对于单机版的redis使用简单示例如下:
- import redis.clients.jedis.Jedis;
- import redis.clients.jedis.JedisPool;
- import redis.clients.jedis.JedisPoolConfig;
- public class JedisPoolUtil {
- private static JedisPool jedisPool;
- public static JedisPool getJedisPool(){
- if(jedisPool == null){
- JedisPoolConfig config = new JedisPoolConfig();
- config.setMaxIdle(200);
- config.setMaxIdle(50);
- config.setMaxWaitMillis(1000 * 100);
- config.setTestOnBorrow(false);
- jedisPool = new JedisPool(config, "192.168.42.128",6379);
- }
- return jedisPool;
- }
- public static String get(String key){
- String value = null;
- JedisPool pool = null;
- Jedis jedis = null;
- try{
- pool = getJedisPool();
- jedis = pool.getResource();
- value = jedis.get(key);
- }catch(Exception e){
- e.printStackTrace();
- }
- return value;
- }
- public static void set(String key,String value){
- JedisPool pool = null;
- Jedis jedis = null;
- try{
- pool = getJedisPool();
- jedis = pool.getResource();
- value = jedis.set(key,value);
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- set("name", "xx-jedis");
- String name = get("name");
- System.out.println(name);
- }
- }
这是一个最简单的demo,实际项目中,会配置redis host,port等信息,也会根据redis支持的方法和jedis的api,完善更多的方法,如delete,expire,sadd,lpush等等。
当项目增大,需要缓存的数据量增大,我们会考虑做分布式集群,集群的数量可以根据业务需求扩展。数据存储会均匀分布在各个分片上。这里给出一个示例:
- import java.util.ArrayList;
- import java.util.List;
- import redis.clients.jedis.JedisPoolConfig;
- import redis.clients.jedis.JedisShardInfo;
- import redis.clients.jedis.ShardedJedis;
- import redis.clients.jedis.ShardedJedisPool;
- public class ShardedPoolUtil {
- private static ShardedJedisPool jedisPool;
- public static ShardedJedisPool getJedisPool(){
- if(jedisPool == null){
- JedisPoolConfig config = new JedisPoolConfig();
- config.setMaxTotal(200);
- config.setMaxIdle(50);
- config.setMaxWaitMillis(1000*100);
- config.setTestOnBorrow(false);
- List<JedisShardInfo> shareInfos = new ArrayList<JedisShardInfo>();
- shareInfos.add(new JedisShardInfo("192.168.42.128", 6379));
- shareInfos.add(new JedisShardInfo("192.168.42.128", 6380));
- jedisPool = new ShardedJedisPool(config, shareInfos);
- }
- return jedisPool;
- }
- public static void set(String key,String value){
- ShardedJedisPool pool = null;
- ShardedJedis jedis = null;
- try{
- pool = getJedisPool();
- jedis = pool.getResource();
- jedis.set(key, value);
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- public static String get(String key){
- String value = null;
- ShardedJedisPool pool = null;
- ShardedJedis jedis = null;
- try{
- pool = getJedisPool();
- jedis = pool.getResource();
- value = jedis.get(key);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return value;
- }
- public static void main(String[] args) {
- String age = "30";
- String address = "beijing";
- set("age", age);
- set("address", address);
- System.out.println(get("age"));
- System.out.println(get("address"));
- }
- }
相对单机版的redis,sharding分布式集群方式:配置ShardedJedisPool多了设置多个redis服务器信息。 数据分布在哪个机器上,是有算法的,这里支持MD5和MURMUR两种散列函数的方式,默认采用的是MURMUR哈希方法。
这第二种方法,虽然是分布式的,数据分布在不同的机器上,但是并没有采用集群的方式,因为支持redis集群的是3.0版本及以上,目前redis集群方式,数据是以槽的方式分布的,因为需要保证一个master对应至少一个slave节点,所以节点数会比sharding分布式节点多。
redis-cluster这种情况下,java调用的方式会发生一些变化,但是还是相似的思路。
- import java.util.HashSet;
- import java.util.Set;
- import redis.clients.jedis.HostAndPort;
- import redis.clients.jedis.JedisCluster;
- import redis.clients.jedis.JedisPoolConfig;
- public class ClusterPoolUtil {
- private static JedisCluster jedisCluster;
- private static String hostAndPorts = "192.168.42.128:6379||192.168.42.128:6380||"
- + "192.168.42.128:6381||192.168.42.128:6382||"
- + "192.168.42.128:6383||192.168.42.128:6384";
- public static JedisCluster getJedisCluster(){
- if(jedisCluster==null){
- int timeOut = 10000;
- Set<HostAndPort> nodes = new HashSet<HostAndPort>();
- JedisPoolConfig poolConfig = new JedisPoolConfig();
- poolConfig.setMaxTotal(200);
- poolConfig.setMaxIdle(50);
- poolConfig.setMaxWaitMillis(1000 * 100);
- poolConfig.setTestOnBorrow(false);
- String[] hosts = hostAndPorts.split("\\|\\|");
- for(String hostport:hosts){
- String[] ipport = hostport.split(":");
- String ip = ipport[0];
- int port = Integer.parseInt(ipport[1]);
- nodes.add(new HostAndPort(ip, port));
- }
- jedisCluster = new JedisCluster(nodes,timeOut, poolConfig);
- }
- return jedisCluster;
- }
- public static void set(String key,String value){
- JedisCluster jedisCluster = getJedisCluster();
- jedisCluster.set(key, value);
- }
- public static String get(String key){
- String value = null;
- JedisCluster jedisCluster = getJedisCluster();
- value = jedisCluster.get(key);
- return value;
- }
- public static void main(String[] args) {
- set("name-1", "value-1");
- set("name-2", "value-2");
- set("name-3", "value-3");
- System.out.println(get("name-1"));
- System.out.println(get("name-2"));
- System.out.println(get("name-3"));
- }
- }
redis-cluster集群安装好了之后,做好slot分配,就可以开始使用redis存储和查找了。redis-cluster是redis3开始支持的,他与sharding分片方式不同的是,数据是按照slot槽(16384个slot)分布的,slot的划分不是固定的,可以人为指定。这里使用了六个节点,分为三组,所以slot划分为3组槽(5461,5461,5460),分别如下:
- {
- =192.168.42.128:, =192.168.42.128:,
- =192.168.42.128:, =192.168.42.128:,
- =192.168.42.128:, =192.168.42.128:
- }
第一组是0-5460,第二组是5461-10922,第三组是10993-16383,从分组中可以看出,6380,6382,6384端口的节点都是master节点,这可以在redis-cluster集群中查看:
存储的key分布在哪个槽上,可以通过如下方法获取:
- public static int getSlot(String key){
- return JedisClusterCRC16.getSlot(key);
- }
按照这种方法计算name-1,name-2,name-3的slot槽分别是:10801,6738,2675。按照之前的slot分布,可以得到name-1,name-2均落在6380上,name-3则落在6382上,我们可以在redis-cluster集群上通过命令来查找key,验证了这个结果:
redis 工具包的更多相关文章
- redis的面试题
1:使用redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,lis ...
- [Redis]Redis 概述及基本使用规范.
1 nosql的简介 1.1 nosql简介 随着互联网Web2.0网站的兴起,传统的关系数据库在应付Web2.0网站,特别是超大规模和高并发的SNS类型的Web2.0纯动态网站已经显得力不从心,暴露 ...
- Redis教程(八):事务详解
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/135.html?1455806987 一.概述: 和众多其它数据库一样,R ...
- Redis学习手册(事务)
一.概述: 和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制.在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基石.相信对有关系型数据 ...
- Redis的那些最常见面试问题
随笔:经过长达一周的奔波和面试,电话面试,回首今天终于成功的入职了,总共面试了大概10家公司,包括阿里,京东,IBM等等,京东技术过了,学历因为非统招就被pass了,阿里面了2次电话面试就没下文了,估 ...
- Redis入门教程(二)
推荐阅读: Redis入门教程(一)https://www.cnblogs.com/jichi/p/10285346.html 5. Redis 的数据结构 5.1 Redis 数据结构介绍 redi ...
- 值得一看的35个Redis常用问题总结
1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.Reids的特点 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库 ...
- redis入门知识汇总
1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.Reids的特点 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库 ...
- (转)Redis的那些最常见面试问题
背景:最近在准备面试相关的题目,发现redis基本一片空白,有必要好好总结下. 转自:https://www.cnblogs.com/Survivalist/p/8119891.html 1.什么是r ...
随机推荐
- Mybatis源码学习之反射工具(三)
简述 MyBatis在进行参数处理.结果映射等操作时,会涉及大量的反射操作.Java中的反射虽然功能强大,但是代码编写起来比较复杂且容易出错,为了简化反射操作的相关代码,MyBatis提供了专门的反射 ...
- AT3912 Antennas on Tree
AT3912 Antennas on Tree %%zzt 只能考虑性质了. 把最后选择的k个点的连通块求出来,连通块内部的点表示都是互异的 连通块外部的点只能形成若干条链,并且这k个点的每一个最多与 ...
- JavaScript设计模式—代理模式
代理模式介绍 使用者无权访问目标对象,中间加代理,通过代理做授权和控制 代理(proxy)是一个对象,它可以用来控制对另外一个对象的访问: 代理对象和本体对象实现了同样的接口,并且会把任何方法调用传递 ...
- windos系统下使tomcat按天生成控制台日志catalina.out
windos系统下的tomcat默认不会记录控制台catalina.out日志,只有访问日志,不便于排错 修改启动文件 1.打开bin下面的startup.bat文件,把 call "%EX ...
- Zookeeper系列(十四)Zookeeper的数据与存储
作者:leesf 掌控之中,才会成功:掌控之外,注定失败. 出处:http://www.cnblogs.com/leesf456/p/6179118.html尊重原创,奇文共欣赏: 一.前言 前 ...
- Leetcode题目55.跳跃游戏(贪心算法-中等)
题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出: ...
- 状压dp,松鼠从起点出发,拿到所有坚果,然后返回起点,求最短时间。
UVA10944 松鼠从起点出发,拿到所有坚果,然后返回起点,求最短时间. #include<iostream> #include<cstdio> #include<al ...
- Qt子窗口QMidSubwindow全屏出现的问题总结
我的需求:想全屏一个子窗口QMidSubwindow,禁止显示最大化最小化和关闭按钮. 我开始尝试的是网上介绍的方法,把结果展现给大家一下,最后再总结: 方法1:QMidSubwindow直接调用sh ...
- Mac下mysql服务端密码重置及环境配置
一 停止mysql服务 关闭MySQL服务的操作: 苹果->系统偏好设置->最下边点MySQL 在弹出页面中 关闭mysql服务(点击stop mysql server) 二 进入终端,命 ...
- ubuntu下如何使用dpkg删除某个软件包?
答:步骤如下: 1. 找出包名 dpkg -l |grep <package name> 2. 卸载 dpkg -r <package name>