5. 一线大厂高并发缓存架构实战与性能优化

2023-11-20


本文是按照自己的理解进行笔记总结,如有不正确的地方,还望大佬多多指点纠正,勿喷。

课程内容:

1、中小公司Redis缓存架构以及线上问题分析

2、大厂线上大规模商品缓存数据冷热分离实战

3、实战解决大规模缓存击穿导致线上数据库压力暴增

4、黑客攻击导致缓存穿透线上数据库宕机Bug

5、一行代码解决线上缓存穿透问题

6、一次大V直播带货导致线上商品系统崩溃原因分析

7、突发性热点缓存重建导致系统压力暴增问题分析

8、基于DCL机制解决热点缓存并发重建问题实战

9、Redis分布式锁解决缓存与数据库双写不一致问题实战

10、大促压力暴增导致分布式锁串行争用问题优化实战

11、一次微博明星热点事件导致系统崩溃原因分析

12、利用多级缓存架构解决Redis线上集群缓存雪崩问题

1. 冷热数据分离

我们建议放缓存的地方都加一个超时时间,只需要对热点数据进行缓存,一些其他的冷门的数据就不用放到缓存里面占用时间了。

如果对于每天都有访问的数据就一直放在缓存里面,对于那些数据每查询一次可以加一点缓存超时延期。也就是读延期。这样以来那些有人访问的数据会一直在缓存里面,而那些没人访问的数据达到缓存的设定时间,就会从缓存里面移除。这样以来就做到了数据的冷热分离

2. 缓存设计

2.1 缓存击穿(失效)

由于大批量缓存在同一时间失效可能导致大量请求同时穿透缓存直达数据库,可能会造成数据库瞬间压力过大甚至挂掉,对于这种情况我们在批量增加缓存时最好将这一批数据的缓存过期时间设置为一个时间段内的不同时间。

如果商品上架或者更新商品,有那这批量更新、批量导入的。对商品进行批量操作,那商品的失效时间是一样的,同时过期。结果都没有缓存了,结果又有大量的请求。就是缓存里面没有了,但是数据库里面还有。

示例伪代码:

这个问题怎么解决呢?

那么我们可以把设置的超时时间设置成随机时间,在原来超时时间的基础上加一个随机数。

2.2 缓存穿透

缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,通常出于容错的考虑,如果从存储层查不到数据则不写入缓存层。

第一种情况:就是比如商品上架之后,一不小心把他彻底删除了,这样删除之后导致数据库以及缓存里面都没有了这个数据。结果后端数据全部没有了,而前端还一直有高并发的数据一直过来,导致大量的请求过来查数据库没有,查缓存也没有,这样一来缓存以及数据库的压力都比较大,特别是数据库。这个就叫做缓存穿透,有一个“透”字,就是把整个后端全部穿透了。

还有一种情况,就是如果是大型互联网,每天都有黑客来攻击你,假如他知道了你这个玩也链接中的数字就是你商品的id,那这个时候别人就可以攻击了,就是造一堆商品不存在的id,然后就用压测的软件去大量请求这个不存在商品,DDoS攻击,这样就会把数据层全部打穿、穿透。

缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。

造成缓存穿透的基本原因有两个:
第一,自身业务代码或者数据出现问题。
第二,一些恶意攻击、爬虫等造成大量空命中。缓存穿透问题解决方案:

那么这样的缓存穿透怎么解决呢?

可以设置一个空缓存。或者我们给一个特殊的标志,为了加以区分其他的情况,可以设置一个“{}”这样的空缓存。
这样看来是解决了黑客的攻击问题,但是如果有些黑客比较聪明,他不是拿一个商品攻击你,他每次都换着id去请求,一个数据库中有成千上万个空数据,那这样就会导致生成成千上万个空“{}”的缓存,又达到了攻击,那怎么解决呢?
过期,设置过期时间。空缓存可以设置几分钟过期之类的。如果他一直使用同一个商品,我们也可以设置一个商品的读延期时间。延期缓存就延期一两分钟的样子可以。

2.3 缓存雪崩

缓存雪崩指的是缓存层支撑不住或宕掉后,流量会像奔逃的野牛一样,打向后端存储层。

由于缓存层承载着大量请求,有效地保护了存储层,但是如果缓存层由于某些原因不能提供服务(比如超大并发过来,缓存层支撑不住,或者由于缓存设计不好,类似大量请求访问bigkey,导致缓存能支撑的并发急剧下降),于是大量请求都会打到存储层,存储层的调用量会暴增,造成存储层也会级联宕机的情况。

