Redis在分布式项目中的应用
利用Redis在分布式项目中实现数据缓存
介绍
Redis作为一个开源的使用 ANSIC 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库. 主要用于在大型分布式项目中对数据库查询到的结果进行缓存 . 减轻数据库压力, 提升项目响应速度 .
利用Redis 将查询到的将查询到的结果进行缓存 .每次通过访问它的key ,如果键存在,则将键所对应的的值返回 ; 如果不存在 , 则将值放入 redis的数据库中进行缓存 .
使用步骤
前提
- 安装Redis或Redis集群
- Maven环境的搭建(用于项目构建和项目管理)
步骤
1. 添加Jedis坐标
Jedis为java整合Redis后的jar ,添加该坐标后, 即可利用java代码来操作Redis数据库
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>>2.7.2</version>
</dependency>
2. 创建 cache.properties
放在src目录下, 在这个properties 配置文件中 ,用于创建查询到数据库结果后,存放value 所对应的 key .根据是否有key ,我们可以判断Redis数据库对是否对查询结果进行了缓存 .(Redis是key-value数据库 , key 代表键,value 代表值) cache.properties
ITEM_CAT=ITEM_CAT_KEY
3. 创建jedis 配置值文件
主要需要修改的有:
- 加载cache.properties 的文件位置
- 配置redis.clients.jedis.JedisCluster(ip , 端口号)
applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 加载cache.properties -->
<context:property-placeholder location="classpath:cache.properties"/>
<!-- 实例化JedisCluster -->
<bean id="cluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.179.131"></constructor-arg>
<constructor-arg name="port" value="8001"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.179.131"></constructor-arg>
<constructor-arg name="port" value="8002"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.179.131"></constructor-arg>
<constructor-arg name="port" value="8003"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.179.131"></constructor-arg>
<constructor-arg name="port" value="8004"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.179.131"></constructor-arg>
<constructor-arg name="port" value="8005"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.179.131"></constructor-arg>
<constructor-arg name="port" value="8006"></constructor-arg>
</bean>
</set>
</constructor-arg>
</bean>
</beans>
注意 : 要让spring的相关配置文件生效 ,需要在web.xml中对其所在目录进行扫描( jedis的配置文件就在src的spring目录下 ),如下
<!-- 指定spring的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
4. 修改 Dao层实现类
使用方式
- 通过@value使用el表达式注入cache.properties 配置文件中的key
- 注入jedis集群对象
- 对返回结果进行判断 ,jeids数据库中查询是否有该缓存,有则返回 ,无则添加( 对应注释 abcd )
- 根据需要 ,看是否设置失效时间
@Service
public class PortalItemCatServiceImpl implements PortalItemCatService{
@Autowired
private ItemCatService itemCatServiceProxy;
@Value("${ITEM_CAT}")
private String itemCatkey;//a.设置redis数据库缓存的键名
@Autowired
private JedisCluster jedisCluster;//b. 注入jedis集群对象
@Override
public String loadItemCatService() {
//c 到jeids数据库中查询是否有该缓存,有则返回
String jedisStr = jedisCluster.get(itemCatkey);
if (!StringUtils.isEmpty(jedisStr)) {
return jedisStr;
}
//1 远程调用服务
List<TbItemCat> list = this.itemCatServiceProxy.loadItemCatList();//获取查询到的结果,list集合
//2 创建catResult对象, 封装响应到前台数据格式
CatResult result = new CatResult();
//3 将list集合转化成符合前端规范的数据格式,递归遍历
List<?>data= getChildren(0L, list);//父id,long类型
result.setData(data);
//4 将reslut序列化为json串
String str = JsonUtils.objectToJson(result);
System.out.println("Str"+str);
//d 到jeids数据库中查询是否有该缓存,无则设置
jedisCluster.set(itemCatkey, str);
jedisCluster.expire(itemCatkey, 86400);//设置失效时间
return str;
}
}
}
运行结果 :
从结果可以看出 ,查询到的结果被保存到了第二个和第五个Reids数据库中 ,这是因为搭建环境( 3主3从,2主5从) .在将数据库保存到redis集群的时候, 他们并不会将查询到的数据缓存到集群中的所有数据库中 ,而是随机缓存到了一个主从数据库中 ,既能保证数据的不易丢失也防止了数据库的过度冗余. 另外需要注意Redis 主从数据集群中实现了读写分离 , Master 只负责写和同步数据给 Slave,Slave 负责被读的任务,通过 Slave 的扩容提高读的速度。
需要搭建这样的主从数据库请跳转至: https://blog.csdn.net/qq_43371556/article/details/97174726
补充: 缓存同步思想
介绍
当前项目对数据库数据进行了增删改操作后,dao层实现类查询到缓存中的数据和数据 库数据不一致,出现脏读。 这时候就需要完成缓存和数据库之间数据的同步.
实现思路
- 可以设置 key 的生命周期,定期的和数据库同步 .
- 当项目对数据库数据完成增删改的时候,清空 redis 中缓存的数据 ;项目重新调用远程服务获得(执行查询操作)数据,再次将查询到的结果放入缓存中
例:简单类型数据的删除 ,调用的是del()方法,详情见本人redis 技术详解.
jedisCluster.del(itemCatkey);
- Oracle中使用Entity Framework 6.x Code-First方式开发
- 边缘计算推动AI发展 未来能摆脱云计算吗?
- intellij idea 高级用法之:集成JIRA、UML类图插件、集成SSH、集成FTP、Database管理
- 微软.NET Core RC2正式发布,横跨所有平台
- 二帮主:央行数字货币的崛起,会给比特币带来什么影响
- cas原理介绍
- 结合Jexus + Kestrel 部署 asp.net core 生产环境
- C#全角和半角转换
- 浅谈Scala在大数据处理方面的优势
- 利用mybatis-generator自动生成代码
- 微信年终放大招!小程序再次升级,这个功能超想要!
- WordPress 中禁止文章自动保存和修订版本的方法
- 第一届机器人学习大会总结
- Hadoop: MapReduce2的几个基本示例
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法