redis概述
Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为
STRING(字符串)、LIST(列表)、SET(集合)、HASH(散列)和ZSET(有序集合)。
有一部分Redis命令对于这5种结构都是通用的,如DEL、TYPE、RENAME等;但也有一部分Redis命令只能对特定的一种或者两种结构使用;
一些数据库和缓存服务器的特性与功能
名称 |
类型 |
数据存储选项 |
查询类型 |
附加功能 |
Redis |
使用内存存储(in-memory)的非关系数据库 |
字符串、列表、集合、散列表、有序集合 |
每种数据类型都有自己的专属命令,另外还有批量操作(bulk operation)和不完全(partial)的事务支持 |
发布与订阅,主从复制(master/slave replication),持久化,脚本(存储过程,stored procedure) |
memcached |
使用内存存储的键值缓存 |
键值之间的映射 |
创建命令、读取命令、更新命令、删除命令以及其他几个命令 |
为提升性能而设的多线程服务器 |
MySQL |
关系数据库 |
每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图(view);支持空间(spatial)和第三方扩展 |
SELECT、 INSERT、 UPDATE、 DELETE、函数、存储过程 |
支持ACID性质(需要使用InnoDB),主从复制和主主复制 (master/master replication) |
PostgreSQL |
关系数据库 |
每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图;支持空间和第三方扩展;支持可定制类型 |
SELECT、 INSERT、 UPDATE、 DELETE、内置函数、自定义的存储过程 |
支持ACID性质,主从复制,由第三方支持的多主复制(multi-master replication) |
MongoDB |
使用硬盘存储(on-disk)的非关系文档存储 |
每个数据库可以包含多个表,每个表可以包含多个无schema(schema-less)的BSON文档 |
创建命令、读取命令、更新命令、删除命令、条件查询命令等 |
支持map-reduce操作,主从复制,分片,空间索引(spatial index) |
==表格样式不是我能决定的,凑合看吧==
Redis提供的5种结构
结构类型 |
结构存储的值 |
结构的读写能力 |
STRING |
可以是字符串、整数或者浮点数 |
对整个字符串或者字符串的其中一部分执行操作;对整数和浮点数执行自增(increment)或者自减(decrement)操作 |
LIST |
一个链表,链表上的每个节点都包含了一个字符串 |
从链表的两端推入或者弹出元素;根据偏移量对链表进行修剪(trim);读取单个或者多个元素;根据值查找或者移除元素 |
SET |
包含字符串的无序收集器(unordered collection),并且被包含的每个字符串都是独一无二、各不相同的 |
添加、获取、移除单个元素;检查一个元素是否存在于集合中;计算交集、并集、差集;从集合里面随机获取元素 |
HASH |
包含键值对的无序散列表 |
添加、获取、移除单个键值对;获取所有键值对 |
ZSET(有序集合) |
字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定 |
添加、获取、删除单个元素;根据分值范围(range)或者成员来获取元素 |
redis特性
源码简单 ,约23000行C语言源代码。
- 速度快
Redis是用C语言实现的;Redis的所有数据存储在内存中,用于快速地读写访问。
- 持久化
Redis的所有数据存储在内存中,对数据的更新将异步地保存到磁盘上;
redis的持久化有两种方式:AOF与RDB两种模式
- 支持多种数据结构
Redis支持五种数据结构:String、List、Set、Hash、Zset
- 支持多种编程语言
Java、php、Python、Ruby、Lua、Node.js等
- 功能丰富
除了支持五种数据结构之外,还支持缓存、事务、流水线、发布/订阅、消息队列等功能。
发布/订阅模型: Redis支持创建发布和订阅通道,这样Redis客户端可以订阅任意的通道来进行数据消费,并且任何已订阅该通道的客户端可以发布数据。
- 主从复制
主服务器(master)执行写入(增删改),从(slave)服务器执行查询。复制提供可伸缩性和可用性。任何一个slave宕机,其他的slave还可以提供数据访问。
- 虚拟内存
Redis使用RAM作为内存式存储。但是,在内存不足的情况下,它使用虚拟内存来保存数据。
- 高可用及分布式
Redis-Sentinel(v2.8)支持高可用
Redis-Cluster(v3.0)支持分布式
redis部分命令
flushdb:清空当前数据库;
select [index]:选择索引数据库,index为索引值名,如:select 1;
del [key]:删除一条指定key的值;
keys *:查看数据库内所有的key;
flushall:清空所有数据库;
quit:退出客户端连接。
==友情提示:部分命令慎用,线上一定不能用==
redis安装
redis下载安装
- windows版本下载:https://github.com/MicrosoftArchive/redis/releases ,目前是redis-3.2.100版本。
- 解压下载的zip压缩包:
Redis on Windows.docx:关于Redis的描述文档
redis.windeows.conf:默认的配置文件
RedisService.docx:安装手册
redis-server.exe:redis服务启动执行文件
redis-cli.exe:redis客户端启动执行文件
- 注册redis服务到本机系统中
在当前redis解压文件目录下...\Redis-x64-3.2.100\,本机系统中注册服务:
redis-server --service-install redis.windows.conf --loglevel verbose
卸载服务:
redis-server --service-uninstall
启动Redis:
redis-server.exe
指定配置文件启动,适用于多个redis数据库的时候
redis-server.exe redis.windows.conf
停止Redis:
redis-server --service-stop
安装成功:
启动redis:

- redis客户端测试
- 双击redis客户端执行文件:redis-cli.exe
- 测试:ping
redis桌面可视化工具
redis Java客户端
redis支持的语言,可在官网查看!重点看下redis的java客户端jedis:
github地址:https://github.com/xetorthio/jedis
spring boot 整合redis
spring boot整合redis有两种方式:
其一:使用外部配置,通过jedis技术框架实现;
其二:通过spring boot提供的数据访问框架Spring Data Redis实现,它是基于Jedis的。
第一种方式,可以参考SSM框架整合jedis进行操作配置;重点是第二种实现方式!
spring data redis
通过spring boot中的redis自动配置类,关于redis自动配置类RedisAutoConfiguration.java
@EnableAutoConfiguration(exclude = RedisAutoConfiguration.class)
查看其源码:

spring boot在Spring Data Redis提供了两个模板:
- RedisTemplate
- StringRedisTemplate
RedisTemplate会使用JdkSerializationRedisSerializer处理数据,这意味着key和value都会通过Java进行序列化。
StringRedisTemplate默认会使用StringRedisSerializer处理数据。
要是操作字符串的话,用StringRedisTemplate就可以满足。但要是想要存储一个对象Object,我们就需要使用RedisTemplate,并对key采用String序列化方式,对value采用json序列化方式,这时候就需要对redisTemplate自定义配置,项目源码片段:
@Bean
public RedisTemplate<String, Object> functionDomainRedisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
initDomainRedisTemplate(redisTemplate);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
}
RedisTempalte类API
方 法 |
子API接口 |
描 述 |
opsForValue() |
ValueOperations<K, V> |
操作具有简单值的条目 |
opsForList() |
ListOperations<K, V> |
操作具有list值的条目 |
opsForSet() |
SetOperations<K, V> |
操作具有set值的条目 |
opsForZSet() |
ZSetOperations<K, V> |
操作具有ZSet值(排序的set)的条目 |
opsForHash() |
HashOperations<K, HK, HV> |
操作具有hash值的条目 |
boundValueOps(K) |
BoundValueOperations<K,V> |
以绑定指定key的方式,操作具有简单值的条目 |
boundListOps(K) |
BoundListOperations<K,V> |
以绑定指定key的方式,操作具有list值的条目 |
boundSetOps(K) |
BoundSetOperations<K,V> |
以绑定指定key的方式,操作具有set值的条目 |
boundZSet(K) |
BoundZSetOperations<K,V> |
以绑定指定key的方式,操作具有ZSet值(排序的set)的条目 |
boundHashOps(K) |
BoundHashOperations<K,V> |
以绑定指定key的方式,操作具有hash值的条目 |
spring boot缓存管理
spring boot集成redis进行数据缓存功能;有两种实现:
1,通过在代码中调用redis API实现数据的CRUD;
【参考RedisUtils工具类,该工具类支持redis的其他业务场景】
2,通过在方法上添加缓存注解实现;
【重点介绍,只支持redis作为缓存管理时使用】
Spring 提供了很多缓存管理器,例如:
- SimpleCacheManager
- EhCacheCacheManager
- CaffeineCacheManager
- GuavaCacheManager
- CompositeCacheManager
- RedisCacheManager Spring Data提供的缓存管理器:RedisCacheManager
在Spring Boot中通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),默认情况下Spring Boot根据下面的顺序自动检测缓存提供者:
- Generic
- JCache (JSR-107)
- EhCache 2.x
- Hazelcast
- Infinispan
- Redis
- Guava
- Simple
因为之前已经配置了RedisTemplate了,Spring Boot就无法自动给RedisCacheManager设置RedisTemplate了,所以要自己配置CacheManager。
1, 修改RedisConfig配置类,添加@EnableCaching注解,并继承CachingConfigurerSupport,重写CacheManager 方法:
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
rcm.setDefaultExpiration(120);
return rcm;
}
Spring提供了如下注解来声明缓存规则:
- @Cacheable triggers cache population
- @cacheevict triggers cache eviction
- @cacheput updates the cache without interfering with the method execution
- @caching regroups multiple cache operations to be applied on a method
- @cacheconfig shares some common cache-related settings at class-level
注 解 |
描 述 |
@Cacheable |
表明Spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值。否则的话,这个方法就会被调用,返回值会放到缓存之中 |
@cacheput |
表明Spring应该将方法的返回值放到缓存中。在方法的调用前并不会 检查缓存,方法始终都会被调用 |
@cacheevict |
表明Spring应该在缓存中清除一个或多个条目 |
@caching |
这是一个分组的注解,能够同时应用多个其他的缓存注解 |
@cacheconfig |
可以在类层级配置一些共用的缓存配置 |
@Cacheable和@cacheput有一些共有的属性:
属 性 |
类 型 |
描 述 |
value |
String[] |
要使用的缓存名称 |
condition |
String |
SpEL表达式,如果得到的值是false的话,不会将缓存应用到方法调用上 |
key |
String |
SpEL表达式,用来计算自定义的缓存key |
unless |
String |
SpEL表达式,如果得到的值是true的话,返回值不会放到缓存之中 |
2, 通过注解@Cacheable,对数据进行缓存处理:
代码片段:
@Cacheable
@RequestMapping(value = "/getCat/{catId}", method = RequestMethod.GET)
@ResponseBody
public Cat add(@PathVariable("catId") int catId){
return this.catService.getCat(catId);
}
注意:Cat对象必须实现implements Serializable接口!
启动访问:http://127.0.0.1:8066/redis/getCat/1
java.lang.IllegalStateException: No cache could be resolved for 'Builder[public com.wyait.redis.pojo.Cat com.wyait.redis.controller.RedisCacheController.add(int)] caches=[] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@5e67a11d'. At least one cache should be provided per cache operation.
at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:244) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
这个错误,是由于@Cacheable注解没有指定缓存名称导致的。加上value值,再试:
@Cacheable(value = "catCache")
测试访问成功!多次访问,走redis缓存。
3, redis缓存key生成策略
键的生成策略有两种,一种是默认策略,一种是自定义策略。
-
----------------------------默认策略:
If no params are given, return SimpleKey.EMPTY.
If only one param is given, return that instance.
If more the one param is given, return a SimpleKey containing all parameters.
默认的key是通过KeyGenerator生成的,其默认策略如下:
1.如果方法没有参数,则使用0作为key;
2.如果只有一个参数的话则使用该参数作为key;
3.如果参数多于一个则使用所有参数的hashcode作为key;
- ----------------------------自定义策略:
自定义策略是指我们通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用参数以及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。
之前在redisTemplate里设置了template.setKeySerializer(new StringRedisSerializer()),需要key是string类型。也可以使用SpEL表达式生成Key,
(SpEL表达式:http://itmyhome.com/spring/expressions.html)
返回结果需要是string类型(比如#root.methodName就是,#root.method不是String),通用办法是重写keyGenerator定制Key默认生成策略(按照缓存名称+id方式生成key,同时确保更新操作的时候,操作的是同一条数据),也可以在使用缓存注解时指定key:
@Bean public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override public Object generate(Object target, Method method,
Object... params) {
StringBuilder sb = new StringBuilder();
String[] value = new String[1];
Cacheable cacheable = method.getAnnotation(Cacheable.class);
if (cacheable != null) {
value = cacheable.value();
}
CachePut cachePut = method.getAnnotation(CachePut.class);
if (cachePut != null) {
value = cachePut.value();
}
CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);
if (cacheEvict != null) {
value = cacheEvict.value();
}
sb.append(value[0]);
for (Object obj : params) {
sb.append(":" + obj.toString());
}
return sb.toString();
}
};
}
注意:
1,在使用缓存注解时,也可以指定统一规则的key
(比如:@Cacheable(value = "catCache", key = "#root.caches[0].name + ':' + #id"));
就可以不走KeyGenerator默认规则;同样可以实现,更新和查询都是同一个key的数据;
2,使用注解进行数据缓存,指定数据过期时间需要百度普及下!
4, 更新缓存数据
更新与删除Redis缓存需要用到@cacheput和@cacheevict。必须保证keyGenerator生成同一个key,否则更新的不是同一条的数据;
@CachePut(value = "catCache", key = "#root.caches[0].name + ':' + #id")
@RequestMapping(value = "/updateCat", method = RequestMethod.POST)
@ResponseBody
public Cat update(@RequestParam int id){
System.out.println("==========请求参数:"+id);
return this.catService.updateCat(id);
}
本文转自 wyait 51CTO博客,原文链接:http://blog.51cto.com/wyait/2048478,如需转载请自行联系原作者