预防和解决缓存雪崩问题,可以从以下三个方面进行着手。

  1. 保证缓存层服务高可用性,比如使用Redis Sentinel或Redis Cl
    uster。
  2. 依赖隔离组件为后端限流熔断并降级。比如使用Sentinel或Hystrix限流降级组件。
    比如服务降级,我们可以针对不同的数据采取不同的处理方式。当业务应用访问的是非核心数据(例如电商商品属性,用户信息等)时,暂时停止从缓存中查询这些数据,而是直接返回预定义的默认降级信息、空值或是错误提示信息;当业务应用访问的是核心数据(例如电商商品库存)时,仍然允许查询缓存,如果缓存缺失,也可以继续通过数据库读取。
  3. 提前演练。在项目上线前,演练缓存层宕掉后,应用以及后端的负载情况以及可能出现的问题,在此基础上做一些预案设定。

3. 大V直播带货导致线上商品系统崩溃原因分析

像一些特别大的直播带货主播可能会上一些非常冷门的商品,就是之前根本没有买的商品,也没有访问的商品。但是当这些大主播们在直播间让大家抢这些商品的时候,可能一下几百万人去请求这个商品,但是这个商品在缓存里面没有,因为他是冷门的商品嘛。

假设现在一下有几万个请求来调用这个方法,然后查缓存是没有的,这个时候就会走到数据库这边来。但是数据的抗压能力很弱的。不过这个是小概率事件,因为可能这个冷门的商品在上架之前先进行访问就会缓存起来,我们不考虑这种情况,我们就考虑这种小概率的事件,就是这个冷门的商品缓存失效了,然后又有很多人来访问,现在就会压力全给到数据库,数据库承受压力很小的,这样就会导致数据库可能会挂掉。这样就会防止这种情况的。

虽然是小概率事件,我们还是要规避的。这就是突发性热点缓存重建导致系统压力暴增问题

4. 突发性热点缓存重建导致系统压力暴增问题

这个问题怎么解决呢?

最简单的方式就是加锁。就是单例模式里面有一个DCL(Double Check Lock)双重检测锁。这个就可以解决这个问题。

就是双重查询

在这里插入图片描述

对于那些突发性的热点缓存,并发重建的问题就解决了。一下来了几万条数据需要重建缓存,没关系,只有一个人能重建缓存。这个时候其他的请求就得等着这个重建缓存,但是等这个重建完成之后,进到这块代码的时候发现缓存里面有数据了,就不会再添加缓存了。

其实这样做还是回有问题,就是synchronized只在单节点内是有效的。如果这个是一个web应用的一个集群,用这个代码做的话,他的每个web服务器上都要重建一次,synchronized{this}中使用this肯定是不行的。就是比如101商品是在A的直播间里面加锁了,那么现在来了一个102商品在B直播间,是不是也阻塞住了,这样是不应该的,关键现在是不同的商品,现在因为一个商品会导致别的商品阻塞住。这个时候就可以使用分布式锁。把这个锁替换成分布式锁就得到了解决。分布式锁就是解决多节点间的并发问题。而且重建只需要建一次。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果我们在开发的时候,开发着开发着发现里面的代码开始比较多了,且里面还有重复的,这个时候我们就可以重构一下:

在这里插入图片描述
在这里插入图片描述

这个时候仍然会有一个小问题

如果这个里面的数据是不存在的,然后里面放的是空缓存,但是我们这个时候返回的是null,再走到上面就会又去查数据库,这个时候是没必要的,因此需要区分一下。

在这里插入图片描述
在这里插入图片描述

5. 缓存数据库双写不一致问题

下面这两种情况全部都是缓存数据库双写不一致问题:

在这里插入图片描述

在这里插入图片描述

删除缓存同样也会有这样的问题

在这里插入图片描述

分布式锁就可以解决这个问题,

在这里插入图片描述

意思就是在一个线程操作的时候加上分布式锁即可

在这里插入图片描述

现在开始加锁

在这里插入图片描述

在更新、创建的地方都应该加这样的分布式锁,直接复制过去即可。

其实看着这样写了很多代码,会觉得在执行的时候效率很低。其实不是的,因为这个解决的是小概率事件,其中90%还是在缓存了就会读到。

