当数据库的访问量过大时数据库会宕机 ,所以得采用办法来解决这个问题
1 redis
将高频访问且不经常修改的数据放在内存中
redis 是内存中中非关系性数据库 即数据键值对之间没有关联
redis依赖
<!--redis配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
在java中调用redis是通过redisTemplete 它需要去配置键的泛型不然会出现一些读不懂的内容
package com.itheima.reggie.config;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Redis配置类
*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
//默认的Key序列化器为:JdkSerializationRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
也需要在yml或者properties 中配置 即用谁的redis
redis: #host: localhost host: 目标ip port: 6379 password: password database: 0 #操作的是0号数据库 # jedis: # #Redis连接池配置 # pool: # max-active: 8 #最大连接数 # max-wait: 1ms #连接池最大阻塞等待时间 # max-idle: 4 #连接池中的最大空闲连接 # min-idle: 0 #连接池中的最小空闲连接
然后在需要用的地方直接调用如
@Autowired
private DishService dishService;
@Autowired
private RedisTemplate redisTemplate;
/**
* 添加菜品
*
* @param dishDto
* @return
*/
@PostMapping
public R<String> addDishAndFlavor(@RequestBody DishDto dishDto) {
//添加只需要清空指定菜品类
String redisKey = "dish_"+dishDto.getCategoryId()+"_1";
redisTemplate.delete(redisKey);
dishService.addDishAndFlavor(dishDto);
return R.success("添加成功");
}
其中得注意什么时候要删除内存的数据
如更新菜品就得把所有的都菜品都删除因为更新菜品不知道会不会修改的它的分类id即不知道更改了那
然后 :有没有什么更简单的方法吗?
有:springcache提供了一些注解来代替具体代码
依赖:在redis依赖基础上再引用
<!--cache配置与redis关联--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
分别有:4个注解
@EnableCaching //开启缓存管理
在application 引导类加上这个注解 是用来启动 redisManager的
@CacheEvict(value = {"setmealCache"} ,allEntries = true)
删除这个值即setmealCache下所有 键值对
@Cacheable(value = "setmealCache",key ="#categoryId+'_'+#status")
这个注解是有数据请求发过来 先在缓存中找 。有就直接返回 没有就通过方法去访问数据库并将返回值存进缓存中
@CachePut
它是将方法访问数据库得到的返回值存进缓存中 一般用在新增上
2主从复制
优点:1读写分离 2 高可用性
为什么还要主从复制呢 ?因为redis只能解决不经常修改的数据的访问
如果访问的高频数据需要经常修改呢?
如果它再用redis是不是显得多此一举?都要经常修改是不是去得经常删然后又存!
什么是主从复制?
既然单个数据库不能满足访问量的需求 ,是不是可以用多个数据库来将足够能让数据库宕机的访问量分散来 就能满足需要 且每个数据库数据一致
且这样还有优点:可能因为某些情况一个数据库数据丢失了,然后呢再建一个数据库就好了因为有多个数据库且里面数据一样。
一般主从复制:只有一个主机 多个副机
主机:一般用于增删改 副机用于查询 因为相对于增删改 查询的访问次数更多
然后java中使用主从复制也有依赖且不会改变原有代码 感慨一下idea真强大
依赖:
#读写分离配置1
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
还得在yml或者properties中配置一下
spring: shardingsphere: datasource: names: master,slave,xxx # 主数据源 master: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/reggie?characterEncoding=utf-8 username: 账号 password: 密码 # 从数据源 slave: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://副机ip:3306/reggie?characterEncoding=utf-8 username: 账号 password: 密码 xxx: type:....... ..................... masterslave: # 读写分离配置 load-balance-algorithm-type: round_robin #轮询 即查的请求你一个我一个它一个轮着来 # 最终的数据源名称 name: dataSource #一般不变 # 主库数据源名称 master-data-source-name: master # 从库数据源名称列表,多个逗号分隔 slave-data-source-names: slave,xxx props: sql: show: true #开启SQL显示,默认false main: allow-bean-definition-overriding: true
main:
allow-bean-definition-overriding: true
作用:就是如果项目中存在同名 的 bean 后定义的bean会覆盖开始的bean让项目不出错
然后它就会自动根据请求需求来访问那个数据