【Redis】redis实战:在业务中添加缓存机制

电商系统Redis缓存实践

     需求:


       商城首页广告位的广告,更新不算频繁,但是用户经常从首页访问进来,查询操作比较频繁。如果将广告位信息加入到缓存中使用redis进行存储,就可以提高性能,增加用户的体验度。



   使用步骤:

  • 1.引用jedisjar
  • 2.编写工具类JedisClient和两个具体的实现单机版和集群版
  • 3.spring整合redis
  • 4.向业务中加入缓存
  • 5.缓存同步


   代码实现:


1.引入jar包,版本在聚合工程中统一管理了

<!-- Redis客户端 -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>

2.接口声明,两个实现类

接口:

package cn.e3mall.common.jedis;

import java.util.List;

public interface JedisClient {

	String set(String key, String value);
	String get(String key);
	Boolean exists(String key);
	Long expire(String key, int seconds);
	Long ttl(String key);
	Long incr(String key);
	Long hset(String key, String field, String value);
	String hget(String key, String field);
	Long hdel(String key, String... field);
	Boolean hexists(String key, String field);
	List<String> hvals(String key);
	Long del(String key);
}


单机版:

package cn.e3mall.common.jedis;

import java.util.List;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class JedisClientPool implements JedisClient {
	
	private JedisPool jedisPool;

	public JedisPool getJedisPool() {
		return jedisPool;
	}

	public void setJedisPool(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}

	@Override
	public String set(String key, String value) {
		Jedis jedis = jedisPool.getResource();
		String result = jedis.set(key, value);
		jedis.close();
		return result;
	}

	@Override
	public String get(String key) {
		Jedis jedis = jedisPool.getResource();
		String result = jedis.get(key);
		jedis.close();
		return result;
	}

	@Override
	public Boolean exists(String key) {
		Jedis jedis = jedisPool.getResource();
		Boolean result = jedis.exists(key);
		jedis.close();
		return result;
	}

	@Override
	public Long expire(String key, int seconds) {
		Jedis jedis = jedisPool.getResource();
		Long result = jedis.expire(key, seconds);
		jedis.close();
		return result;
	}

	@Override
	public Long ttl(String key) {
		Jedis jedis = jedisPool.getResource();
		Long result = jedis.ttl(key);
		jedis.close();
		return result;
	}

	@Override
	public Long incr(String key) {
		Jedis jedis = jedisPool.getResource();
		Long result = jedis.incr(key);
		jedis.close();
		return result;
	}

	@Override
	public Long hset(String key, String field, String value) {
		Jedis jedis = jedisPool.getResource();
		Long result = jedis.hset(key, field, value);
		jedis.close();
		return result;
	}

	@Override
	public String hget(String key, String field) {
		Jedis jedis = jedisPool.getResource();
		String result = jedis.hget(key, field);
		jedis.close();
		return result;
	}

	@Override
	public Long hdel(String key, String... field) {
		Jedis jedis = jedisPool.getResource();
		Long result = jedis.hdel(key, field);
		jedis.close();
		return result;
	}

	@Override
	public Boolean hexists(String key, String field) {
		Jedis jedis = jedisPool.getResource();
		Boolean result = jedis.hexists(key, field);
		jedis.close();
		return result;
	}

	@Override
	public List<String> hvals(String key) {
		Jedis jedis = jedisPool.getResource();
		List<String> result = jedis.hvals(key);
		jedis.close();
		return result;
	}

	@Override
	public Long del(String key) {
		Jedis jedis = jedisPool.getResource();
		Long result = jedis.del(key);
		jedis.close();
		return result;
	}

}

集群版:

package cn.e3mall.common.jedis;

import java.util.List;

import redis.clients.jedis.JedisCluster;

public class JedisClientCluster implements JedisClient {
	
	private JedisCluster jedisCluster;
	

	public JedisCluster getJedisCluster() {
		return jedisCluster;
	}

	public void setJedisCluster(JedisCluster jedisCluster) {
		this.jedisCluster = jedisCluster;
	}

	@Override
	public String set(String key, String value) {
		return jedisCluster.set(key, value);
	}

	@Override
	public String get(String key) {
		return jedisCluster.get(key);
	}

	@Override
	public Boolean exists(String key) {
		return jedisCluster.exists(key);
	}

	@Override
	public Long expire(String key, int seconds) {
		return jedisCluster.expire(key, seconds);
	}

	@Override
	public Long ttl(String key) {
		return jedisCluster.ttl(key);
	}