其实在一些电商平台,基本上95%还是读操作,只有你加入购物车了或者是下单了才会涉及到写操作。也就是电商平台就是读多写少的问题,针对这个问题使用分布式锁去解决问题,可以借助分布式的读写锁优化,这种情况下可以借助分布式的读写锁redisson优化。读就加读锁,写就加写锁,因为写写会冲突,读写会冲突,但是读读是不会有冲突的。

如果现在大家伙都在读,在加读锁的时候是互相不冲突的,大家都可以进行读。也就是并行执行。秒杀之前大家都是读,都去并发执行,效率是很高的,也就那1s时间是有写读或者写写共存的情况。

在这里插入图片描述

  1. 第一句代码使用 Redisson 的 getReadWriteLock() 方法获取了一个名为 LOCK_PRODUCT_UPDATE_PREFIX + productId 的读写锁 productUpdateLock,用于保证对 productId 对应的数据的读写操作是互斥的。
  2. 第二句代码通过 productUpdateLock 的 writeLock() 方法获取了一个写入锁 writeLock,用于保证对 productId 对应的数据的写操作是互斥的。
  3. 第三句代码使用 writeLock 的 lock() 方法获取了写入锁,并阻塞当前线程,直到获取到锁为止。然后,该线程可以执行对 productId 对应数据的写操作。

这把读写锁,这个锁的key必须是一样的。

下面是读锁的底层源码:

在这里插入图片描述

如果第一个线程是写锁,现在来了一个线程,首先判断这个锁的模式,如果是读锁,那就把这个在写锁上加1,如果是写锁你就在这等着。

分布式锁有很多的优化场景,要根据不同的场景使用不同的锁。

下面这块应该使用不了读写锁优化,那么应该怎么来进行优化。

在这里插入图片描述

假如我们知道有99.99%的线程会在1s钟将这个方法里面的所有的步骤执行完,因此这个时候串行就可以转成并行

在这里插入图片描述
就是我等1s时间,如果我还加不上锁我就走了,返回方法。

package com.hs.distributlock.service;

import com.alibaba.fastjson.JSON;
import com.hs.distributlock.entity.ProductEntity;
import com.hs.distributlock.mapper.ProductMapper;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 高并发缓存架构
 * @Author 胡尚
 * @Date: 2023/3/25 20:10
 */
@Service
public class ProductService {

    @Autowired
    StringRedisTemplate redisTemplate;


    @Autowired
    Redisson redisson;

    @Autowired
    ProductMapper productMapper;

    /**
     * 缓存穿透默认值
     */
    public static final String PRODUCT_PENETRATE_DEFAULT = "{}";

    /**
     * 突发性热点缓存重建时加的锁
     */
    public static final String LOCK_PRODUCT_HOT_CACHE_CREATE_PREFIX = "lock:product:hot_cache_create:";

    /**
     * 突发性热点缓存重建时加的锁
     */
    public static final String LOCK_CACHE_DB_UNLIKE_PREFIX = "lock:cache_db_unlike:";

    public void updateProduct(ProductEntity entity){
        
        // 解决缓存与数据库双写 数据不一致问题 而加写锁
        RReadWriteLock readWriteLock = redisson.getReadWriteLock(LOCK_CACHE_DB_UNLIKE_PREFIX + entity.getId());
        RLock wLock = readWriteLock.writeLock();
        wLock.lock();
        try {
            // 更新DB 更新缓存
            productMapper.update(entity);
            String json = JSON.toJSONString(entity);
            redisTemplate.opsForValue().set("product:id:" + entity.getId(), json, 12*60*60+getRandomTime(), TimeUnit.SECONDS);
        }finally {
            wLock.unlock();
        }
    }



    public void insertProduct(ProductEntity entity){
        // 解决缓存与数据库双写 数据不一致问题 而加写锁
        RReadWriteLock readWriteLock = redisson.getReadWriteLock(LOCK_CACHE_DB_UNLIKE_PREFIX + entity.getId());
        RLock wLock = readWriteLock.writeLock();
        wLock.lock();
        try {
            // 更新DB 更新缓存
            productMapper.insert(entity);
            String json = JSON.toJSONString(entity);
            redisTemplate.opsForValue().set("product:id:" + entity.getId(), json, 12*60*60+getRandomTime(), TimeUnit.SECONDS);
        }finally {
            wLock.unlock();
        }
    }



