首页 技术 正文
技术 2022年11月21日
0 收藏 737 点赞 4,621 浏览 6482 个字

一、实现原理

  一致性哈希算法(Consistent Hashing): http://www.zsythink.net/archives/1182

二、配置两个redis服务,端口号要不一致

三、代码

. 配置文件
redis1.ip = 127.0.0.1
redis1.port= redis2.ip = 127.0.0.1
redis2.port= #最大连接数
redis.max.total=
#最大空闲数
redis.max.idle=
#最小空闲数
redis.min.idle=
#效验使用可用连接
redis.test.borrow=true
#效验归还可用连接
redis.test.return=false
 package com.mmall.common; import com.mmall.util.PropertiesUtil;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;
import java.util.ArrayList;
import java.util.List; /**
* redis分片连接池
*/
public class RedisShardedPool {
private static ShardedJedisPool pool ; //jedis连接池
private static Integer maxTotal = Integer.parseInt(PropertiesUtil.getProperty("redis.max.total","20")); //最大连接数
private static Integer maxIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.max.idle","10")); //最大空闲状态
private static Integer minIdle =Integer.parseInt(PropertiesUtil.getProperty("redis.min.idle","2")); //最小空闲状态 private static Boolean testOnBorrow =Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.borrow","true")); //验证从连接池拿出的jedis实例,一定可用
private static Boolean testOnReturn =Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.return","true")); //验证还回连接池的jedis实例,一定可用 private static String redis1Ip =PropertiesUtil.getProperty("redis1.ip"); //最小空闲状态
private static Integer redis1Port =Integer.parseInt(PropertiesUtil.getProperty("redis1.port")); //最小空闲状态
private static String redis2Ip =PropertiesUtil.getProperty("redis2.ip"); //最小空闲状态
private static Integer redis2Port =Integer.parseInt(PropertiesUtil.getProperty("redis2.port")); //最小空闲状态 private static void initPool(){
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
config.setMinIdle(minIdle); config.setTestOnBorrow(testOnBorrow);
config.setTestOnReturn(testOnReturn); config.setBlockWhenExhausted(true); //连接耗尽时是否阻塞,false抛出异常;true阻塞到超时。默认true JedisShardInfo info1 = new JedisShardInfo(redis1Ip,redis1Port,1000*2);
JedisShardInfo info2 = new JedisShardInfo(redis2Ip,redis2Port,1000*2);
List<JedisShardInfo> jedisShardInfoList = new ArrayList<JedisShardInfo>(2);
jedisShardInfoList.add(info1);
jedisShardInfoList.add(info2); pool = new ShardedJedisPool(config,jedisShardInfoList, Hashing.MURMUR_HASH, Sharded.DEFAULT_KEY_TAG_PATTERN);
} static{
initPool();
} public static ShardedJedis getJedis(){
return pool.getResource();
} /**
* redis不正常不可用,将其废弃,最新版本直接将此连接销毁jedis.close();
* @param jedis
*/
public static void returnBrokenResource(ShardedJedis jedis){
pool.returnBrokenResource(jedis);
} public static void returnResource(ShardedJedis jedis){
pool.returnResource(jedis);
} public static void main(String[] args) {
ShardedJedis shardedJedis = pool.getResource();
for (int i = 0; i<10; i++){
shardedJedis.set("key"+i,"value"+i);
}
returnResource(shardedJedis); //使用后的连接放回连接池中
// pool.destroy(); // 销毁连接池的所有连接
System.out.println("program is end"); }
}

运行main方法,查询redis生成的数据:

redis集群(多机)分布

封装常用redisAPI

