Java对Redis集群部署工具类(单个Redis服务器同样适用)
前言
在高并发的前提下,频繁的对数据库访问IO操作会增加数据库负担。 Redis中间件可以完美的解决这个问题。 我们可以将经常需要读取但是不经常变化的一些数据放入到Redis中,因为读取的时候是向内存中读取数据,可以大大减少运行和等待时间。有效的减少数据库的IO操作,从而提高系统运行的效率。注意
Redis集群化部署的时候,一个value值会根据key的哈希值存放到一个Redis服务器。 也就是说在进行测试集群化Redis的时候,要存取多个值才会更加明显。该Redis集群化部署工具类的优点
Redis的连接池是动态的
也就是说,只要你配置的Redis集群服务器只要有一台在正常工作,改工具类就可以正常使用。
在程序运行过程中,增加或者减少Redis服务器都可以正常运行。只要在配置文件中写入了改Redis服务器的IP和端口,改Redis服务器就会被正常地加载到集群中。
一、Redis集群化部署工具类
因为在这里我使用了自定义的读取配置文件的工具类还有日志工具,后面一并写出
进行集群化部署配置
*在这里我配置了本地(127.0.0.1)三个端口的服务器
6379
8090
8091
统一设置最大连接数都为200
*
# redis服务器地址&多个
jedisIp=127.0.0.1&127.0.0.1&127.0.0.1
# redis服务器端口
jedisPort=6379&8090&8091
# redis最大连接数
jedisMaxTotal=200
读取配置文件工具源码
package com.mabo.utils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
/**
* @Author mabo
* @Description 用于读取配置文件的工具类
*/
public class PropertyUtil {
private LogUtil log=new LogUtil();
//设置配置文件的基本路径
private String path;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
/**
* @Author mabo
* @Description 获取配置文件对象
*/
public Properties getProperties(String propertiesName) {
log.info("========读取配置文件工具开始");
String springManager="spring-manager.xml";
Properties props = new Properties();
ApplicationContext context=new ClassPathXmlApplicationContext(springManager);
if(context!=null){
PropertyUtil propertyUtil=null;
String propertyUtilBean="propertyUtil";
Object propertyUtilObject = context.getBean(propertyUtilBean);
if(propertyUtilObject!=null){
propertyUtil = (PropertyUtil)propertyUtilObject;
path=propertyUtil.getPath();
Resource resource = new ClassPathResource(path+propertiesName);
if(resource!=null){
try {
InputStream is = resource.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
props.load(bf);
log.info(propertiesName+"配置文件读取成功");
} catch (Exception e) {
e.printStackTrace();
log.error(propertiesName+"配置文件读取失败");
}
}
else log.error(propertiesName+"配置文件不存在");
}
else log.error(propertyUtilBean+" bean 不存在");
}
else log.error(springManager+"配置文件读取失败");
log.info("========读取配置文件工具结束");
return props;
}
/**
* @Author mabo
* @Description 指定配置文件名,和key,获取value
*/
public String get(String propertyFileName,String key){
PropertyUtil propertyUtil=new PropertyUtil();
Properties properties = propertyUtil.getProperties(propertyFileName);
String value=null;
value = properties.getProperty(key);
if (value==null){
log.error("配置文件"+propertyFileName+"获取-------:"+key+"失败");
}
else log.info("配置文件"+propertyFileName+"获取--------:"+key+"成功");
return value;
}
}
spring的相关配置
<?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.xsd">
<!--log输出日志-->
<bean id="logUtil" class="com.mabo.utils.LogUtil"></bean>
<!--读取配置文件的工具类-->
<bean id="propertyUtil" class="com.mabo.utils.PropertyUtil">
<!--配置文件读取的根路径-->
<property name="path" value="properties/"></property>
</bean>
<!-- jedie操作工具-->
<bean id="jedisSharkUtil" class="com.mabo.utils.JedisSharkUtil">
<property name="log" ref="logUtil"></property>
<property name="properties" ref="propertyUtil"></property>
</bean>
</beans>
Redis集群工具类源码
import redis.clients.jedis.*;
import java.util.ArrayList;
import java.util.List;
/**
* @Author mabo
* @Description 集群部署redis使用改工具类
*/
public class JedisSharkUtil {
private LogUtil log;
private PropertyUtil properties;
public void setLog(LogUtil log) {
this.log = log;
}
public void setProperties(PropertyUtil properties) {
this.properties = properties;
}
ShardedJedisPool shardedJedisPool=null;
/**
* @Author mabo
* @Description 获取jedis连接对象
*/
public ShardedJedis getShardedJedis(){
log.info("JedisSharkUtil连接---------开始");
String jedisIp = properties.get("config.properties", "jedisIp");
String jedisPort = properties.get("config.properties", "jedisPort");
int jedisMaxTotal=Integer.parseInt(properties.get("config.properties", "jedisMaxTotal"));
String[] ips = jedisIp.split("&");
String[] ports = jedisPort.split("&");
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
for (int i=0;i< ips.length;i++) {
//获取连接对象jedis
try {
JedisPoolConfig poolConfig = new JedisPoolConfig();
//创建连接池
JedisPool pool = new JedisPool(poolConfig, ips[i], Integer.parseInt(ports[i]));
Jedis jedis = null;
try {
jedis = pool.getResource();
} catch (Exception e) {
e.printStackTrace();
}
if (jedis!=null){
int port=Integer.parseInt(ports[i]);
shards.add(new JedisShardInfo(ips[i],port));
log.info(ips[i]+":"+ports[i]+"即将连接");
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
//配置连接池最大连接数量
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(jedisMaxTotal);
//创建分片式redis连接池
shardedJedisPool = new ShardedJedisPool(poolConfig, shards);
try {
//获取连接
ShardedJedis jedis = shardedJedisPool.getResource();
//序列化当前的集群
log.info("JedisSharkUtil连接---------成功结束");
return jedis;
} catch (Exception e) {
e.printStackTrace();
log.info("JedisSharkUtil连接---------失败");
}
return null;
}
/**
* @Author mabo
* @Description 改方法必须在getShardedJedis()方法执行之后再使用才有值
*/
public ShardedJedisPool getShardedJedisPool(){
log.info("JedisSharkUtil连接---------结束");
return shardedJedisPool;
}
}
日志工具类源码
package com.mabo.utils;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author mabo
* @Description 日志记录工具类
*/
public class LogUtil {
// String path = System.getProperty("user.dir")+"/systemLogs/";
String path =this.getClass().getResource("").getPath();
SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat ymdHMS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* @Author mabo
* @Description 用于接受消息
*/
public void message(String info,int flag){
for(int i=0;i<5;i++){
File file=new File(path);
path = file.getParent();
}
path=path+"/systemLogs/";
String messageType="";
if(flag==1){
messageType="信息|||||||";
}
else if(flag==0){
messageType="错误-------";
}
Date date=new Date();
File folder = new File(path+ymd.format(date));
if (!folder.exists() && !folder.isDirectory()) {
folder.mkdirs();
}
File file = new File(folder+"/"+date.getHours()+".txt");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
OutputStreamWriter write = null;
try {
write = new OutputStreamWriter(new FileOutputStream(file,true),"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedWriter writer=new BufferedWriter(write);
//写入信息
try {
writer.append(messageType+ymdHMS.format(date)+"=====:"+info);
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Author mabo
* @Description 信息日志
*/
public void info(String info){
LogUtil logUtil=new LogUtil();
logUtil.message(info,1);
}
/**
* @Author mabo
* @Description 错误日志
*/
public void error(String error) {
LogUtil logUtil=new LogUtil();
logUtil.message(error,0);
}
}
如何使用
在同一台计算机,多端口的前提下
经过测试,在存取6个Key-Value键值对,for循环读取6个键值对10000次的时候
1个Redis服务器完成需要9.958秒
2个Redis服务器完成需要8.559秒*
3个Redis服务器完成需要6.270秒*
public class JedisSharkUtilTest {
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-manager.xml");
JedisSharkUtil jedisSharkUtil = (JedisSharkUtil) context.getBean("jedisSharkUtil");
ShardedJedis jedis = jedisSharkUtil.getShardedJedis();
LogUtil log=new LogUtil();
jedis.set("1asd","mabo");
jedis.set("2qqe","12345");
jedis.set("3dffdsg","12345");
jedis.set("4ada","mabo");
jedis.set("5fsdf","12345");
jedis.set("6hfd","12345");
for (int i = 0; i < 10000; i++) {
jedis.get("1asd");
jedis.get("2qqe");
jedis.get("3dffdsg");
jedis.get("4ada");
jedis.get("5fsdf");
jedis.get("6hfd");
}
jedis.close();
ShardedJedisPool shardedJedisPool = jedisSharkUtil.getShardedJedisPool();
shardedJedisPool.close();
}
}