    /**
     * 重点方法,这其中使用了双重检测去查询缓存,还加了读锁去解决缓存和数据库双写导致的数据不一致问题
     */
    public ProductEntity queryProduct(Long id) throws InterruptedException {

        String productKey = "product:id:" + id;

        // 从缓存取数据
        ProductEntity entity = queryCache(productKey);
        if (entity != null){
            return entity;
        }

        // 突发性热点缓存重建问题,避免大量请求直接去请求DB,进而加锁拦截
        RLock lock = redisson.getLock(LOCK_PRODUCT_HOT_CACHE_CREATE_PREFIX + id);
        lock.tryLock(3, 30, TimeUnit.SECONDS);
        try {
            // 第二次验证 从缓存取数据
            entity = queryCache(productKey);
            if (entity != null){
                return entity;
            }

            // 缓存与DB数据双写不一致问题 加锁
            RReadWriteLock readWriteLock = redisson.getReadWriteLock(LOCK_CACHE_DB_UNLIKE_PREFIX + id);
            RLock rLock = readWriteLock.readLock();
            rLock.lock();
            try {
                // 查询数据库 更新缓存
                entity = queryDatabase(productKey, id);
            }finally {
                rLock.unlock();
            }
            
        }finally {
            lock.unlock();
        }
        return entity;
    }

    /**
     * 从缓存中查询
     */
    private ProductEntity queryCache(String key){
        ProductEntity entity = null;
        String json = redisTemplate.opsForValue().get(key);
        if (StringUtils.hasLength(json)){
            // 判断是否为解决缓存穿透而手动存储的值,如果是则直接返回一个新对象,并和前端约定好错误提示
            if (Objects.equals(PRODUCT_PENETRATE_DEFAULT, json)){
                return new ProductEntity();
            }
            entity = JSON.parseObject(json, ProductEntity.class);
            // 延期
            redisTemplate.expire(key, 12*60*60+getRandomTime(), TimeUnit.SECONDS);
        }

        return entity;
    }

    /**
     * 从数据库中查询,如果查询到了就将数据在缓存中保存一份,如果没有查询到则往缓存中存一个默认值来解决缓存击穿问题
     */
    private ProductEntity queryDatabase(String productKey, long id){
        ProductEntity entity = productMapper.get(id);
        // 如果数据库中也没有查询到,那么就往缓存中存一个默认值,去解决缓存击穿问题
        if (entity == null){
            redisTemplate.opsForValue().set(productKey, PRODUCT_PENETRATE_DEFAULT, 60*1000, TimeUnit.SECONDS);
        } else {
            redisTemplate.opsForValue().set(productKey, JSON.toJSONString(entity), 12*60*60+getRandomTime(), TimeUnit.SECONDS);
        }
        return entity;
    }

    private Integer getRandomTime(){
        return new Random().nextInt(5) * 60 * 60;
    }
}

在这段代码中,使用了Redisson提供的分布式锁来解决缓存和数据库双写导致的数据不一致问题。具体来说,使用了Redisson提供的读写锁(RReadWriteLock)来对缓存和数据库进行加锁。

在updateProduct和insertProduct方法中,首先获取了一个写锁(RReadWriteLock.writeLock())wLock,然后使用wLock.lock()方法获取锁并阻塞当前线程,直到获取到锁为止。在获取到锁之后,更新了数据库中的数据,然后更新了缓存中的数据,最后释放锁,以便其他线程能够获取锁并进行操作。

在queryProduct方法中,首先从缓存中查询数据,如果缓存中不存在,则使用Redisson提供的分布式锁(RLock)来解决突发性热点缓存重建问题。具体来说,使用redisson.getLock(LOCK_PRODUCT_HOT_CACHE_CREATE_PREFIX + id)获取一个名为LOCK_PRODUCT_HOT_CACHE_CREATE_PREFIX + id的锁lock,然后使用lock.tryLock(3, 30, TimeUnit.SECONDS)方法获取锁并阻塞当前线程,直到获取到锁为止。在获取到锁之后,再次从缓存中查询数据,如果缓存中不存在,则使用Redisson提供的读写锁(RReadWriteLock)来对缓存和数据库进行加锁。

