1、linux 下 Redis安装
1)在redis官网下载tar.gz压缩包,写这篇文章的时候最新版本为redis-3.2.9。
2)在Terminal找到对应文件,使用解压命令
tar -xzvf redis-3.2.9.tar.gz
3) cd进入解压后的redis文件夹,使用“make”命令安装。在安装之前,保证linux已经配置好GCC环境。
4) 安装完成后,找到目录中的可执行文件。启动redis服务。可以将自己的配置信息写到redis.conf。例如redis的持久化RDB、AOF的配置等。
redis-server redis.conf
2、Java 项目引入 Jedis 客户端
1)现在一般都用maven进行项目的管理。首先在pom.xml文件中,添加Jedis客户端的依赖。
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
<version>2.7.3version>
dependency>
因为redis是使用“key-value”方式将数据存储的,而且value通常是字符串对象,而不是自定义对象。为了存储我们声明的对象,必须将其序列化为二进制数组字符串,然后再存储到redis服务器中。使用性能最好的ProtoStuff 将对象序列化。
<dependency>
<groupId>com.dyuproject.protostuffgroupId>
<artifactId>protostuff-coreartifactId>
<version>1.0.8version>
dependency>
<dependency>
<groupId>com.dyuproject.protostuffgroupId>
<artifactId>protostuff-runtimeartifactId>
<version>1.0.8version>
dependency>
2)Redis操作也是DAO层的操作,我们需要写一个RedisDao。采用jedis连接池的方式来操作redis。
private final JedisPool jedisPool;
//声明一个构造函数,用于spring构造函数注入
public RedisDao(String ip, int port) {
jedisPool = new JedisPool(ip, port);
}
因为我将DAO组件都托管到了spring容器中,所以要spring配置文件要写上对应的RedisDaoBean,而且采用的是构造函数注入方式。
<bean id="redisDao" class="org.seckill.dao.cache.RedisDao">
<constructor-arg index="0" value="localhost"/>
<constructor-arg index="1" value="6379"/>
bean>
之后就可以进行读写操作。
3、Java使用Redis存储、读取对象实例
private RuntimeSchema schema = RuntimeSchema.createFrom(Seckill.class);
public Seckill getSeckill(long seckillId) {
// redis操作逻辑
try {
Jedis jedis = jedisPool.getResource();
try {
String key = "seckill:" + seckillId;
// 并没有实现内部序列化操作
// get-> byte[] -> 反序列化 ->Object(Seckill)
// 采用自定义序列化
// protostuff : 要求是pojo对象.
byte[] bytes = jedis.get(key.getBytes());
// 缓存中获取到bytes
if (bytes != null) {
// 空对象
Seckill seckill = schema.newMessage();
ProtostuffIOUtil.mergeFrom(bytes, seckill, schema);
// seckill 被反序列化
return seckill;
}
} finally {
jedis.close();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
public String putSeckill(Seckill seckill) {
// set Object(Seckill) -> 序列化 -> byte[]
try {
Jedis jedis = jedisPool.getResource();
try {
String key = "seckill:" + seckill.getSeckillId();
byte[] bytes = ProtostuffIOUtil.toByteArray(seckill, schema,
LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
// 超时缓存
int timeout = 60 * 60;// 1小时
String result = jedis.setex(key.getBytes(), timeout, bytes);
return result;
} finally {
jedis.close();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
4、Juni4测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:spring/spring-dao.xml" })
public class RedisDaoTest {
private long id = 1001;
@Autowired
private RedisDao redisDao;
@Autowired
private SeckillDao seckillDao;
@Test
public void testSeckill() throws Exception {
// get & put
Seckill seckill = redisDao.getSeckill(id);
if (seckill == null) {
seckill = seckillDao.queryById(id);
if (seckill != null) {
String result = redisDao.putSeckill(seckill);
System.out.println("RedisDao的返回结果:" + result);
seckill = redisDao.getSeckill(id);
System.out.println("从Redis中取出seckill:" + seckill);
}
}
}
}
5、其他
在跟着mooc教程做的练习项目中,第一次接触到redis作为缓存使用。项目的完整源码地址 https://github.com/kaka0509/seckill 。
以前实习听研究所的工程师提过,在真实项目中,通常会做成缓存服务器集群来应对高并发。不直接去和数据库进行数据交换。借助消息队列暂存对数据的一些操作,最后再从队列中逐渐推到MYSQL数据库。很可惜没有遇上实践的机会,只能以后再深入学习了。