Redis介绍
Redis 是一种开源(BSD 许可)的内存数据结构存储,用作数据库、缓存、消息代理和流式处理引擎。Redis 提供数据结构,例如字符串、哈希、列表、集、带有范围查询的排序集、位图、超日志、地理空间索引和流。 Redis 具有内置复制、Lua 脚本、LRU 逐出、事务和不同级别的磁盘持久性,并通过 Redis Sentinel 和 Redis 集群的自动分区提供高可用性。
官方文档:Redis 简介 |雷迪斯Redis 简介 |雷迪斯Redis 简介 |雷迪斯
为什么要用Redis
1、内存数据库,快,很快.......
2、工作单线程worker,串行化、原子操作. (IO线程是多线程)
3、IO模型(epoll), 支撑高并发.
4、kv模型,v具有类型结构.
5、具有本地方法,计算向数据移动。(a,b) => 交集
二进制安全,Value最大512M
Redis单线程问题
主要是指Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。
但Redis的其他功能,比如持久化、异步删除、集群数据同步等等,其实是由额外的线程执行的。Redis工作线程是单线程的,但是,整个Redis来说,是多线程的。
2 Redis单线程为什么快
(1) 基于内存操作:Redis 的所有数据都存在内存中,因此所有的运算都是内存级别的,所以他的性能比较高;
(2) 数据结构简单:Redis 的数据结构是专门设计的,而这些简单的数据结构的查找和操作的时间大部分复杂度都是 O(1),因此性能比较高;
(3) 多路复用和非阻塞 I/O:Redis使用 I/O多路复用功能来监听多个 socket连接客户端,这样就可以使用一个线程连接来处理多个请求,减少线程切换带来的开销,同时也避免了 I/O 阻塞操作;
(4) 避免上下文切换:因为是单线程模型,因此就避免了不必要的上下文切换和多线程竞争,这就省去了多线程切换带来的时间和性能上的消耗,而且单线程不会导致死锁问题的发生;
(5) I/O 多路复用
这是IO模型的一种,即经典的Reactor设计模式,
I/O 多路复用,简单来说就是通过监测文件的读写事件再通知线程执行相关操作,保证 Redis 的非阻塞 I/O 能够顺利执行完成的机制。
多路指的是多个socket连接,
复用指的是复用一个线程。多路复用主要有三种技术:select,poll,epoll。
epoll是最新的也是目前最好的多路复用技术。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗),且Redis在内存中操作数据的速度非常快(内存内的操作不会成为这里的性能瓶颈),主要以上两点造就了Redis具有很高的吞吐量。
SpringBoot集成Redis
一、引入依赖
<!--整合redis依赖-->
<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>
二、配置文件
server.port=8081
#--------------------------mysql-------------------------------------
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url: jdbc:mysql://localhost:3306/mx_web?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.druid.initial-size=2
spring.datasource.druid.max-active=10
spring.datasource.druid.min-idle=2
spring.datasource.druid.max-wait=3000
#--------------------------mybatis-plus-------------------------------------
mybatis-plus.mapper-locations=classpath:mappers/*.xml
#--------------------------????-------------------------------------
logging.level.root=error
logging.level.cn.deruan=debug
#----------------------redis??-----------------------------#
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.database=0
spring.redis.timeout=1800000
spring.redis.password=
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=5
spring.redis.lettuce.pool.max-active=20
三、编写序列化配置类
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
// 创建模板
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// key和 hashKey采用 string序列化
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// value和 hashValue采用 JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
}
四、使用使用redis进行简单的存值,取值
@RestController
@RequestMapping("redis")
public class RedisController {
@Autowired
private RedisTemplate redisTemplate;
@GetMapping
public void contextLoads2() {
redisTemplate.opsForValue().set("name", "你好,redis");
String name = (String) redisTemplate.opsForValue().get("name");
System.out.println(name); //你好,redis
}
}
还有更多中操作redis的API
四、API的简单认识
通过本地的redis可视化工具查看