黑马点评DAY5|商户查询缓存

news2024/11/22 23:11:18

商户查询缓存

缓存的定义

缓存就是数据交换的缓冲区(Cache),是存储数据的临时地方,一般读写性能较高。

  • 比如计算机的CPU计算速度非常快,但是需要先从内存中读取数据再放入CPU的寄存器中进行运算,这样会限制CPU的运算速度,所以CPU中也会设计一个缓存,存入经常需要用到的数据,提升了运算效率。CPU缓存也是衡量CPU性能好坏的重要标准之一。
  • 再比如浏览器缓存,会缓存一些页面静态资源(js、css),浏览器缓存未命中的一些数据就会去Tomcat中的Java应用请求,而Java应用也有应用层缓存,一般用Redis去做。如果缓存再没有命中,就可以去数据库查询,数据库也有缓存,mysql中如索引数据。最后还会去查询CPU缓存,磁盘缓存。在这里插入图片描述

缓存的优缺点

优点:

  • 降低了后端的负载,实际开发的过程中,企业的数据量,少则几十万,多则几千万,如果没有缓存来作为避震器,这么大的用户并发量服务器是扛不住的。
  • 缓存的读写效率非常高,响应时间短

缺点:

  • 数据一致性成本高
  • 代码维护成本高,解决一致性问题需要复杂的业务编码,也有可能出现缓存穿透、缓存雪崩等问题
  • 运维成本,缓存需要大规模集群模式,需要人力成本

给店铺查询任务添加缓存

整体的业务逻辑如下图所示:
在这里插入图片描述

  • 先从redis中通过店铺id查询缓存数据,登录模块是用map存的,这里我们使用String来存,就需要将对象先转为JSON格式。
  • 如果redis中存在,就返回店铺信息。
  • 如果redis中不存在,就继续向数据库中查询。
  • 如果数据库不存在,返回“店铺不存在”
  • 如果数据库存在,将店铺信息写入redis
  • 返回店铺信息
    代码如下:
package com.hmdp.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.dto.Result;
import com.hmdp.entity.Shop;
import com.hmdp.mapper.ShopMapper;
import com.hmdp.service.IShopService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import static com.hmdp.utils.RedisConstants.CACHE_SHOP_KEY;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {
    @Autowired
    StringRedisTemplate  stringRedisTemplate;
    @Override
    public Result queryById(Long id) {
        String key = CACHE_SHOP_KEY + id;
        //1.从redis中查询
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        //2.存在,返回店铺信息
        if (!StringUtils.isBlank(shopJson)) {
            return Result.ok(JSONUtil.toBean(shopJson, Shop.class));
        }
        //3.不存在,用id在数据库查询
        Shop shop = getById(id);
        //4.不存在,返回“店铺不存在”
        if (shop == null) {
            return Result.ok("店铺不存在");
        }
        //5.存在,缓存到redis
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop));
        //6.返回店铺信息
        return Result.ok(shop);
    }
}

然后再去第二次查询某一个美食的数据,发现速度由2ms变成了1ms。
在resp中也发现了cache:shop:id的缓存。
在这里插入图片描述

拓展练习

将首页的店铺种类信息缓存到redis中
在这里插入图片描述
因为店铺种类有十种,可以通过LIst的数据结构存储,但是需要将List中的ShopType对象先转为JSON,取出的时候再由JSON转为ShopType对象。具体代码如下:

package com.hmdp.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.dto.Result;
import com.hmdp.entity.ShopType;
import com.hmdp.mapper.ShopTypeMapper;
import com.hmdp.service.IShopTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.hmdp.utils.RedisConstants.CACHE_SHOP_TYPE_KEY;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    public Result queryTypeList() {
        //1.从redis中查找店铺类型数据
        List<String> shopTypesByRedis = stringRedisTemplate.opsForList().range(CACHE_SHOP_TYPE_KEY, 0, 9);
        //2.存在,返回店铺信息,最终需要返回List<ShopType>形式的list,因此需要将JSON转换为ShopType类型
        List<ShopType> shopTypes = new ArrayList<>();
        if(shopTypesByRedis.size() != 0){
            for(String s:shopTypesByRedis){
                //转为JSON
                ShopType shoptype = JSONUtil.toBean(s, ShopType.class);
                shopTypes.add(shoptype);
            }
            return Result.ok(shopTypes);
        }
        //3.不存在,去数据库中寻找,并根据sort排序
        List<ShopType> shopTypesByMysql = query().orderByAsc("sort").list();
        //4.数据库不存在,返回店铺信息不存在
        if(shopTypesByMysql.size() == 0){
            return Result.ok("店铺信息不存在");
        }
        //5.店铺信息存在,存入redis中
        for(ShopType shop:shopTypesByMysql){
            stringRedisTemplate.opsForList().leftPush(CACHE_SHOP_TYPE_KEY, JSONUtil.toJsonStr(shop));
        }
        //6.返回店铺信息
        return Result.ok(shopTypesByMysql);
    }
}

缓存更新策略

在业务中,如果我们对数据库数据做了一些修改,但是缓存中的数据没有保持同步更新,用户查询时会查到缓存中的旧数据,这在很多场景下是不允许的。缓存更新的几种策略有三种

  • 内存淘汰(该机制默认存在)
    缓存设定一定的上限,当达到这个上限就会自动淘汰部分数据。一致性保持较差,因为淘汰的这一部分数据才可以更新,维护成本为0.
  • 超时剔除
    通过redis中的expire关键字添加TTL时间,到期后自动删除缓存。
    一致性强弱取决于TTL的时间,一致性一般好于内存淘汰机制。维护成本也不是很高。
  • 主动更新 <\font>
    自己编写业务逻辑,在修改数据库的同时,更新缓存。
    一致性好,但是维护成本较高。

业务场景选择更新策略的原则:

  • 低一致性需求:使用内存淘汰机制,例如店铺类型的查询缓存
  • 高一致性需求:主动更新,并以超时剔除作为兜底方案。如店铺详情查询。
    一般采用01的方式主动更新缓存

在这里插入图片描述
主动更新的方法可以采用:当数据库发生改变的时候,删除缓存,当查询数据库的时候,更新缓存。
这里有两种操作顺序的选择:

  • 先删除缓存,再操作数据库,但是有可能发生如下图左图的安全问题。
  • 先操作数据库,再删除缓存。有可能发生如下图右图的安全问题。
  • 但是因为数据库读写时间远远大于缓存读写时间,因此右图发生的概率更低。万一发生,超时时间可以兜底。
    在这里插入图片描述

业务修改

  • 根据id查询商铺信息,如果未能在缓存命中,从数据库查询,并写入缓存,设置超时时间
   //5.存在,缓存到redis,加入有效时间限制
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
  • 根据id修改商铺信息,先修改数据库,再删除缓存。这两个动作需要绑定,所以该方法用事务控制其原子性
    @Override
    @Transactional
    public Result update(Shop shop) {
        Long id = shop.getId();
        if(id == null){
            return Result.fail("店铺id不为空");
        }
        //1.更新数据库
        updateById(shop);
        //2.删除缓存
        stringRedisTemplate.delete(CACHE_SHOP_KEY+shop.getId());
        return Result.ok();
    }

测试:

  • 首先测试当访问某一家店铺信息的时候,未命中,是否会缓存到redis中
  • 再测试修改店铺信息是否会删除redis缓存,因为修改的功能只能在商家界面做,所以这里用http-client对业务逻辑进行测试。==发送请求,数据库修改,redis缓存也被删除。==说明业务修改成功。这样可以有效解决一致性问题。
PUT http://localhost:8081/shop
Content-Type: application/json

{
  "area":"大关",
  "openHours": "10:00-22:00",
  "sold": 4215,
  "address": "china",
  "comments":3035,
  "avgPrice": 80,
  "score": 37,
  "name": "110茶餐厅",
  "typeId": 1,
  "id": 1
}

缓存穿透

