面对高频访问的解决办法--redis and 主从复制

当数据库的访问量过大时数据库会宕机 ,所以得采用办法来解决这个问题

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让项目不出错

然后它就会自动根据请求需求来访问那个数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值