具体来说,使用redisson.getReadWriteLock(LOCK_CACHE_DB_UNLIKE_PREFIX + id)获取一个名为LOCK_CACHE_DB_UNLIKE_PREFIX + id的读写锁readWriteLock,然后使用readWriteLock.readLock()获取一个读锁rLock,使用rLock.lock()方法获取锁并阻塞当前线程,直到获取到锁为止。在获取到读锁之后,查询数据库并更新缓存中的数据,最后释放读锁,以便其他线程能够获取锁并进行操作。最后,释放热点缓存重建锁,以便其他线程能够获取锁并进行操作。

需要注意的是,获取锁后必须执行对应的解锁操作,以便其他线程能够获取锁并进行操作。在上述代码示例中,使用了try-finally语句块来确保锁的释放。这样,即使在执行操作时抛出异常,也能够保证锁会被正确释放。

6. 一次微博明星热点事件导致系统崩溃原因分析

可能同时上百万的人访问,一个单个节点redis就是再缓存大概能支持10万个,因此redis可能也扛不住,redis扛不住,web请求可能就会报错。

也就是缓存雪崩

针对这种问题我们可以限流。这个即使前端代码层已经有限流,也要在后端也进行限流。万一前端没有限流成功,后端可以。也就是多加一级缓存,也就是多级缓存架构。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

5. 一线大厂高并发缓存架构实战与性能优化 的相关文章

  • Java 将字节转换为二进制安全字符串

    我有一些以字节为单位的数据 我想将它们放入Redis中 但是Redis只接受二进制安全字符串 而我的数据有一些二进制非安全字节 那么如何将这些字节转换为二进制安全字符串以便将它们保存到 Redis 中呢 Base64 对我有用 但它使数据更
  • 2 个具有共享 Redis 依赖的 Helm Chart

    目前 我有 2 个 Helm Charts Chart A 和 Chart B Chart A 和 Chart B 对 Redis 实例具有相同的依赖关系 如Chart yaml file dependencies name redis v
  • Laravel 所有会话 ID 与 Redis 驱动程序

    在我的应用程序中 我希望允许某些用户能够注销除他 她之外的所有其他用户 当会话驱动程序设置为文件时 我已经完成了此功能 但现在我使用 redis 作为会话驱动程序 并且我无法找到任何方法来列出所有当前会话 就像我在文件时所做的那样司机 问题
  • 使用 Celery 通过 Gevent 进行实时、同步的外部 API 查询

    我正在开发一个 Web 应用程序 该应用程序将接收用户的请求 并且必须调用许多外部 API 来编写对该请求的答案 这可以直接从主 Web 线程使用 gevent 之类的东西来扇出请求来完成 或者 我在想 我可以将传入的请求放入队列中 并使用
  • StackExchange.Redis的正确使用方法

    这个想法是使用更少的连接和更好的性能 连接会随时过期吗 对于另一个问题 redis GetDatabase 打开新连接 private static ConnectionMultiplexer redis private static ID
  • Scala 使用的 Redis 客户端库建议

    我正在计划使用 Scala 中的 Redis 实例进行一些工作 并正在寻找有关使用哪些客户端库的建议 理想情况下 如果存在一个好的库 我希望有一个为 Scala 而不是 Java 设计的库 但如果现在这是更好的方法 那么仅使用 Java 客
  • Redis+Docker+Django - 错误 111 连接被拒绝

    我正在尝试使用 Redis 作为使用 Docker Compose 的 Django 项目的 Celery 代理 我无法弄清楚我到底做错了什么 但尽管控制台日志消息告诉我 Redis 正在运行并接受连接 事实上 当我这样做时 docker
  • Amazon Elasticache Redis 集群 - 无法获取端点

    我需要获取 Amazon Elasticache 中 Redis 集群的终端节点 以下代码适用于 Memcached 集群 但不适用于 Redis import com amazonaws auth AWSCredentials impor
  • 如何将“.csv”数据文件导入Redis数据库

    如何将 csv 数据文件导入 Redis 数据库 csv 文件中包含 id 时间 纬度 经度 列 您能否向我建议导入 CSV 文件并能够执行空间查询的最佳方法 这是一个非常广泛的问题 因为我们不知道您想要什么数据结构 您期望什么查询等等 为
  • 在 Spring 4 中干掉通用的 RedisTemplate

    我读到你可以拥有 Autowired从 Spring 4 开始泛型 这太棒了 我有一个摘要RedisService我想参加的课程 Autowired一个通用的 RestTemplate 如下所示 public abstract class
  • 超出 Redis 连接/缓冲区大小限制

    在对我们的应用程序服务器进行压力测试时 我们从 Redis 中得到以下异常 ServiceStack Redis RedisException 无法连接到 redis host 6379 处的 redis 实例 gt System Net
  • 使用环境变量在 redis.conf 中设置动态路径

    我有一个环境变量MY HOME其中有一个目录的路径 home abc 现在 我有一个redis conf文件 我需要像这样设置这个路径 redis conf pidfile MY HOME local var pids redis pid
  • 没有适用于机器人的 Laravel 会话

    我在大型 Laravel 项目和 Redis 存储方面遇到问题 我们将会话存储在 Redis 中 我们已经有 28GB 的 RAM 然而 它的运行速度仍然相对较快 达到了极限 因为我们有来自搜索引擎机器人的大量点击 每天超过 250 000
  • nginx/uwsgi 服务器的持久内存中 Python 对象

    我怀疑这是否可能 但这是问题和提出的解决方案 提出的解决方案的可行性是这个问题的对象 我有一些需要可用于所有请求的 全局数据 我将这些数据保存到 Riak 并使用 Redis 作为缓存层以提高访问速度 目前 数据被分为约 30 个逻辑块 每
  • Redis AOF fsync(始终)与 LSM 树

    我对日志结构化合并树 LSM 树 的理解是 它利用了附加到磁盘非常快 因为它不需要查找 这一事实 只需将更新附加到预写日志并返回到客户端即可 我的理解是 这仍然提供了立即的持久性 同时仍然非常快 我不认为 Redis 使用 LSM 树 它似
  • 具有匹配模式的 ioredis 密钥

    我想用键匹配模式 LOGIN 搜索 Redis 数据库 我在我的应用程序中使用 ioredis 昨天我搜索了整个网络 我得到了一些执行这项工作的选项 如下所示 KEYS 扫描流 Issue import Redis from ioredis
  • 如何高效地将数十亿数据插入Redis?

    我有大约 20 亿个键值对 我想将它们有效地加载到 Redis 中 我目前正在使用 Python 并使用 Pipe 如redis py https redis py readthedocs io en latest redis Redis
  • 执行 SET {Key} 超时,inst: 0,mgr: Inactive,queue: 2, qu=1, qs=1, qc=0, wr=1/1, in=0/0

    我正在尝试使用 StackExchange Redis 客户端将 90 KB pdf 文件保存到 Azure Redis 缓存中 我已将该文件转换为字节数组并尝试使用 stringSet 方法保存它并收到错误 Code byte bytes
  • 如何按键中的值对 Redis 哈希进行排序

    Redis 有没有一种好方法来获取按值排序的哈希中的键 我查看了文档 但没有找到直接的方法 另外有人可以解释一下redis中的排序是如何实现的 以及什么吗 本文档 http redis io commands SORT using hash
  • Flask-SocketIO redis 订阅

    我在用着https github com miguelgrinberg Flask SocketIO https github com miguelgrinberg Flask SocketIO实现 WebSocket 服务器 我需要从另一

