缓存服务—Redis
Redis 简介
Redis 是一个开源(BSD 许可)的、内存中的数据结构存储系统,它可以用作数据库、缓存和
消息中间件。
为什么要用 Redis
在高并发场景下,如果需要经常连接结果变动频繁的数据库,会导致数据库读取及存取的速
度变慢,数据库压力极大。
因此我们需要通过缓存来减少数据库的压力,使得大量的访问进来能够命中缓存,只有少量
的需要到数据库层。由于缓存基于内存,可支持的并发量远远大于基于硬盘的数据库。所以
对于高并发设计,缓存的设计是必不可少的一环。
而 Redis 作为比较热门的内存存储系统之一,由于其对数据持久化的支持,种类丰富的数据
结构,使其定位更倾向于内存数据库,适用于对读写效率要求都很高、数据处理业务复杂和
对安全性要求较高的系统。
Redis Cluster 架构
Redis 搭建方式有很多种,本章主要介绍 Redis Cluster 集群构建方式:
Redis 3.0 之后版本支持 Redis Cluster 集群,Redis Cluster 采用无中心结构,每个节点保存数据
和整个集群状态,每个节点都和其他所有节点连接。
Redis Cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节
点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会
有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。主从结构,一是为了纯粹的
冗余备份,二是为了提升读性能,比如很消耗性能的 SORT 就可以由从服务器来承担。
Redis 的主从同步是异步进行的,这意味着主从同步不会影响主逻辑,也不会降低 redis 的处
理性能。
主从架构中,可以考虑关闭主服务器的数据持久化功能,只让从服务器进行持久化,这样可
以提高主服务器的处理性能。在主从架构中,从服务器通常被设置为只读模式,这样可以避
免从服务器的数据被误修改。
Redis小测试
1.新建springboot项目,结构如下:
2 . pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>demo</name>
<description>Demo project for Spring Boot</description> <!-- Spring Boot 启动父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/>
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.3.2.RELEASE</version>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins> </build> </project> 3.application.yml 文件如下
4. 在本地 mysql 中添加数据
insert into cat(id,cat_age,cat_name) values( , , );
5. 构建并运行本 demo,然后根据 yml 文件中配置的地址,访问生成的数据:
结果验证
查看日志,查询第一次访问数据所耗时间,返回的结果为 3183ms:
再次刷新页面访问数据,第二次并没有调用方法打印数据,并且查询所用时间仅为 5ms,查询速度提高
其他具体代码如下 :
package com.example.demo.config; import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer; import java.lang.reflect.Method; @Configuration
@EnableCaching//开启注解
public class RedisConfig { @Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory){ RedisTemplate<Object, Object> template=new RedisTemplate<Object, Object>(); template.setConnectionFactory(connectionFactory);
//实现序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
//实现序列化和反序列化redis的value值,默认使用JdkSerializationRedisSerializer
//template.setValueSerializer(new RedisObjectSerializer());
//template.setValueSerializer();
return template; } @Bean
public CacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// cacheManager.setCacheNames(Arrays.asList("users", "emptyUsers"));
cacheManager.setUsePrefix(true);
// Number of seconds before expiration. Defaults to unlimited (0)
cacheManager.setDefaultExpiration(1800L);
return cacheManager;
} @Bean
public KeyGenerator accountKeyGenerator() {
return new KeyGenerator(){
@Override
public Object generate(Object target, Method method, Object... params) {
//first parameter is caching object
//second paramter is the name of the method, we like the caching key has nothing to do with method name
//third parameter is the list of parameters in the method being called
return target.getClass().toString() + "accountId:" + params[0].toString();
}
};
}
}
package com.example.demo.controller; import com.example.demo.model.Cat;
import com.example.demo.service.CatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; @RestController
public class CatController { @Autowired
private CatService catService; @RequestMapping(value = "/cat/{id}", method = RequestMethod.GET)
public Cat findOne(@PathVariable("id") Integer id) {
long beginTime=System.currentTimeMillis();
Cat cat=catService.findOneCat(id);
long time=System.currentTimeMillis()-beginTime;
System.out.println(time);
return cat;
}
@RequestMapping(value = "/cat", method = RequestMethod.POST)
public void createCat(@RequestBody Cat cat) {
catService.saveCat(cat);
} // @RequestMapping(value = "/cat/{id}", method = RequestMethod.DELETE)
// public void modifyCity(@PathVariable("id") Integer id) {
// catService.deleteCat(id);
// } }
package com.example.demo.model; import org.hibernate.annotations.GenericGenerator; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable; /**
* 创建了一个实体类。
*
* 如何持久化呢?
*
* 1、使用@Entity进行实体类的持久化操作,当JPA检测到我们的实体类当中有
*
* @Entity 注解的时候,会在数据库中生成对应的表结构信息。
*
*
* 如何指定主键以及主键的生成策略?
*
* 2、使用@Id指定主键.
*
*
*
*/
@Entity
public class Cat implements Serializable{ /**
* 使用@Id指定主键.
*
* 使用代码@GeneratedValue(strategy=GenerationType.AUTO)
* 指定主键的生成策略,mysql默认的是自增长。
*
*/ @Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;//主键. private String catName;//姓名. cat_name private int catAge;//年龄. cat_age; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getCatName() {
return catName;
} public void setCatName(String catName) {
this.catName = catName;
} public int getCatAge() {
return catAge;
} public void setCatAge(int catAge) {
this.catAge = catAge;
} }
package com.example.demo.repository; import com.example.demo.model.Cat;
import org.springframework.data.repository.CrudRepository; /**
* Repository -- 是接口 ,不是class.
*/
public interface CatRepository extends CrudRepository<Cat, Integer> { }
package com.example.demo.service.impl; import com.example.demo.model.Cat;
import com.example.demo.repository.CatRepository;
import com.example.demo.service.CatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import java.util.List; @Service
public class CatServiceImpl implements CatService { @Autowired
private CatRepository catRepository;
//与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@CachePut(value="baseCatInfo")
public void saveCat(Cat cat) {
catRepository.save(cat);
} @Override
public int updateCat(Cat cat) {
// TODO Auto-generated method stub
return 0;
} //@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作
@CacheEvict(value="cat")
public void deleteCat(int id) {
System.out.println(id); } @Override
public List<Cat> getCatAll() {
return (List<Cat>) catRepository.findAll();
} @Cacheable(value="cat", keyGenerator = "accountKeyGenerator")
@Override
public Cat findOneCat(Integer id) {
System.out.println("开始查询.....");
try {
Thread.sleep(3 * 1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查询结束......");
Cat cat=catRepository.findOne(id); return cat;
} }
package com.example.demo.service; import com.example.demo.model.Cat; import java.util.List; public interface CatService { public void saveCat(Cat cat); public int updateCat(Cat cat); public void deleteCat(int id); //查询数据.
public List<Cat> getCatAll(); public Cat findOneCat(Integer id);
}
package com.example.demo; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement; @EnableTransactionManagement
@SpringBootApplication
public class DemoApplication { public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
缓存服务—Redis的更多相关文章
- .NET WebAPI 采用 IDistributedCache 实现分布式缓存过滤器 Redis 模式
分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护. 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时. 与其 ...
- 【新手总结】在.Net项目中使用Redis作为缓存服务
最近由于项目需要,在系统缓存服务部分上了redis,终于有机会在实际开发中玩一下,之前都是自己随便看看写写,很零碎也没沉淀下来什么,这次算是一个系统学习和实践过程的总结. 和Redis有关的基础知识 ...
- Windows Azure Redis 缓存服务
8月20日,Windows Azure (中国版)开始提供Redis缓存服务,比较国际版的Microsoft Azure晚了差不多一年的时间.说实话,微软真不应该将这个重要的功能delay这么长时间, ...
- 在.Net项目中使用Redis作为缓存服务
转自:http://www.cnblogs.com/hohoa/p/5771255.html 最近由于项目需要,在系统缓存服务部分上了redis,终于有机会在实际开发中玩一下,之前都是自己随便看看写写 ...
- 如何用分布式缓存服务实现Redis内存优化
Redis是一种支持Key-Value等多种数据结构的存储系统,其数据特性是“ALL IN MEMORY”,因此优化内存十分重要.在对Redis进行内存优化时,先要掌握Redis内存存储的特性比如字符 ...
- 高级运维(六):源码安装Redis缓存服务、常用Redis数据库操作指令、配置Redis主从服务器
一.源码安装Redis缓存服务 目标: 本案例要求先快速搭建好一台Redis服务器,并测试该缓存服务器: 1> 设置变量test,值为123 2> 查看变量test的值 3> 设置计 ...
- 阿里云发布 Redis 5.0 缓存服务:全新 Stream 数据类型带来不一样缓存体验
4月24日,阿里云正式宣布推出全新 Redis 5.0 版本云数据库缓存服务,据悉该服务完全兼容 4.0 及早期版本,继承了其一贯的安全,稳定,高效等特点并带来了全新的 Stream 数据结构及多项优 ...
- 四、NOSQL之Redis持久化缓存服务基础实战第三部
1.NOSQL的理解 NOSQL是不仅仅是SQL,说的就是sql的补充,但是不能替代SQL. nosql库:memcached.memcachedb.redis 2.redis 简介 Redis是一个 ...
- 再谈缓存和Redis
自从上次分享<Redis到底该如何利用?>已经有1年多了,这1年经历了不少.从码了我们网站的第一行开始到现在,我们的缓存模块也不断在升级,这之中确实略有心得,最近也有朋友探讨缓存,觉得可以 ...
随机推荐
- MFC字体
GDI字体分3类:点阵字体(raster font).笔画字体(stroke font)和Truetype字体. 默认点阵字体有7种: System (用于SYSTEM_FONT) ...
- 周一01.4安装PyCharm步骤
安装集成开发工具 步骤一 步骤二 步骤三 步骤四
- C# -- 使用委托 delegate 执行异步操作
C# -- 使用委托 delegate 执行异步操作 委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似. 与 C 中的函数指针不同,委托是面向对象的.类型安全的和保险的. 委托的 ...
- qemu 系列
一.. qemu uboot 1. 首先安装交叉编译器,执行: sudo apt-get install gcc-arm-linux-gnueabi 2. 下载U-Boot源文件: ht ...
- springMVC框架核心方法调用源码解析
- SpringBoot前端模板
Springboot支持thymeleaf.freemarker.JSP,但是官方不建议使用JSP,因为有些功能会受限制,这里介绍thymeleaf和freemarker. 一.thymeleaf模板 ...
- Spring boot整合Mybatis
时隔两个月的再来写博客的感觉怎么样呢,只能用“棒”来形容了.闲话少说,直接入正题,之前的博客中有说过,将spring与mybatis整个后开发会更爽,基于现在springboot已经成为整个业界开发主 ...
- appium框架之bootstrap
(闲来无事,做做测试..)最近弄了弄appium,感觉挺有意思,就深入研究了下. 看小弟这篇文章之前,先了解一下appium的架构,对你理解有好处,推荐下面这篇文章:testerhome appium ...
- vue数组变异方法
Vue数组变异方法,会改变被这些方法调用的原始数组,将会触发视图更新 push() 接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度 pop() 从数组末尾移除最后一项,减少数组的 ...
- Github经理和员工开发
Git简介 Git是目前世界上最先进的分布式版本控制系统 git的两大特点: 版本控制:可以解决多人同时开发的代码问题,也可以解决找回历史代码的问题 分布式:Git是分布式版本控制系统,同一个Git仓 ...