缓存服务—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年经历了不少.从码了我们网站的第一行开始到现在,我们的缓存模块也不断在升级,这之中确实略有心得,最近也有朋友探讨缓存,觉得可以 ...
随机推荐
- 关于tomcat 配置时一闪而过的问题
TOMCAT JAVA_HOME or JRE_HOME environment variable is not defined correctly 按照教程已经安装了JDK并设置好了JAVA_HOM ...
- js获取时间相关函数
js获取时间函数 var myDate = new Date; var year = myDate.getFullYear();//获取当前年 var yue = myDate.getMonth()+ ...
- 【Python 08】汇率兑换2.0-1(字符串索引)
1.案例描述 设计一个汇率换算程序,其功能是将人民币转换为美元,或者美元转换为人民币. 增加功能:根据输入判断是人民币还是美元,进行相应的转换计算. 2.案例分析 3.字符串 两个双引号或单引号括起 ...
- Spark的性能调优杂谈
下面这些关于Spark的性能调优项,有的是来自官方的,有的是来自别的的工程师,有的则是我自己总结的. 基本概念和原则 <1> 每一台host上面可以并行N个worker,每一个worke ...
- yum源 Python3 Django mysql安装
yum 源安装 yum源位置: yum源仓库的地址 在/etc/yum.repos.d/,并且只能读出第一层的repo文件 yum仓库的文件都是以.repo结尾的 linux软件包管理 yum工具如同 ...
- 如何在本地搭建DVWA环境
如何在本地搭建DVWA环境 1.工具下载: (1)phpStudy: http://phpstudy.php.cn/download.html (2)DVWA:http://www.dvwa.c ...
- eclipse 创建springboot项目
eclipse创建springboot项目的三种方法: 引自:https://blog.csdn.net/mousede/article/details/81285693
- 再看ExpressionTree,Emit,反射创建对象性能对比
[前言] 前几日心血来潮想研究着做一个Spring框架,自然地就涉及到了Ioc容器对象创建的问题,研究怎么高性能地创建一个对象.第一联想到了Emit,兴致冲冲写了个Emit创建对象的工厂.在做性能测试 ...
- Winform数据库连接app.config文件配置
1.添加配置文件 新建一个winform应用程序,类似webfrom下有个web.config,winform下也有个App.config;不过 App.config不是自动生成的需要手动添加,鼠标右 ...
- ExcelDna项目完整工程演示及讲解
原始链接:http://www.cnblogs.com/Charltsing/p/ExcelDnaDemo.html ExcelDna工程演示讲课内容 1.ExcelDna是啥? 2.ExcelDna ...