import com.mmall.common.RedisShardedPool;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ShardedJedis;/**
* 封装分片redis
*/
@Slf4j
public class RedisShardedPoolUtil { /**
* 设置对应key的有效期
* @param key
* @param exTime 有效期,单位秒
* @return
*/
public static Long expire(String key, int exTime){
ShardedJedis shardedJedis = null;
Long result = null;
try{
shardedJedis = RedisShardedPool.getJedis();
result = shardedJedis.expire(key,exTime);
}catch (Exception e){
log.error("set key:{} exTime:{} value:{} error",key,exTime,e);
RedisShardedPool.returnBrokenResource(shardedJedis);
return result;
}
RedisShardedPool.returnResource(shardedJedis);
return result;
} /**
* string 添加,存在有效期exTime
* @param key 键
* @param value 值
* @param exTime 有效期,单位秒
* @return
*/
public static String setEx(String key, String value, int exTime){
ShardedJedis shardedJedis = null;
String result = null;
try{
shardedJedis = RedisShardedPool.getJedis();
result = shardedJedis.setex(key,exTime,value);
}catch (Exception e){
log.error("set key:{} exTime:{} value:{} error",key,exTime,value,e);
RedisShardedPool.returnBrokenResource(shardedJedis);
return result;
}
RedisShardedPool.returnResource(shardedJedis);
return result;
} /**
* string 添加
* @param key
* @param value
* @return
*/
public static String set(String key, String value){
ShardedJedis shardedJedis = null;
String result = null;
try{
shardedJedis = RedisShardedPool.getJedis();
result = shardedJedis.set(key,value);
}catch (Exception e){
log.error("set key:{} value:{} error",key,value,e);
RedisShardedPool.returnBrokenResource(shardedJedis);
return result;
}
RedisShardedPool.returnResource(shardedJedis);
return result;
} /**
* string 获取
* @param key
* @return
*/
public static String get(String key){
ShardedJedis shardedJedis = null;
String result = null;
try{
shardedJedis = RedisShardedPool.getJedis();
result = shardedJedis.get(key);
}catch (Exception e){
log.error("get key:{} error",key,e);
RedisShardedPool.returnBrokenResource(shardedJedis);
return result;
}
RedisShardedPool.returnResource(shardedJedis);
return result;
}
public static String getSet(String key, String value){
ShardedJedis shardedJedis = null;
String result = null;
try{
shardedJedis = RedisShardedPool.getJedis();
result = shardedJedis.getSet(key,value);
}catch (Exception e){
log.error("set key:{} value:{} error",key,value,e);
RedisShardedPool.returnBrokenResource(shardedJedis);
return result;
}
RedisShardedPool.returnResource(shardedJedis);
return result;
} /**
* stirng 删除
* @param key
* @return
*/
public static Long del(String key){
ShardedJedis shardedJedis = null;
Long result = null;
try{
shardedJedis = RedisShardedPool.getJedis();
result = shardedJedis.del(key);
}catch (Exception e){
log.error("get key:{} error",key,e);
RedisShardedPool.returnBrokenResource(shardedJedis);
return result;
}
RedisShardedPool.returnResource(shardedJedis);
return result;
} public static Long setnx(String key, String value){
ShardedJedis shardedJedis = null;
Long result = null;
try{
shardedJedis = RedisShardedPool.getJedis();
result = shardedJedis.setnx(key,value);
}catch (Exception e){
log.error("set key:{} value:{} error",key,value,e);
RedisShardedPool.returnBrokenResource(shardedJedis);
return result;
}
RedisShardedPool.returnResource(shardedJedis);
return result;
}
}

四、ShardedJedis相关类介绍

  (1)、ShardedJedisPool

    ShardedJedis是基于一致性哈希算法实现的分布式Redis集群客户端;ShardedJedis的设计分为以下几块:
    对象池设计:Pool,ShardedJedisPool,ShardedJedisFactory
    面向用户的操作封装:BinaryShardedJedis,BinaryShardedJedis
    一致性哈希实现:Sharded

    Sharded一致性哈希实现
    shared一致性哈希采用以下方案:
    Redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)
    将划分虚拟节点采用TreeMap存储
    对每个Redis服务器的物理连接采用LinkedHashMap存储
     对Key or KeyTag 采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点。

  (2)、JedisShardInfo

      配置每台redis服务器的连接

     JedisShardInfo info1 = new JedisShardInfo(redis1Ip,redis1Port,1000*2);
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,077
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,552
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,401
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,813
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,896