前言

分别论述Ubuntu、Mac、Windows系统下Redis的安装配置。

Ubuntu下Redis的安装配置

测试使用的系统版本是Ubuntu16.04,其他Linux环境应该是差别不大。

安装命令

sudo apt-get install redis-server

安装完成后即可运行和查看

ps -aux|grep redis
netstat -nlt|grep 6379
sudo /etc/init.d/redis-server status

默认情况下密码为空,仅能本地访问,如果要设置远程访问和密码,可修改redis.conf文件

sudo vim /etc/redis/redis.conf

找到127.0.0.1,修改为0.0.0.0,则可以远程访问。

bind 0.0.0.0

找到################################## SECURITY ###################################下的requirepass,注释放开,设置密码,并非必须,不设置的话,连接使用用空即可

requirepass XXxxxxXX

设置完成后可重启

/etc/init.d/redis-server stop #停止
/etc/init.d/redis-server start #启动
/etc/init.d/redis-server restart #重启

Mac下Redis的安装配置

测试使用的系统版本是macOS Catalina 10.15.7

需要从官网下载安装包,官网地址:https://redis.io/download/,下载位置如下图(官网升级位置可能会有变化)

RedissonClient 需要依赖包_macos


下载速度略微感人,多等等,或者查看本人csdn下载资源,可直接下载使用,点击这里

下载完成后解压,双击就能解压,或者使用tar -zxvf 命令,并且重命名文件夹,比如改成redis-6.2.6。将文件夹redis-6.2.6移动到/usr/local中(sudo mv redis-6.2.2 /usr/local)

移动完成后,打开终端,进入该文件夹,并执行编译测试(等待时间可能会很久)

cd /usr/local/redis-6.2.2
sudo make test

如果执行完成后最终显示的是OK,则代表测试通过,可以执行下面的安装命令。

sudo make install

安装成功后可本地启动测试,启动文件位于redis-6.2.2中src文件夹

cd src
./redis-server

Windows下Redis的安装配置

老早版本就已经不支持Windows了,最最开始还是有的,大概到3.0以后就很难找到了,主要也是很少会windows上安装这个。不过如果非常必要,也是能将就用的。可以从这里下载:https://github.com/mythz/redis-windows,直接下载zip包,解压缩后找到download文件夹中的redis-latest.zip,这个压缩包就是真正使用的。文件复制到任意文件夹下,比如c:\redis。
命令提示符cd进入redis存放路径,然后执行

redis-server.exe redis.conf

启动完成后,会显示redis图像和基本信息。不过这种启动方式必须一直开着窗口,关闭之后redis也就跟着一起关闭了。

可以将redis做成服务,不用一直开着窗口。同时服务可以实现开机自启动等。该步骤不是必须的。

注册服务 Redis-server.exe –service-install redis.windows.conf
删除服务 redis-server –service-uninstall
开启服务 redis-server –service-start
停止服务 redis-server –service-stop

Java连接Redis

绝大部分框架都已经有了连接Redis的辅助类,也都考虑了连接池效率提升,下面的代码班门弄斧,仅仅用来演示数据是如何存储读取的。

测试类,可以最后完成的时候使用。
public static void main(String[] args){
		//测试存储字符串
    	JedisUtil.set("myKey", "我是一只小小鸟", 0);
    	//测试获取字符串
    	System.out.println(JedisUtil.get("myKey"));
    	//测试删除字符串
    	JedisUtil.del("myKey");
    	System.out.println(JedisUtil.get("myKey"));
    	
    	//组装一个List
    	List<TestUser> lists = buildTestData();
    	lists.add(null); //需要加上这句,不然获取会出异常
		ListTranscoder<TestUser> listTranscoder = new ListTranscoder<>(); //list对应实体类作为类型传入
		byte[] result1 = listTranscoder.serialize(lists); //序列化,要求TestUser必须序列化
		//测试存储list对应的字节
		JedisUtil.set("mylist".getBytes(), result1, 0);	
		//测试读取集合并打印
		List<TestUser> results = listTranscoder.deserialize(JedisUtil.get("mylist".getBytes()));
		for (TestUser user : results) {
			System.out.println(user.getName() + "\t" + user.getAge());
		}
		//测试删除集合	
		JedisUtil.del("mylist".getBytes());
		System.out.println(listTranscoder.deserialize(JedisUtil.get("mylist".getBytes())).size());
    	
    }

    private static List<TestUser> buildTestData() {
    	JedisUtil tst = new JedisUtil();
		TestUser userA =  tst.new TestUser();
		userA.setName("lily"); 
        userA.setAge(25); 
        TestUser userB = tst.new TestUser();  
        userB.setName("Josh Wang"); 
		userB.setAge(28); 
        List<TestUser> list = new ArrayList<TestUser>();  
        list.add(userA);  
        list.add(userB);  
        return list;  
    }
    
    
    class TestUser implements Serializable {
		private static final long serialVersionUID = 1L;

		private String name;
			
		private int age;
			

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public int getAge() {
			return age;
		}

		public void setAge(int age) {
			this.age = age;
		}
			
	}