	@Override
	public Long incr(String key) {
		return jedisCluster.incr(key);
	}

	@Override
	public Long hset(String key, String field, String value) {
		return jedisCluster.hset(key, field, value);
	}

	@Override
	public String hget(String key, String field) {
		return jedisCluster.hget(key, field);
	}

	@Override
	public Long hdel(String key, String... field) {
		return jedisCluster.hdel(key, field);
	}

	@Override
	public Boolean hexists(String key, String field) {
		return jedisCluster.hexists(key, field);
	}

	@Override
	public List<String> hvals(String key) {
		return jedisCluster.hvals(key);
	}

	@Override
	public Long del(String key) {
		return jedisCluster.del(key);
	}

}

3.spring的xml配置文件中装配jedis对象

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">

<!-- 	连接redis单机版 -->
	<bean id="jedisClientPool" class="cn.e3mall.common.jedis.JedisClientPool">
		<property name="jedisPool" ref="jedisPool"></property>
	</bean>
	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
		<constructor-arg name="host" value="192.168.139.128"/>
		<constructor-arg name="port" value="6379"/>
	</bean>
	<!-- 连接redis集群 -->
<!-- 	<bean id="jedisClientCluster" class="cn.e3mall.common.jedis.JedisClientCluster"> -->
<!-- 		<property name="jedisCluster" ref="jedisCluster"/> -->
<!-- 	</bean> -->
<!-- 	<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster"> -->
<!-- 		<constructor-arg name="nodes"> -->
<!-- 			<set> -->
<!-- 				<bean class="redis.clients.jedis.HostAndPort"> -->
<!-- 					<constructor-arg name="host" value="192.168.139.128"></constructor-arg> -->
<!-- 					<constructor-arg name="port" value="7001"></constructor-arg> -->
<!-- 				</bean>  -->
<!-- 				<bean class="redis.clients.jedis.HostAndPort"> -->
<!-- 					<constructor-arg name="host" value="192.168.139.128"></constructor-arg> -->
<!-- 					<constructor-arg name="port" value="7002"></constructor-arg> -->
<!-- 				</bean>  -->
<!-- 				<bean class="redis.clients.jedis.HostAndPort"> -->
<!-- 					<constructor-arg name="host" value="192.168.139.128"></constructor-arg> -->
<!-- 					<constructor-arg name="port" value="7003"></constructor-arg> -->
<!-- 				</bean>  -->
<!-- 			</set> -->
<!-- 		</constructor-arg> -->
<!-- 	</bean>  -->
</beans>



4.向业务中加入缓存

具体代码的思路:
1、查询数据库之前先查询缓存。
2、查询到结果,直接响应结果。
3、查询不到,缓存中没有需要查询数据库。
4、把查询结果添加到缓存中。
5、返回结果。

	@Override
	public List<TbContent> getContentListByCid(long cid) {
		//查询缓存
		String jsonString=jedisClient.hget(CONTENT_LIST, cid+"");
		try {
			if (StringUtils.isNotBlank(jsonString)) {
				//如果缓存中有直接响应结果
				List<TbContent> list=JsonUtils.jsonToList(jsonString, TbContent.class);
				return list;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//如果没有查询数据库
		TbContentExample example=new TbContentExample();
		Criteria criteria=example.createCriteria();
		criteria.andCategoryIdEqualTo(cid);
		List<TbContent> list=contentMapper.selectByExampleWithBLOBs(example);
		try {
			//将数据添加到redis中
			jedisClient.hset(CONTENT_LIST, cid+"", JsonUtils.objectToJson(list));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}

5.缓存同步,在发生修改和删除的时候,将缓存内容删除。

	@Value("${CONTENT_LIST}")
	private String CONTENT_LIST;
	@Override
	public E3Result addContent(TbContent content) {
		//将内容数据插入到内容表
		content.setCreated(new Date());
		content.setUpdated(new Date());
		//插入到数据库
		contentMapper.insert(content);
		//删除缓存中的数据
		jedisClient.hdel(CONTENT_LIST, content.getCategoryId().toString());
		return E3Result.ok();
	}


  总结:

        相对于Memcached来说,redis的数据类型更多。同时,redis支持持久化,可以将数据保存到硬盘中。memcached只能保存到内存中,如果出现宕机的意外,数据就丢掉了。在电商项目中,一些商品信息用户信息适合放到缓存中,但是订单信息这样需要及时反馈,及时更新的。就不适合了。



评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值