Redis缓存与 Java

Redis 和  MongoDB 都是较成熟的NoSQL数据库,但是在高并发的项目中常见做缓存却是Redis 而不是MongoDB 那在这里就要谈一下他们各自的使用场景了

MongoDB 有点类似于Mysql 支持字段索引(MongoDB2.6以后支持了全文索引) 以及游标操作,但MongoDB的数据存储并不是全部在内存;

而Redis 用的C来实现的,支持多种数据结构存储,Redis(3.0之后支持集群)的存储特别的快,官方数据显示在Linux系统读写速度分别可达10万;并且在数据存储中数据全部在内存,并且Redis有自己的策略来保证数据的一致性;

在网上也有很多人说MongoDB是关系型数据库的一种替代;然而却没有人说Redis是关系型数据库的一种替代;也根据他们各自的特点得出

MongoDB 多用于数据存储;Redis 则多用于高并发的缓存

言归正传下边就贴上Redis做缓存的Java代码

1:首先是JAR包 -- 这里用的是Maven做的JAR包管理

在jar包管理中添加了protoStuff 序列化的包,作用就是在反序列化的时候比JDK自带的要更有效率

<!-- redis -->
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.9.0</version>
</dependency>
<!-- protoStuff 序列化 -->
<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>
2:Java 代码 (Seckill 类是一个实体对象)

首先是从Redis中获取数据 这里才获取的时候传入的数据的格式一定要注意一下 |k:v| 并且要转换为字节数组

获取到的值也是字节数组,所以需要反序列化一下

最后返回对象

如果返回的对象为空,那么就需要在service 层进行逻辑控制(存入Redis 缓存)

首先是将Seckill 对象序列化,并设置KEY值

然后设置超时自动维护时间

最后存入Redid中 备以后使用

public class RedisDaoCache {
	
	//有点类似连接池的Pool
	private final JedisPool jedisPool;
	
	private RuntimeSchema<Seckill> runtimeSchema = RuntimeSchema.createFrom(Seckill.class);
	
	public RedisDaoCache(String ip, int port) {
		jedisPool = new JedisPool(ip, port);
	}
	
	//从缓存获取
	public Seckill getSeckill(long seckillid) {
		//Reais缓存 操作逻辑
		try {
			//获取链接
			Jedis jedis = jedisPool.getResource();
			try {
				String key = "seckill:" + seckillid;
				
				//从redis中拿到的是二进制数组  需要反序列化成Seckill
				byte[] bs = jedis.get(key.getBytes());
				if (bs != null) {
					//创建空对象
					Seckill seckill = runtimeSchema.newMessage();
					//传到空对象 被反序列化
					ProtostuffIOUtil.mergeFrom(bs, seckill, runtimeSchema);
					return seckill;
				}
			} finally {
				jedis.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	//存入缓存
	public String putSeckill(Seckill seckill) {
		try {
			Jedis jedis = jedisPool.getResource();
			try {
				//设置key
				String key = "seckill:" + seckill.getSeckillid();
				//序列化
				byte[] bs = ProtostuffIOUtil.toByteArray(seckill, runtimeSchema, 
						LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
				//存储
				int timeOut = 60 * 60; //一个小时 超时维护设置时间
				String succuss = jedis.setex(key.getBytes(), timeOut, bs); //成功返回OK
				return succuss;
			} finally {
				jedis.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
这里还有一点需要提一下;(假如在进行商品的秒杀)在减完关系型数据库的库存之后还要更改Redis的数据;又因为Redis 的数据是定期的维护;所以建议使用Java常量也来记录库存量;并在减少库存的时候与Readis库存进行比较;这样可以降低数据错误的出现;

期待下一篇的Redis 与 Java

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值