随机推荐

  • 提升mysql服务器性能(系统参数与文件系统优化方案)

    加快TCP链接的回收 不应该使用CFQ cfq 完全公平队列 是anicipaory模式的替代品 没有过多的做预测性调度 而是根据给定的进程io优先级 直接来分配操作的顺序 最好使用 防止饥饿 xfs据说比较好 v
  • C# --- Struct and Record

    C Struct and Record Struct Record Struct struct是一种数据类型 和class非常类似 主要有以下的不同 struct是value type class是reference type 因为是val
  • log4j2配置文件

  • 机器学习-线性回归-多元梯度下降法

    目录标题 线性回归 多元线性回归 正规方程 线性回归 我们的回归方程常写成如下形式 h x 0 1 X 代价函数 J 12 i 1m h x i y i 2 看看代价函数到底是在干什么 如图 梯度下降是一个用来求函数最小值的算法 我们将使用
  • Echarts-折线图-设置线条颜色以及线条以下区域显示渐变颜色

    首先 先看折线图效果 1 设置线条颜色 在series中 数组项设置lineStyle属性 lineStyle 设置线条的style等 normal color red 折线线条颜色 红色 2 设置线条上点的颜色 也是图例的颜色 在seri
  • [OpenAirInterface实战-1] :什么是OAI?OAI常见问题解答

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 120490410 目录 前言 什么是软
  • 上拉加载原理

    实现思路 之前写过一篇触底加载 经过一番苦学钻研 优化一下 样式方面 滚动区域是给固定高度 设置 overflow y auto 来实现 接下来看看js方面的实现 其实也很简单 触发的条件是 可视高度 滚动距离 gt 实际高度 例子我会使用
  • 网络工程师学习笔记-------关于T1和E1载波

    关于T和E载波 标准模拟话音信号频率为4KHz 为了对模拟语音进行数字化 必须按至少8KHz的速率采样 采用7Bit进行量化即128级量化 则每个信道的比特率为 8KHz 7Bit 56Kb s 为了每一个这样的低速信道安装一条通信线路是不
  • 机器学习F1值的概念

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一 什么是F1 score 二 计算过程 1 首先定义以下几个概念 2 通过第一步的统计值计算每个类别下的precision和recall 3 通过第二步计算结果计
  • openstack-nova-compute.service起不来

    1 启动服务 2 查看compute nova日志tail var log nova nova compute log 发现身份验证机制AMQPLAIN拒绝登录 3 关闭防火墙 root controller systemctl stop
  • 资讯汇总230217

    230217 22 48 美联储理事鲍曼 美国通胀仍旧太高 美联储理事鲍曼表示 美国通胀仍旧太高 美国当前的经济数据不一致 不同寻常的低失业率是一个好迹象 让通胀回到目标还有很长的路要走 需要继续加息 直到看到更多进展 财联社 230217
  • 西门子PLC如何与多个三菱PLC建立无线通信?

    对一个大型工厂 由于生产线的不断改造 新老流程的不断更新 这些PLC系统往往是由不同的制造商提供的 那么在智慧工厂的实现中 常会遇到不同品牌PLC之间需要进行相互通讯的情况 由于场地和生产能效的原因 在后期的系统改造中 通常需要采用无线的方
  • 构建流式应用—RxJS详解

    最近在 Alloyteam Conf 2016 分享了 使用RxJS构建流式前端应用 会后在线上线下跟大家交流时发现对于 RxJS 的态度呈现出两大类 有用过的都表达了 RxJS 带来的优雅编码体验 未用过的则反馈太难入门 所以 这里将结合
  • Oracle块损坏处理(MOS)

    处理 Oracle 块损坏 文档 ID 1526911 1 适用于 Oracle Database Enterprise Edition 版本 7 0 16 0 到 11 2 0 2 0 发行版 7 0 到 11 2 本文档所含信息适用于所
  • 微信小程序 如何返回上一个页面并实现刷新

    转载地址 https blog csdn net u011088792 article details 87938213 删除或编辑 之后返回 上一级并刷新 var pages getCurrentPages var beforePage
  • R语言实现RMF模型

    RMF模型说明 RMF模型是客户管理中 常被用来衡量客户价值和客户创利能力的重要方法 它主要考量三个指标 最近一次消费 Recency 近期购买的客户倾向于再度购买 消费频率 Frequency 经常购买的客户再次购买概率高 消费金额 Mo
  • 8年测试经验分享 —— 从0铸造测试技术壁垒

    前言 相信所有从事着软件测试或相关工作的同学都会思考一个问题 如何在持续且部分重复的测试活动中有效的进行测试技术积累 这个有趣的问题我先不予回答 我们先谈谈如何有效保证软件质量 作为团队中的质量保证者 需要深刻的意识到 验证系统原有功能是否
  • oracle 12c recover table恢复单表

    在 Oracle 12c 之前 如果误删一张表 常规的方法是 Flashback 闪回或 TSPITR 如果需要恢复的表空间过大 TSPITR 会耗时非常久 而开启 flashback 会消耗磁盘空间 在 12C 中oracle提供一个新功
  • java接口的详解

    文章目录 接口 1 1 接口的概念 1 2 接口语法规则 1 3 接口使用 1 4 接口特性 1 5 实现多个接口 1 6 接口间的继承 1 7 特殊的接口 1 7 1 Comparable接口实现compareTo方法 1 7 2 Com
  • 5. 一线大厂高并发缓存架构实战与性能优化

    分布式缓存技术Redis 1 冷热数据分离 2 缓存设计 2 1 缓存击穿 失效 2 2 缓存穿透 2 3 缓存雪崩 3 大V直播带货导致线上商品系统崩溃原因分析 4 突发性热点缓存重建导致系统压力暴增问题 5 缓存数据库双写不一致问题 6