Redis 简介
Redis 是一个开源的使用 ANSI C 语言编写, 遵守 BSD 协议, 支持网络, 可基于内存亦可持久化的日志型, Key-Value 数据库, 并提供多种语言的 API 的非关系型数据库 (NoSQL).
Redis 的特性
Redis 的所有操作都是原子性的, 意思就是要么成功执行要么失败完全不执行. 单个操作是原子性的. 多个操作也支持事务, 即原子性, 通过 MULTI 和 EXEC 指令包起来.
性能极高 - Redis 能读的速度是 110000 次 / s, 写的速度是 81000 次 / s . 丰富的数据类型 - Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作.
原子 - Redis 的所有操作都是原子性的, 意思就是要么成功执行要么失败完全不执行. 单个操作是原子性的. 多个操作也支持事务, 即原子性, 通过 MULTI 和 EXEC 指令包起来.
丰富的特性 - Redis 还支持 publish/subscribe, 通知, key 过期等等特性.
Redis 的应用
会话缓存
数据缓存
排行榜 / 计数器
消息队列
Redis 的数据类型
String: 字符串
Hash: 散列
List: 列表
Set: 集合
Sorted Set: 有序集合
Redis 的部署
PS: 我这里是基于 Mac 环境, Windows 环境下的同学可以安装 Linux 虚拟机同步进行操作.
官网下载 https://redis.io/download Stable(稳定) 版本
找到下载的文件, 解压并编译
- tar -zxvf Redis-5.0.4.tar.gz
- mv Redis-5.0.4 /usr/local/
- cd /usr/local/Redis-5.0.4/
- make test
执行到这里, 最好先执行一遍 make test, 确保编译可以通过, 需要大概三分钟.
到这个就说明测试通过了. 我们接着往下执行
- make
- cd src/
- make install
执行到这里安装就算是告一段落了, 接下来我们进行 Redis 的一些配置:
VIM ../Redis.conf
找到 136 行左右的 daemonize 将其属性改为 yes, 可以让 Redis 在后台运行, 然后找到 500 行左右的 requirepass, 后面输入我们需要设置的密码, 这样就可以通过密码来访问 Redis 了.
然后我们通过指定配置文件的方式来启动 Redis
./Redis-server ../Redis.conf
执行完事儿之后, 查看是否执行成功:
ps -ef | grep Redis
可以看到, 我们的 Redis 已经启动成功了, 然后通过 rdm 来访问一下:
大功告成, 现在万事俱备, 只欠东风. 我们下面来看一下在 Spring Boot 中怎么使用 Redis 吧.
在 Spring Boot 中的使用
Spring Boot 给我们提供了现成的 spring-boot-starter-data-Redis, 我们只需要在 pom 文件中将之导入即可.
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-Redis</artifactId>
- </dependency>
- <!-- 创建连接池 -->
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-pool2</artifactId>
- </dependency>
然后, 我们需要在配置文件中配置一些有关 Redis 的信息:
- spring:
- Redis:
- host: 127.0.0.1 # IP
- port: 6379 # 端口号
- password: 123456 # 密码
- lettuce:
- pool:
- max-active: 8 # 连接池最大连接数
- max-wait: -1ms # 连接池最大阻塞等待时间 (使用负值表示没有限制)
- min-idle: 0 # 连接池中的最小空闲连接
- max-idle: 8 # 连接池中的最大空闲连接
接下来, 我们需要对我们所需要的 Redis 的操作给封装到一个接口中, 方便我们去调用, 这里我基于接口, 抽象类, 实现类的结构实现了一套 Redis 的方法, 需要的同学可以去 GitHub 上下载 (子项目名称: viboot-rds),GitHub 的地址在文末. 这里仅仅贴出接口的部分方法.
- package com.itframe.dao;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- /**
- *
- */
- public interface RedisDao {
- /**
- * 判断缓存中是否有对应的 value
- *
- * @param key
- * @return boolean
- */
- public boolean existsKey(Object key);
- /**
- * 根据 key 获取 key 列表 (key 值可为模糊匹配 ---taskInfo:taskDetail:* <---> * 代表任意字符)
- *
- * @param pattern
- * @return Set<Object>
- */
- public Set <Object> keys(Object pattern);
- /**
- * 根据 key 删除对应的 value
- *
- * @param key
- */
- public boolean delete(Object key);
- /**
- * 根据 key 获取个数
- *
- * @param key
- */
- public int count(Object key);
- /**
- * 批量删除对应的 value
- *
- * @param keys
- */
- public void delete(String[] keys);
- /**
- * 批量删除 key(key 值可为模糊匹配 ---taskInfo:taskDetail:* <---> * 代表任意字符)
- *
- * @param pattern
- */
- public long deletePattern(Object pattern);
- /**
- * 批量删除对应的 value
- *
- * @param keys
- */
- public long delete(Set <Object> keys);
- /**
- * 写入缓存 (操作字符串)
- *
- * @param key
- * @param value
- * @return boolean
- */
- public boolean vSet(Object key, Object value);
- /**
- * 写入缓存设置时效时间 (操作字符串)
- *
- * @param key
- * @param value
- * @return boolean
- */
- public boolean vSet(Object key, Object value, Long expireTime);
- /**
- * 更新写入缓存设置时效时间 (操作字符串)
- *
- * @param key
- * @return boolean
- */
- public boolean vSetUpdate(Object key, Long expireTime);
- /**
- * 读取缓存 (操作字符串)
- *
- * @param key
- * @return Object
- */
- public Object vGet(Object key);
- /**
- * 哈希 添加 (操作 hash)
- *
- * @param key
- * @param hashKey
- * @param value
- */
- public void hmSet(Object key, Object hashKey, Object value);
- /**
- * 哈希 添加 (操作 hash)
- *
- * @param key
- * @param map
- */
- public void hmSetAll(Object key, Map <Object, Object> map);
- /**
- * 哈希获取数据 (操作 hash)
- *
- * @param key
- * @return Map<Object, Object>
- */
- public Map <Object,
- Object> hmGet(Object key);
- /**
- * 哈希获取数据 (操作 hash)
- *
- * @param key
- * @param hashKey
- * @return Object
- */
- public Object hmGet(Object key, Object hashKey);
- /**
- * 哈希删除数据 (操作 hash)
- *
- * @param key
- * @param hashKey
- * @return Object
- */
- public Object hmDel(Object key, Object hashKey);
- }
在抽象类中我们进行了 RedisTemplate 的初始化以及序列化:
- public abstract class AbstractBaseRedisDao<K, V> {
- @Resource(name = "redisTemplate")
- protected RedisTemplate<K, V> redisTemplate;
- /**
- * 设置 redisTemplate
- *
- * @param redisTemplate
- */
- public void setRedisTemplate(RedisTemplate<K, V> redisTemplate) {
- this.redisTemplate = redisTemplate;
- }
- /**
- * 获取 RedisSerializer
- */
- protected RedisSerializer<String> getRedisSerializer() {
- return redisTemplate.getStringSerializer();
- }
- }
在实现类中我们通过操作 RestTemplate 来实现接口中的方法~
Redis 缓存实战
首先, 我们如果想在 Spring Boot 项目中启用缓存, 需要在启动类上加上注解 @EnableCaching, 这个是重点, 要记住了!
首先介绍一下注解三剑客:@Cacheable,@CachePut,@CacheEvict.
@Cacheable: 主要针对方法配置, 能够根据方法的请求参数对其进行缓存, 常用于查询操作
@CachePut: 主要针对方法配置, 能够根据方法的请求参数对其进行缓存, 常用于修改操作
@CacheEvict: 清空缓存, 主要用于删除操作.
下面我们来看一下用法:
- /**
- * value: 缓存的名称
- * key: 缓存的键
- * return 缓存的值
- */
- @Override
- @Cacheable(value = "users", key = "#id")
- public UserDO findOne(Long id) {
- // 如果我们第二次访问的时候, 控制台没有打印出这句话说明是从缓存中取出
- log.info("From MYSQL");
- return userMapper.get(id);
- }
- @Override
- @CachePut(value = "users", key = "#userDO.id")
- public UserDO update(UserDO userDO) {
- // 执行之后, 再次访问 findOne 的时候, 应当没有打印出 "From MySQL", 且返回的是我们修改后的值, 说明这一步缓存成功
- if (userMapper.update(userDO)> 0) {
- return userMapper.get(userDO.getId());
- }
- return null;
- }
- @Override
- @CacheEvict(value = "users", key = "#id")
- public int delete(Long id) {
- // 执行之后去 rdm 中查看即可
- return userMapper.delete(id);
- }
测试 1
第一次访问 findOne
第二次访问 findOne:
仍然是刚刚的结果, 但是控制台没有打印出任何东西, 说明缓存成功
测试 2
调用 update 后再次调用 findOne:
可以看出信息已被修改且未访问数据库
测试 3
访问 delete, 查看 rdm:
说明删除成功~
原创文章, 文笔有限, 才疏学浅, 文中若有不正之处, 万望告知.
源码地址
- GitHub https://github.com/viyog/viboot
- Gitee https://gitee.com/viyog/viboot
记得顺手点个 star, 您的肯定是对我写作最大的动力!
????~
寻找组织
QQ 群: 645860262
QQ:2148715557
程序员经典必备枕头书免费送
Vi 的技术博客公号为了反馈广大读者对我的支持, 特将在近期举办无套路, 包邮送书活动 (活动规则为公号粉丝到达 500 人, 目前 445)
来源: http://www.bubuko.com/infodetail-2995766.html