我们搭建redis分Windows版和Linux都试了,Windows我们用的是win10,Linux用的是centos7.
Windows版:
我们先从https://github.com/ServiceStack/redis-windows下载最新的redis。
下载后解压如图,解压redis-latest.zip,
解压后在目录下新建startup.bat,在里面写redis-server.exe redis.windows.conf。
启动bat文件如下
Linux版:
获取redis:
$ wget http://download.redis.io/releases/redis-4.0.10.tar.gz
$ tar xzf redis-4.0.10.tar.gz
$ cd redis-4.0.10
安装:
$ make
# 将redis-server redis-cli执行程序安装在/usr/local/redis目录下
$ make PREFIX=/usr/local/redis install
安装过程可能出现的问题:
- CentOS5.7默认没有安装gcc,这会导致我们无法make成功。使用yum安装:
yum -y install gcc
- make时报如下错误:
zmalloc.h:50:31: error: jemalloc/jemalloc.h: No such file or directory zmalloc.h:55:2: error: #error "Newer version of jemalloc required" make[1]: *** [adlist.o] Error 1 make[1]: Leaving directory `/data0/src/redis-2.6.2/src' make: *** [all] Error 2
原因是jemalloc重载了Linux下的ANSI C的malloc和free函数。解决办法:make时添加参数。
make MALLOC=libc
- make之后,会出现一句提示
Hint: To run 'make test' is a good idea ;)
但是不测试,通常是可以使用的。若我们运行make test ,会有如下提示
[devnote@devnote src]$ make test You need tcl 8.5 or newer in order to run the Redis test make: ***[test] Error_1
解决办法是用yum安装tcl8.5(或去tcl的官方网站http://www.tcl.tk/下载8.5版本,并参考官网介绍进行安装)
yum install tcl
修改redis.conf配置文件:
## 为了redis客户端远程能够访问
1.将`bind 127.0.0.1`改为`#bind 127.0.0.1`
2.将`protected-mode yes`改为`protected-mode no`,
## 指定日志文件目录
logfile "/var/log/redis/server-out.log"
## 默认启动时为后台启动
daemonize yes
启动:
$ cp redis.conf /usr/local/redis/bin/redis.conf
# 加入环境变量
$ ln -s /usr/local/redis/bin/* /usr/sbin
$ /usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf
这样就后台启动成功,我们可以通过输入ps -ef | grep redis得到下面的样子
这样就说明可以在其他的机器上连接此台的redis
我们输入/usr/local/redis/bin/redis-cli 可以进入命令行,这里是我里面存入了数据才可以得到。你也可以自己去测试.
如果服务强制关闭导致了
Please check the Redis logs for details about the RDB error.
进入redis,写上
config set stop-writes-on-bgsave-error no
项目我们测试了spring和springboot
spring:
maven文件结构如下
pom.xml文件如下
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
application.properties文件
# Redis settings
redis.host=localhost
redis.port=6379
redis.pass=
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:application.properties" />
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxActive" value="${redis.maxActive}" />
<property name="maxWait" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="userDao" class="org.ligz.dao.Impl.UserDao" />
</beans>
User.java文件
package org.ligz.model;
import java.io.Serializable;
/**
* @author ligz
*/
public class User implements Serializable {
private static final long serialVersionUID = -6011241820070393952L;
private String id;
private String name;
private String password;
public User() {
}
public User(String id, String name, String password) {
super();
this.id = id;
this.name = name;
this.password = password;
}
/**
* 获得id
* @return the id
*/
public String getId() {
return id;
}
/**
* 设置id
* @param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* 获得name
* @return the name
*/
public String getName() {
return name;
}
/**
* 设置name
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* 获得password
* @return the password
*/
public String getPassword() {
return password;
}
/**
* 设置password
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}
AbstractBaseRedisDao.java文件
package org.ligz.dao;
import javax.annotation.Resource;
/**
* @author ligz
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
public abstract class AbstractBaseRedisDao<K, V> {
protected RedisTemplate<K, V> redisTemplate;
/**
* 设置redisTemplate
*/
@Resource
public void setRedisTemplate(RedisTemplate<K, V> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 获取 RedisSerializer
*/
protected RedisSerializer<String> getRedisSerializer() {
return redisTemplate.getStringSerializer();
}
}
IUserDao.java文件
package org.ligz.dao;
/**
* @author ligz
*/
import java.util.List;
import org.ligz.model.User;
public interface IUserDao {
/**
* 新增
* @param user
* @return
*/
boolean add(User user);
/**
* 批量新增 使用pipeline方式
* @param list
* @return
*/
boolean add(List<User> list);
/**
* 删除
* @param key
*/
void delete(String key);
/**
* 删除多个
* @param keys
*/
void delete(List<String> keys);
/**
* 修改
* @param user
* @return
*/
boolean update(User user);
/**
* 通过key获取
* @param keyId
* @return
*/
User get(String keyId);
}
UserDao.java
package org.ligz.dao.Impl;
/**
* @author ligz
*/
import java.util.ArrayList;
import java.util.List;
import org.ligz.dao.AbstractBaseRedisDao;
import org.ligz.dao.IUserDao;
import org.ligz.model.User;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.util.Assert;
public class UserDao extends AbstractBaseRedisDao<String, User> implements IUserDao {
/**
* 新增
* @param user
* @return
*/
public boolean add(final User user) {
boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection)
throws DataAccessException {
RedisSerializer<String> serializer = getRedisSerializer();
byte[] key = serializer.serialize(user.getId());
byte[] name = serializer.serialize(user.getName());
return connection.setNX(key, name);
}
});
return result;
}
/**
* 批量新增 使用pipeline方式
*@param list
*@return
*/
public boolean add(final List<User> list) {
Assert.notEmpty(list);
boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection)
throws DataAccessException {
RedisSerializer<String> serializer = getRedisSerializer();
for (User user : list) {
byte[] key = serializer.serialize(user.getId());
byte[] name = serializer.serialize(user.getName());
connection.setNX(key, name);
}
return true;
}
}, false, true);
return result;
}
/**
* 删除
* @param key
*/
public void delete(String key) {
List<String> list = new ArrayList<String>();
list.add(key);
delete(list);
}
/**
* 删除多个
* @param keys
*/
public void delete(List<String> keys) {
redisTemplate.delete(keys);
}
/**
* 修改
* @param user
* @return
*/
public boolean update(final User user) {
String key = user.getId();
if (get(key) == null) {
throw new NullPointerException("数据行不存在, key = " + key);
}
boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection)
throws DataAccessException {
RedisSerializer<String> serializer = getRedisSerializer();
byte[] key = serializer.serialize(user.getId());
byte[] name = serializer.serialize(user.getName());
connection.set(key, name);
return true;
}
});
return result;
}
/**
* 通过key获取
* @param keyId
* @return
*/
public User get(final String keyId) {
User result = redisTemplate.execute(new RedisCallback<User>() {
public User doInRedis(RedisConnection connection)
throws DataAccessException {
RedisSerializer<String> serializer = getRedisSerializer();
byte[] key = serializer.serialize(keyId);
byte[] value = connection.get(key);
if (value == null) {
return null;
}
String name = serializer.deserialize(value);
return new User(keyId, name, null);
}
});
return result;
}
}
RedisTest.java文件测试redis
package org.ligz.redis;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.ligz.dao.IUserDao;
import org.ligz.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import junit.framework.Assert;
@ContextConfiguration(locations = {"classpath*:applicationContext.xml"})
public class RedisTest extends AbstractJUnit4SpringContextTests {
@Autowired
private IUserDao userDao;
/**
* 新增
*/
@Test
public void testAddUser() {
User user = new User();
user.setId("user1");
user.setName("ligzzzzz");
boolean result = userDao.add(user);
Assert.assertTrue(result);
System.out.println("add success");
}
/**
* 批量新增 普通方式
*/
@Test
public void testAddUsers1() {
List<User> list = new ArrayList<User>();
for (int i = 10; i < 50000; i++) {
User user = new User();
user.setId("user" + i);
user.setName("ligzzzzz" + i);
list.add(user);
}
long begin = System.currentTimeMillis();
for (User user : list) {
userDao.add(user);
}
System.out.println(System.currentTimeMillis() - begin);
}
/**
* 批量新增 pipeline方式
*/
@Test
public void testAddUsers2() {
List<User> list = new ArrayList<User>();
for (int i = 10; i < 1500000; i++) {
User user = new User();
user.setId("user" + i);
user.setName("ligzzzzz" + i);
list.add(user);
}
long begin = System.currentTimeMillis();
boolean result = userDao.add(list);
System.out.println(System.currentTimeMillis() - begin);
Assert.assertTrue(result);
}
/**
* 修改
*/
@Test
public void testUpdate() {
User user = new User();
user.setId("user1");
user.setName("new_password");
boolean result = userDao.update(user);
Assert.assertTrue(result);
}
/**
* 通过key删除单个
*/
@Test
public void testDelete() {
String key = "user1";
userDao.delete(key);
}
/**
* 批量删除
*/
@Test
public void testDeletes() {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
list.add("user" + i);
}
userDao.delete(list);
}
/**
* 获取
*/
@Test
public void testGetUser() {
String id = "user1";
User user = userDao.get(id);
System.out.println(user.getId());
System.out.println(user.getName());
Assert.assertNotNull(user);
Assert.assertEquals(user.getName(), "ligzzzzz");
}
/**
* 设置userDao
* @param userDao the userDao to set
*/
public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
}
我们打开redis.cli.exe
发现可以获取到,测试成功。
springboot:
application.properties
# REDIS (RedisProperties)
# Redis settings
spring.redis.host=172.16.2.245
spring.redis.port=6379
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.timeout=0
RedisConfig.java
package com.phy.util;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author ligz
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* 生成key的策略
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
/**
* 管理缓存
*/
@SuppressWarnings("rawtypes")
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
// 多个缓存的名称,目前只定义了一个
rcm.setCacheNames(Arrays.asList("thisredis"));
//设置缓存过期时间(秒)
rcm.setDefaultExpiration(600);
return rcm;
}
/**
* RedisTemplate配置
*/
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
RedisService.java
package com.phy.service;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
/**
* @author ligz
*/
@Service
public class RedisService {
@Autowired
private RedisTemplate redisTemplate;
/**
* 写入缓存
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存设置时效时间
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 批量删除对应的value
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
* @param pattern
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
/**
* 删除对应的value
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
* @param key
* @return
*/
public Object get(final String key) {
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
/**
* 哈希 添加
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value){
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key,hashKey,value);
}
/**
* 哈希获取数据
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey){
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key,hashKey);
}
/**
* 根据key获取所有的hash值
* @param key
* @return
* @author ligz
*/
public Map<Object, Object> hmGetAll(String key) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
Map<Object, Object> map = hash.entries(key);
return map;
}
/**
* 列表添加
* @param k
* @param v
*/
public void lPush(String k,Object v){
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k,v);
}
/**
* 列表获取
* @param k
* @param l
* @param l1
* @return
*/
public List<Object> lRange(String k, long l, long l1){
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k,l,l1);
}
/**
* 集合添加
* @param key
* @param value
*/
public void add(String key,Object value){
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key,value);
}
/**
* 集合获取
* @param key
* @return
*/
public Set<Object> setMembers(String key){
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key,Object value,double scoure){
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key,value,scoure);
}
/**
* 有序集合获取
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<Object> rangeByScore(String key,double scoure,double scoure1){
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
}
我们直接在controller层调用service层的方法即可。