客户端请求的数据在缓存和数据库中都不存在,那么根据我们的缓存更新策略,最终都会向数据库索取数据;那么如果有不怀好意的人用并发的线程用虚假的id向数据库请求数据,就会搞垮数据库。
两种解决方案:

  • 缓存空对象:如果redis和数据库中都未能命中,最终数据库会向redis写入一个null,这样在下一次向redis请求的时候就不会再到达数据库。
    优点:实现简单、维护方便
    缺点:
    • 有额外的内存消耗(但是也可以给null设置一个TTL
    • 可能造成短期的不一致(可以控制TTL的时长
      在这里插入图片描述
  • 布隆过滤器
    • 布隆过滤器的原理
      • 定义:布隆过滤器(Bloom Filter)是一种空间效率非常高的概率型数据结构,用于判断一个元素是否属于某个集合。
      • 构成
        1.布隆过滤器使用一个固定长度的位数组,所有位初始都设置为0。
        2.一组独立的哈希函数,用于将输入元素映射到位数组中的某个位置。
      • 判断原理:向布隆过滤器中添加元素时,通过k个哈希函数计算出k个位置,并将这些位置上的位设置为1。查询元素时,使用同样的哈希函数计算出k个位置,并检查这些位置上的位是否全为1。如果所有位置都为1,则元素可能在集合中如果有一个位置为0,则元素肯定不在集合中
    • 优点:内存占用小,没有多余的key
    • 缺点:实现复杂、存在误判可能

在这里插入图片描述

采用缓存空对象解决缓存穿透问题

我们应该做如下修改:
在这里插入图片描述
我们需要修改queryById方法,注意字符串判断内容是否相等用equals:shopJson.equals(“”)

   @Override
    public Result queryById(Long id) {
        String key = CACHE_SHOP_KEY + id;
        //1.从redis中查询
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        //2.命中,返回店铺信息
        if (!StringUtils.isBlank(shopJson)) {
            return Result.ok(JSONUtil.toBean(shopJson, Shop.class));
        }
        //如果命中的是"",就返回"店铺信息不存在!"
        if(shopJson != null){
            return Result.fail("店铺信息不存在!");
        }
        //3.不存在,用id在数据库查询
        Shop shop = getById(id);
        //4.不存在,返回“店铺不存在”
        if (shop == null) {
            //如果数据库不存在该id的商铺,就向redis中存入空字符串,并返回"店铺信息不存在!"
            stringRedisTemplate.opsForValue().set(key, "");
            return Result.ok("店铺信息不存在!");
        }
        //5.存在,缓存到redis,加入有效时间限制
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
        //6.返回店铺信息
        return Result.ok(shop);
    }

然后进行测试,发送请求:http://localhost:8080/api/shop/1111,id=1111并不存在,但是该数据会被缓存到redis中:
在这里插入图片描述再次发送这个请求,不会到达数据库,而是访问redis之后直接就返回。控制台也没有任何数据库调用的日志打印出来。
在这里插入图片描述
其他解决方案:

  • 增加id的复杂度,让攻击者无发猜测到id格式。
  • 对id做一些基础的格式校验
  • 加强用户权限的管理
  • 做好热点参数的限流

缓存雪崩

缓存雪崩指的是大量可以在同一时段同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。
在这里插入图片描述
解决方案:

  • 给不同的key的TTL添加随机值,这样key就不会在同一时间宕机
  • 提高==Redis集群(Redis哨兵模式)==服务的可用性。当一个Redis挂了,会被监控到,立马启动另外一个Redis提供服务。也可以使用主从结构构成集群,防止主节点的数据丢失。
  • 给缓存业务添加降级限流策略(比如快速失败、拒绝服务)
  • 给业务添加多级缓存(Nginx缓存–JVM缓存–Redis缓存–数据库缓存)。

缓存击穿

缓存击穿也叫热点Key问题,就是一个被高并发访问(比如正在做活动的某一件商品)并且缓存建立业务较为复杂的key失效了,突然大量的请求会在瞬间给数据库带来巨大的冲击。
两种解决方案:

互斥锁解决缓存击穿

让多线程只有一个线程能获取锁来创建缓存
在这里插入图片描述
在这里插入图片描述
我们可以手动地设定一个锁来实现这样的功能,redis中的setnx表示只有当一个key不存在的时候才可以写入,那么这样就可以达到互斥的效果。那么,

  • 获取锁的操作就是:setnx lock 1通常还会给锁加一个TTL,如果超过这个时间,就自动删除锁。防止获取到锁的线在这里插入代码片程出问题。
  • 释放锁的操作就是:del lock
    在这里插入图片描述
    代码实现:
  • 首先定义获取锁和释放锁的方法:
    获取锁:
    private boolean tryLock(String key){
        //获取锁
        Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10L, TimeUnit.SECONDS);
        return BooleanUtil.isTrue(flag);
    }

释放锁:

    private void unLock(String key){
        stringRedisTemplate.delete(key);
    }

将缓存穿透的业务逻辑封装,最终返回Shop对象

  //解决缓存穿透的代码
    public Shop queryWithPassThroough(Long id){
        String key = CACHE_SHOP_KEY + id;
        //1.从redis中查询
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        //2.命中,返回店铺信息
        if (!StringUtils.isBlank(shopJson)) {
            return JSONUtil.toBean(shopJson, Shop.class);
        }
        //如果命中的是"",就返回"店铺信息不存在!"
        if(shopJson != null){
            return null;
        }
        //3.不存在,用id在数据库查询
        Shop shop = getById(id);
        //4.不存在,返回“店铺不存在”
        if (shop == null) {
            //如果数据库不存在该id的商铺,就向redis中存入空字符串,并返回"店铺信息不存在!"
            stringRedisTemplate.opsForValue().set(key, "");
            return shop;
        }
        //5.存在,缓存到redis,加入有效时间限制
        stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
        //6.返回店铺信息
        return shop;
    }

用互斥锁解决缓存击穿的问题:

    //用互斥锁解决缓存击穿的问题
    public Shop queryWithMutex(Long id){
        String key = CACHE_SHOP_KEY + id;
        //1.从redis中查询
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        //2.命中,返回店铺信息
        if (!StringUtils.isBlank(shopJson)) {
            return JSONUtil.toBean(shopJson, Shop.class);
        }
        //3.如果命中的是"",就返回"店铺信息不存在!"
        if(shopJson != null){
            return null;
        }
        Shop shop = null;
        //4.实现缓存重建
        //4.1 获取互斥锁
        String lockKey = "lock:shop:" + id;
        boolean isLock = tryLock(lockKey);
        try {
            //4.2 判断是否获取成功
            //4.3 失败,则休眠并重试
            if(!isLock){
                Thread.sleep(50);
                return queryWithMutex(id);
            }
            //4.4 成功,用id在数据库查询
            shop = getById(id);
            //5.不存在,返回“店铺不存在”
            if (shop == null) {
                //如果数据库不存在该id的商铺,就向redis中存入空字符串,并返回"店铺信息不存在!"
                stringRedisTemplate.opsForValue().set(key, "");
                return shop;
            }
            //6.存在,缓存到redis,加入有效时间限制
            stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
            //7.释放互斥锁
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally{
            unLock(lockKey);
        }
        //8.返回店铺信息
        return shop;
    }
  • 通过自动化测试工具jmeter对进行压力测试
    在这里插入图片描述
    执行完发现没有报错
    在这里插入图片描述
    并且数据库只调用了一次select操作,说明互斥锁成功实现了
    在这里插入图片描述

设置逻辑过期时间解决缓存击穿

在这里插入图片描述

  • 缓存工具封装对象:
    先定义一个类用来保存以及超时时间,对原来代码没有侵入性。
package com.hmdp.entity;

import lombok.Data;

import java.time.LocalDateTime;

/**
 * @author Zonda
 * @version 1.0
 * @description TODO
 * @2024/7/4 16:21
 */
@Data
public class RedisData {
    private LocalDateTime expireTime;
    private Object data;

}

在ShopServiceImpl 新增此方法,利用单元测试进行缓存预热

    public void saveShop2Redis(Long id,Long expireSeconds){
        Shop shop = getById(id);
        RedisData redisData = new RedisData();
        redisData.setData(shop);
        redisData.setExpireTime(LocalDateTime.now().plusSeconds(expireSeconds));
        stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, JSONUtil.toJsonStr(redisData));
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1893779.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

67.WEB渗透测试-信息收集- WAF、框架组件识别(7)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;66.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;6&#xff09;-CSDN博客 关于w…

6年铲屎官测评宠物空气净化器哪款好,热门养宠空气净化器排名

作为一名资深猫奴&#xff0c;发现很多铲屎官每到春秋换季就开始疯狂打喷嚏、突然开始全身过敏。其原因是猫毛一到换季就开始疯狂掉毛&#xff0c;相对于可见猫毛&#xff0c;漂浮在空气中的浮毛就是罪灰祸首。微小的浮毛在空气总容易被人体吸入体内&#xff0c;而浮毛上面附带…

通义灵码AI编程助手怎么样?通义灵码详解(亲测)

通义灵码是阿里云推出的一款基于通义大模型的AI智能编程辅助工具&#xff0c;通义灵码提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、代码解释、研发智能问答、异常报错排查等能力&#xff0c;阿小云axiaoyun.com整理通义灵码介绍、使用场景、…

澳蓝荣耀时刻,6款产品入选2024年第一批《福州市名优产品目录》

近日&#xff0c;福州市工业和信息化局公布2024年第一批《福州市名优产品目录》&#xff0c;澳蓝自主研发生产的直接蒸发冷却空调、直接蒸发冷却组合式空调机组、间接蒸发冷水机组、高效间接蒸发冷却空调机、热泵式热回收型溶液调湿新风机组、防火湿帘6款产品成功入选。 以上新…

二叉树与堆相关的时间复杂度问题

目录 满二叉树与完全二叉树高度h和树中节点个数N的关系 向上调整算法&#xff1a; 介绍&#xff1a; 复杂度推导&#xff1a; 向下调整算法&#xff1a; 介绍&#xff1a; 复杂度推导&#xff1a; 向上调整建堆&#xff1a; 介绍&#xff1a; 复杂度推导&#xff1a;…

自然语言处理学习--3

对自然语言处理领域相关文献进行梳理和总结&#xff0c;对学习的文献进行梳理和学习记录。希望和感兴趣的小伙伴们一起学习。欢迎大家在评论区进行学习交流&#xff01; 论文&#xff1a;《ChineseBERT: Chinese Pretraining Enhanced by Glyph and Pinyin Information》 下面…

sublime 3 背景和字体颜色修改

sublime 4 突然抽风&#xff0c;每次打开都显示 “plugin_host-3.3 has exited unexpectedly, some plugin functionality won’t be available until Sublime Text has been restarted” 一直没调好&#xff0c;所以我退回到sublime 3了。下载好了软件没问题&#xff0c;但是一…

基于opencv的斜光测距及python实现

1.前言 最近做了一个基于opencv的斜光测距的小项目&#xff0c;东西不多&#xff0c;但是很有意思&#xff0c;值得拿出来学一学。项目里面需要比较精确的定位功能&#xff0c;将前人matlab代码移植到python上&#xff0c;并且做了一些优化&#xff0c;简化逻辑(毕竟我是专业的…

Spring Boot中使用SpringEvent组件

Spring的事件机制是基于观察者模式的实现&#xff0c;主要由以下三个部分组成&#xff1a; 事件&#xff08;Event&#xff09;&#xff1a;事件是应用中发生的重要事情&#xff0c;通常是一个继承自ApplicationEvent的类。 事件发布器&#xff08;Publisher&#xff09;&…

iPhone白苹果怎么修复?4个方法解决你的烦恼!

其实iPhone手机出现“白苹果”这事&#xff0c;如果是iPhone轻度用户&#xff0c;可能大家一辈子都不会遇到一次。但如果是iPhone重度用户、越狱爱好者、软件收集狂&#xff0c;可能就会遇到了。 白苹果&#xff0c;一般指iOS设备出现软、硬件故障&#xff0c;卡在一个类似于启…

AI智能对话绘画音乐三合一创作神器源码系统 带完整的源代码包以及搭建部署教程

系统概述 该系统旨在通过先进的AI技术&#xff0c;实现用户与机器的深度交互&#xff0c;从而在对话中创作出独一无二的艺术作品——无论是细腻的画作、动人的乐曲&#xff0c;还是两者兼备的多媒体体验&#xff0c;都能在这个平台上轻松实现。本文将详细介绍该系统的系统概述…

2024年在WordPress中创建销售活动的专家级优惠券方法

2024年在WordPress中创建销售活动的专家级优惠券方法 今天我想和大家分享一些关于如何在WordPress网站上使用专家级优惠券工具来创建销售活动的经验。对于已经在电商领域有一定经验的店主&#xff0c;利用专家级优惠券不仅能吸引顾客&#xff0c;还能显著增加销量。在这篇文章…

CLAM用于弱监督WSI分析

计算病理学&#xff08;computational pathology&#xff09;下的深度学习方法需要手动注释大型 WSI 数据集&#xff0c;并且通常存在领域适应性和可解释性较差的问题。作者报告了一种可解释的弱监督深度学习方法&#xff0c;只需要WSI级标签。将该方法命名为聚类约束注意力多实…

商务视频推广8个增加用户转化率的技巧-华媒舍

商务视频推广是一种有效的营销策略&#xff0c;可以帮助企业吸引更多的潜在客户并增加用户转化率。我们将介绍8个提高商务视频推广效果的技巧&#xff0c;帮助您更好地利用视频来促进业务增长。 技巧一&#xff1a;制作高质量的内容 成功的商务视频推广首先要有高质量的内容。…

达梦数据库 页大小与数据库字段长度的关系

对于达梦数据库实例而言&#xff0c;页大小 (page_size)、簇大小 (extent_size)、大小写敏感 (case_sensitive)、字符集 (charset) 这四个参数&#xff0c;一旦确定无法修改&#xff1b;如果过程中发现这些数据设置的不对&#xff0c;只能是重新新建数据库实例&#xff0c;而不…

Linux服务器上安装CUDA11.2和对应的cuDNN 8.4.0

一、检查 检查本机是否有CUDA工具包&#xff0c;输入nvcc -V: 如图所示&#xff0c;服务器上有CUDA&#xff0c;但版本为9.1.85&#xff0c;版本过低&#xff0c;因此博主要重装一个新的。 二、安装CUDA 1.查看服务器最高支持的CUDA版本 在命令行输入nvidia-smi查看显卡驱动…

航空数据管控系统-①项目准备阶段:任务2:项目技术预研(技术架构)

任务描述 掌握项目的总体功能&#xff0c;及实现流程。预习项目中所使用到的技术和知识点。 任务指导 一、项目效果展示 图1-数据统计大屏页面 图2-航空实时监控页面 二、项目架构 1、总体架构&#xff1a; 2、技术架构 技术清单&#xff1a; 功能 组件 说明 消息中间件…

MySQL 三大日志 ( binlog、redo log 和 undo log ) 的作用?

MySQL是一个功能强大的关系型数据库管理系统&#xff0c;它的高可靠性、高性能和易用性使得它成为众多企业和开发者的首选。在MySQL内部&#xff0c;为了保证数据的完整性、恢复能力和并发性能&#xff0c;设计了一套复杂的日志系统。其中&#xff0c;redo log、bin log和undo …

数据开发人员如何真正理解业务、并构建业务模型?

问题背景 最近有同学在问&#xff0c;新到一家公司&#xff0c;如何去深入理解业务&#xff1f;并高于业务视角呢&#xff1f; 针对这个问题 &#xff0c;我们将问题进行拆分以下几点进行回答&#xff0c;首先懂业务的标准是什么&#xff1f; 根据笔者的经验将懂业务标准进行如…

百度出品_文心快码Comate提升程序猿效率

1.文心快码 文心快码包含指令、插件 和 知识三种功能&#xff0c; 1&#xff09;指令包含Base64编码、Base64解码、JSON转TS类型、JSON转YAML、JWT解码喂JSON。 2&#xff09;插件包含 3&#xff09;指令包含如下功能&#xff1a; 官网链接