调用的Util辅助类

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisUtil implements Serializable {
	
	//连接池对象
	private static JedisPool jedisPool;

	static {
		String host = RedisPropertiesUtil.getProperty("redis.host"); //ip地址
		int port = Integer.valueOf(RedisPropertiesUtil.getProperty("redis.port")); //端口号,默认的是6379
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(Integer.valueOf(RedisPropertiesUtil.getProperty("redis.maxIdle"))); //最大空闲时间,0表示没有限制。可以使用256
        config.setTestOnBorrow(Boolean.valueOf(RedisPropertiesUtil.getProperty("redis.testOnBorrow")));
        config.setMaxTotal(Integer.valueOf(RedisPropertiesUtil.getProperty("redis.maxActive"))); //最大连接数,0表示没有限制。可以使用300
        config.setMaxWaitMillis(Long.valueOf(RedisPropertiesUtil.getProperty("redis.maxWait"))); //最大建立等待时间,-1表示没有限制。可以使用3000
        config.setTestOnReturn(true);
        config.setTestWhileIdle(true);
        config.setMinEvictableIdleTimeMillis(60000l);
        config.setTimeBetweenEvictionRunsMillis(3000l);
        config.setNumTestsPerEvictionRun(-1);
        jedisPool = new JedisPool(config, host, port);
	}

	/**
	 * 获取Jedis连接池
	 */
	public static JedisPool getJedisPool() {
		return jedisPool;
	}
	
	/**
	 * 安全回收资源
	 * 
	 * @param jedis
	 */
	public static void close(Jedis jedis) {
	        try {
	            jedisPool.returnResource(jedis);
	        } catch (Exception e) {
	            if (jedis.isConnected()) {
	                jedis.quit();
	                jedis.disconnect();
	            }
	        }
	    }

    /**
     * 设置字符串型数据
     * 
     * @param key 存储键
     * @param value 存储值
     * @param timeout 超时时间(单位:秒) 设置为0,则无时效性。
     * @return
     */
    public static void set(String key, String value, int timeout) {
        if (key == null || key.length() == 0) {
			throw new NullPointerException("Key不能为空!");
		}
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
            if (timeout > 0) {
				jedis.expire(key, timeout);
			}
        } catch (Exception e) {
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            close(jedis);
        }
    }
    
    /**
     * 设置序列化对象数据
     * 
     * @param key 存储键
     * @param value 存储值
     * @param timeout 超时时间(单位:秒) 设置为0,则无时效性。
     * @return
     */
    public static void set(byte[] key, byte[] value, int timeout) {
        if (key == null) {
			throw new NullPointerException("Key不能为空!");
		}
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
            if (timeout > 0) {
				jedis.expire(key, timeout);
			}
        } catch (Exception e) {
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            close(jedis);
        }
    }
    
    /**
     * 获取字符串型数据
     */
    public static String get(String key) {
        String value = null;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            close(jedis);
        }
        return value;
    }
    
    /**
     * 获取序列化对象数据
     */
    public static byte[] get(byte[] key) {
        byte[] value = null;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            close(jedis);
        }
        return value;
    }
    
    /**
     * 删除数据
     */
    public static void del(byte[] key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.del(key);
        } catch (Exception e) {
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            close(jedis);
        }
    }
    
    /**
     * 删除数据
     */
    public static void del(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.del(key);
        } catch (Exception e) {
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            close(jedis);
        }
    }

}

