普通的基于mss框架的系统在并发量不是很高的状况下,对redis的需求不是很高。redis在系统中的角色至关于一个对象缓存器,在高并发的系统中(好比秒杀系统),在某一刻对数据库中的一条数据多是成千上万的用户同时去访问,系统的用户体验度直接受到数据库的性能的影响。为了保证数据的完整性,用户只能串行访问数据库中的某一条记录。redis则是把记录对应的对象序列化存储在自身的容器中,减小数据库的压力。废话很少说,接下来简单介绍redis的使用。html
http://www.newasp.net/soft/67186.html#downloadedredis
该地址有redis的介绍,安装以及启动。数据库
<dependency>数组
<groupId>redis.client</groupId>缓存
<artifactId>jedis</artifactId>服务器
<version>2.7.3</version>并发
</dependency>框架
Jedis jedis = jedisPool.getResource();asp.net
返回一个操做redis对象池的对象,该对象的存储方式相似于map同样也是采用键值对来存储对象的。jedisPool的初始化采用构造函数指明redis服务器所在的ip地址跟监听的接口,若是实验的redis服务器在本机则ip地址填写localhost便可。maven
如以上所说,redis服务器以键值对来存储对象,可是值得存储方式是将对象序列化再进行存储。jdk为用户提供了一套对象序列化API,此时你们想到的应该是让被序列化类去实现Serializable接口。这种方法是可行的,可是缺点在与sun提供的这套API是比较低效率的,并且压缩以后的对象仍是比较占空间的。此时咱们能够采用Protostuff对象提供的序列化API,测试证实了这套API的序列化效率更高切压缩空间更小。
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
RuntimeSchema<T> schema = RuntimeSchema.createFrom(T.class);
首先是告知protostuffIOUtil即将要序列化的对象的序列化规则。
byte[] bytes = ProtostuffIOUtil.toByteArray(Object, schema,LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
将Object对象进行序列化,schema则是序列化规则,参数三是序列过过程当中使用到的缓冲区。
如上面提到的,schema表明序列化规则,因此经过Object object = schema.newMessage();可让容器按规则生成一个空对象,在根据冲redis中拿到的序列值进行反化
ProtostuffIOUtil.mergeFrom(bytes,object,schema);
该方法是根据参数三的对象序列化规则,对参数一的序列值进行操做,而后将对象封装在空对象object中。
讲了这么对先在该说说redis的存取方法了,如同上面我所说的同样,跟map集合很类似的是redis的取值也是使用get(“key”)方法。不过传入的参数必须是字节数组,并且方法的返回值也是一个字节数组,因此只要将返回的字节数组使用Protostuff的反序列化便可获得所要的对象。
byte[] bytes = jedis.get(key.getBytes());
不一样的是redis的存储并非使用put()方法,而是setex(key.getBytes(), timeout, bytes);方法。方法中的参数一是键值对中的键,参数三是序列化后的对象字节数组,参数二是指明该对象在redis服务器中缓存多长时间,它的单位是秒。
int timeout = 60 * 60;
String result = jedis.setex(key.getBytes(), timeout, bytes);
package org.seckill.dao.cache;import com.dyuproject.protostuff.LinkedBuffer;import com.dyuproject.protostuff.ProtostuffIOUtil;import com.dyuproject.protostuff.runtime.RuntimeSchema;import org.seckill.entity.Seckill;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;/** * Created by Administrator on 2016/8/10 0010. */public class RedisDao{ private final Logger logger = LoggerFactory.getLogger(this.getClass()); private JedisPool jedisPool; //序列化工具类,泛型指明该类序列化的规则 private RuntimeSchema<Seckill> schema = RuntimeSchema.createFrom(Seckill.class); public RedisDao(String ip,int port){ jedisPool = new JedisPool(ip,port); } public Seckill getSeckill(long seckillId){ //redis操做逻辑 try { Jedis jedis = jedisPool.getResource(); try { String key = "seckill:" + seckillId; //并无实现内部序列化操做 //get->byte[]->反序列化->Object(Seckill) //采用自定义序列化 byte[] bytes = jedis.get(key.getBytes()); //缓存从新取到 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; String result = jedis.setex(key.getBytes(), timeout, bytes); return result; }finally{ jedis.close(); } }catch (Exception e){ logger.error(e.getMessage(),e); } return null; }}若有什么不足或者错误的地方但愿你们留言指出,转载的话请标明出处;