上面辅助类用到了几个自定义相关的类,代码如下:

import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 读取属性配置文件
 */
public class RedisPropertiesUtil {
	
	private static Log log = LogFactory.getLog(RedisPropertiesUtil.class);
	
	private static Properties defaultProperties;
	
	static {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		if (classLoader == null) {
			classLoader = RedisPropertiesUtil.class.getClassLoader();
		}
		try {
			if (log.isDebugEnabled()) {
				log.debug("开始装载属性资源参数文件...");
			}
			InputStream is = classLoader.getResourceAsStream("redis.properties");
			defaultProperties = new Properties();
			defaultProperties.load(is);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 返回缺省属性文件[application.properties]属性值
	 */
	public static String getProperty(String pKey) {
		String value = defaultProperties.getProperty(pKey, "");
		return value;
	}
}
import java.io.Closeable;
import org.apache.log4j.Logger;


public abstract class SerializeTranscoder {

	protected static Logger logger = Logger.getLogger(SerializeTranscoder.class);
	
	public abstract byte[] serialize(Object value);
	
	public abstract Object deserialize(byte[] in);
	
	public void close(Closeable closeable) {
		if (closeable != null) {
			try {
				closeable.close();
			} catch (Exception e) {
				 logger.info("Unable to close " + closeable, e); 
			}
		}
	}
}
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class ListTranscoder<M extends Serializable> extends SerializeTranscoder {

	@SuppressWarnings("unchecked")
	public List<M> deserialize(byte[] in) {
		List<M> list = new ArrayList<>();
		ByteArrayInputStream bis = null;
		ObjectInputStream is = null;
		try {
			if (in != null) {
				bis = new ByteArrayInputStream(in);
				is = new ObjectInputStream(bis);
				while (true) {
					M m = (M) is.readObject();
					if (m == null) {
						break;
					}

					list.add(m);

				}
				is.close();
				bis.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			close(is);
			close(bis);
		}

		return list;
	}

	@SuppressWarnings("unchecked")
	@Override
	public byte[] serialize(Object value) {
		if (value == null)
			throw new NullPointerException("Can't serialize null");

		List<M> values = (List<M>) value;

		byte[] results = null;
		ByteArrayOutputStream bos = null;
		ObjectOutputStream os = null;

		try {
			bos = new ByteArrayOutputStream();
			os = new ObjectOutputStream(bos);
			for (M m : values) {
				os.writeObject(m);
			}

			// os.writeObject(null);
			os.close();
			bos.close();
			results = bos.toByteArray();
		} catch (IOException e) {
			throw new IllegalArgumentException("Non-serializable object", e);
		} finally {
			close(os);
			close(bos);
		}

		return results;
	}

}
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class ObjectsTranscoder<M extends Serializable> extends SerializeTranscoder {

	
	@SuppressWarnings("unchecked")
	@Override
	public byte[] serialize(Object value) {
		if (value == null) {  
			throw new NullPointerException("Can't serialize null");  
		}  
		byte[] result = null;  
		ByteArrayOutputStream bos = null;  
		ObjectOutputStream os = null;  
		try {  
			bos = new ByteArrayOutputStream();  
			os = new ObjectOutputStream(bos);
			M m = (M) value;
			os.writeObject(m);  
			os.close();  
			bos.close();  
			result = bos.toByteArray();  
		} catch (IOException e) {  
			throw new IllegalArgumentException("Non-serializable object", e);  
		} finally {  
			close(os);  
			close(bos);  
		}  
		return result;  
	}

	@SuppressWarnings("unchecked")
	@Override
	public M deserialize(byte[] in) {
		M result = null;  
		ByteArrayInputStream bis = null;  
		ObjectInputStream is = null;  
		try {  
		  if (in != null) {  
			  bis = new ByteArrayInputStream(in);  
			  is = new ObjectInputStream(bis);  
			  result = (M) is.readObject();  
			  is.close();  
			  bis.close();  
		  }  
		} catch (IOException e) {  
		 e.printStackTrace();
		} catch (ClassNotFoundException e) {  
			e.printStackTrace();
		} finally {  
		  close(is);  
		  close(bis);  
		}  
	  return result;  
	}
}