Redis实战--Redis应用过程中出现的热门问题及其解决方案

news2024/9/27 8:25:40

        Redis作为一种高性能的key-value数据库,广泛应用于缓存、消息队列、排行榜等场景。然而,在实际应用中,随着业务规模的不断扩大和访问量的持续增长,缓存系统也面临着诸多挑战,其中最为典型的便是缓存穿透、缓存击穿和缓存雪崩三大问题。本文将深入探讨这三大问题的成因、表现以及相应的解决方案,并结合实际案例和最佳实践,为开发者提供全面的指导。

Redis简单介绍与安装应用-CSDN博客

Redis实战--Windows上的Redis使用及Java代码操作Redis-CSDN博客

Redis实战--Redis的数据持久化与搭建Redis主从复制模式和搭建Redis的哨兵模式-CSDN博客

Redis实战--Redis集群的搭建与使用-CSDN博客

一、缓存穿透

1.1 定义与成因

        缓存穿透(Cache Penetration)是指查询一个数据库中不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。简而言之,就是缓存没有起到应有的作用,用户查询的数据在缓存和数据库中都不存在,而大量的这类查询请求会直接打到数据库上,造成数据库压力增大,甚至可能引发数据库宕机。

缓存穿透的成因主要有以下几点:

  • 恶意攻击:攻击者故意构造大量不存在的数据查询请求,以消耗系统资源,达到攻击目的。
  • 用户误操作:用户在输入查询条件时,由于输入错误或系统错误,导致查询的数据不存在。
  • 数据天然不存在:在某些业务场景下,查询的数据可能确实不存在于数据库中,比如用户查询的商品编号已经下架或从未上架。

1.2 解决方案

1.2.1 缓存空对象或缺省值

        缓存空对象或缺省值是一种常见的解决方案。当查询一个不存在的数据时,将其结果(空对象或缺省值)缓存起来,并设置较短的过期时间。这样,当后续的查询请求再次访问这个不存在的数据时,就可以直接从缓存中获取结果,而无需再去查询数据库。这种方法虽然简单有效,但需要注意以下几点:

  • 合理设置过期时间:过期时间不宜过长,以免无效数据长期占用缓存空间。
  • 注意缓存的空间大小:如果大量不存在的数据被缓存,可能会占用过多的缓存空间,影响其他正常数据的缓存效果。
  • 区分业务场景:在某些业务场景下,即使数据不存在也可能有特殊的处理逻辑,因此需要仔细区分并处理。

实现步骤

  • 当查询数据库返回结果为空时,将空对象或缺省值以特定的 key 缓存起来,并设置较短的过期时间。

优点

  • 实现简单,能够快速部署。
  • 能够有效减少数据库查询压力。

缺点

  • 需要缓存层提供更多的内存空间来存储空值或缺省值。
  • 如果空值或缺省值过多,会浪费缓存资源。

1.2.2 布隆过滤器

        布隆过滤器(Bloom Filter)是一种空间效率很高的概率型数据结构,用于判断一个元素是否在一个集合中。它允许存在一定的误判率,但不存在漏判率。通过将所有可能存在的数据通过哈希函数映射到一个足够大的位数组中,布隆过滤器可以快速地判断一个元素是否可能存在。

        在缓存穿透的场景中,可以在查询缓存之前,先使用布隆过滤器判断数据是否存在。如果布隆过滤器判断数据不存在,则直接返回结果,避免查询数据库。这种方法可以显著降低对数据库的查询压力,但需要注意以下几点:

  • 误判率:布隆过滤器存在误判率,即有可能将不存在的数据误判为存在。因此,在设计时需要合理设置布隆过滤器的参数,以平衡误判率和空间效率。
  • 更新与同步:当数据库中的数据发生变化时(如新增、删除等),需要及时更新布隆过滤器中的位数组,以保证数据的准确性。
  • 适用场景:布隆过滤器适用于数据量大、允许一定误判率的场景。对于对数据准确性要求极高的场景,可能需要考虑其他解决方案。

实现步骤

  1. 将所有可能存在的数据key添加到布隆过滤器中。
  2. 在查询缓存之前,先通过布隆过滤器判断key是否存在。
  3. 如果布隆过滤器判断key不存在,则直接返回空值或错误信息,不再查询缓存和数据库。

优点

  • 过滤效率高,能够显著减少数据库查询压力。
  • 占用空间小,适合大规模数据场景。

缺点:

  • 存在误判率,即可能将存在的数据误判为不存在。
  • 代码维护较为复杂,需要维护布隆过滤器的更新和同步。
  • 删除困难,无法直接从布隆过滤器中删除元素。

1.2.3 监控与限流

        除了上述技术手段外,还可以通过监控和限流来应对缓存穿透。通过监控接口的访问频率和请求参数,可以及时发现并处理恶意攻击或异常请求。同时,设置合理的限流策略(如令牌桶算法、漏桶算法等),可以对请求进行限流和降级处理,以保护系统整体稳定性。

实现方式

  • 使用Redis的INCR命令记录每个IP或用户的访问次数。
  • 当访问次数超过阈值时,进行限流或封禁处理。

优点

  • 能够有效防止恶意攻击。
  • 实现简单,易于部署。

缺点

  • 可能误伤正常用户。
  • 需要根据业务场景合理设置访问次数阈值。

二、缓存击穿

2.1 定义与成因

        缓存击穿(Cache Breakdown)是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。与缓存穿透不同的是,缓存击穿针对的是某个热点数据的缓存过期或失效问题。

缓存击穿的成因主要有以下几点:

  • 热点数据缓存过期:热点数据的缓存过期后,大量请求同时访问数据库,导致数据库压力增大。
  • 缓存失效策略不当:如果缓存的失效策略设置不当(如统一设置较短的过期时间),可能会导致大量数据同时失效,从而引发缓存击穿。
  • 数据库压力测试不足:在系统设计时,如果没有充分考虑数据库的压力测试,可能会导致在缓存失效后数据库无法承受高并发访问。

2.2 解决方案

2.2.1 设置热点数据永不过期

        对于热点数据,可以设置较长的过期时间或永不过期,以减少缓存失效的概率。这种方法虽然简单,但需要注意以下几点:

  • 数据更新问题:如果热点数据需要频繁更新,那么永不过期可能会导致数据不一致的问题。因此,需要根据业务场景合理设置过期时间。
  • 缓存空间占用:永不过期的数据会长期占用缓存空间,影响其他数据的缓存效果。因此,需要合理规划缓存空间的使用。

实现步骤

  • 在缓存设置时,对于热点数据,不设置过期时间(物理不过期),或者在数据结构中为每个热点数据项设置一个逻辑过期时间字段。当业务逻辑判断数据需要更新时(如根据数据更新时间戳或其他业务规则),通过异步线程或后台任务来更新数据,并同时更新逻辑过期时间字段。

优点

  • 能够有效避免缓存击穿问题。
  • 实现简单,易于维护。

缺点

  • 需要消耗更多的缓存资源。
  • 可能导致缓存数据与实际数据不一致。

2.2.2 使用互斥锁

        在查询数据库前,先使用互斥锁进行加锁,确保只有一个线程能够查询数据库并更新缓存,其他线程则等待或返回默认值。这种方法可以有效避免多个线程同时查询数据库导致的问题,但需要注意以下几点:

  • 锁的性能问题:互斥锁会引入额外的性能开销,特别是在高并发场景下。因此,需要合理选择锁的实现方式和粒度。
  • 死锁问题:在使用互斥锁时,需要注意避免出现死锁的情况。可以通过设置锁的超时时间、使用可重入锁等方式来避免死锁。

实现步骤

  • 在查询数据库前,使用互斥锁对相关操作进行加锁。可以使用编程语言提供的互斥锁机制(如 Java 中的 synchronized 关键字或 ReentrantLock 类)。当一个线程获取到锁后,其他线程将被阻塞。
  • 获取锁的线程查询数据库获取数据,然后将数据更新到缓存中,并释放锁。其他被阻塞的线程在锁释放后,可以重新尝试获取数据,如果缓存中已经有数据,则直接返回;如果缓存中仍然没有数据,则再次尝试获取锁并查询数据库。

优点

  • 思路比较简单。
  • 能够较好地降低后端存储负载,并在一致性上做得比较好。

缺点

  • 如果在查询数据库和重建缓存(key 失效后进行了大量的计算)时间过长,也可能会存在死锁和线程池阻塞的风险。
  • 在高并发情景下吞吐量会大大降低。

2.2.3 分布式锁

        在多机部署的环境中,需要使用分布式锁来控制缓存的更新。分布式锁可以保证在多台服务器之间同步锁的状态,从而避免多个线程或进程同时查询数据库导致的问题。Redisson等分布式锁工具提供了丰富的功能和良好的性能表现,是实现分布式锁的一种常用方式。

实现步骤

  1. 使用Redis的SETNX或Redisson等分布式锁实现方式。
  2. 在查询数据库之前,先尝试获取锁。
  3. 如果获取到锁,则查询数据库并更新缓存;如果未获取到锁,则等待一段时间后重试或返回空值。

优点

  • 能够有效避免缓存击穿问题。
  • 适用于高并发场景。

缺点

  • 增加了系统的复杂性和延迟。
  • 需要合理设置锁的过期时间和重试机制。

三、缓存雪崩

3.1 定义与成因

缓存雪崩(Cache Avalanche)是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿是一个热点key过期,而缓存雪崩则是大量的key同时过期。当大量缓存数据在同一时间失效时,如果有大量请求访问这些数据,那么这些请求就会直接打到数据库上,导致数据库压力瞬间增大,甚至可能引发数据库宕机。

缓存雪崩的成因主要有以下几点:

  • 缓存过期时间设置不当:如果大量缓存数据的过期时间设置得过于集中(如统一设置为某个时间点的整点过期),就可能导致缓存雪崩。
  • 缓存数据依赖性强:在某些业务场景中,缓存数据之间存在较强的依赖性。当某个关键数据失效时,可能会引发一系列相关数据的失效和重新加载。
  • 数据库压力大:在缓存失效后,如果数据库无法承受高并发访问的压力,就可能导致数据库宕机或性能下降。

3.2 解决方案

3.2.1 数据预热

在系统上线前或低峰期,预先将热点数据加载到缓存中,避免在系统启动时或高峰期大量请求直接打到数据库。数据预热可以显著减少缓存失效后对数据库的访问压力,提高系统的整体性能。

实现步骤

  • 在系统上线前或低峰期,分析业务数据的访问频率和重要性,确定需要预热的热点数据。这些数据通常是在高并发情况下经常被访问的数据,如首页展示数据、热门商品信息等。
  • 将确定的热点数据从数据库中加载出来,并存储到缓存中。可以使用批量加载的方式提高效率,例如使用数据库的查询语句一次性获取多条数据,然后将这些数据批量存储到缓存中。

优点

  • 提前加载数据到缓存,避免在高并发时大量请求直接访问数据库。

缺点

  • 需要手动触发和管理,对于动态数据可能不太适用。

3.2.2 随机过期时间

在设置缓存过期时间时,为不同的key设置不同的过期时间,避免大量key同时过期。可以通过在固定过期时间的基础上加上一个随机时间差来实现这一点。例如,可以将缓存的过期时间设置为“固定时间 + 随机秒数”的形式。这样可以有效分散缓存失效的时间点,降低缓存雪崩的风险。

优点

  • 有效分散缓存失效的时间点,降低缓存雪崩的风险。

缺点

  • 如果随机范围过大,可能会影响缓存数据的时效性。

3.2.3 熔断降级

在缓存失效或数据库压力过大时,使用熔断降级策略来保护系统整体稳定性。熔断降级可以在系统面临过载风险时自动触发,通过暂时停止缓存服务或返回降级信息等方式来减少对数据库的访问压力。同时,还可以根据系统的负载情况动态调整熔断降级的阈值和恢复策略。

实现步骤

  • 根据系统的性能和业务需求,设置熔断降级的阈值和策略。阈值可以包括数据库的负载指标(如每秒查询次数、响应时间等)和缓存的相关指标(如命中率、过期率等)。策略可以包括停止缓存服务、返回降级信息(如默认值、提示信息等)、限制请求流量等。
  • 实时监控系统的性能指标,当达到熔断降级的阈值时,自动触发相应的策略。可以使用监控工具(如 Prometheus、Grafana 等)来实现对系统指标的实时监控。
  • 根据系统的负载情况动态调整熔断降级的阈值和恢复策略。例如,当系统负载降低时,可以适当提高阈值,恢复部分缓存服务或放宽请求流量限制。

优点

  • 保护系统整体稳定性。

缺点

  • 业务功能可能受影响,当触发熔断降级时,可能会停止部分缓存服务或返回不准确的信息,这可能会对业务功能产生一定影响,例如用户可能会看到不准确的页面内容或无法正常使用某些功能。
  • 配置和维护复杂,需要合理设置熔断降级的阈值和恢复工作策略,这需要对系统的性能和业务负载有深入的了解,并且在系统运行过程中可能需要不断调整和优化,增加了配置和维护的复杂性。

3.2.4 监控与预警

建立完善的监控和预警机制是应对缓存雪崩的重要手段之一。通过实时监控缓存和数据库的负载情况、查询频率、响应时间等关键指标,可以及时发现并处理潜在的缓存雪崩风险。同时,还可以设置预警阈值和报警规则,以便在系统出现异常时及时通知相关人员进行处理。

实现步骤

  • 建立完善的监控系统,实时监控缓存和数据库的负载情况、查询频率、响应时间等关键指标。可以使用监控工具(如 Prometheus、Grafana 等)来实现对系统指标的实时监控。
  • 根据系统的性能和业务需求,设置预警阈值和报警规则。阈值可以包括数据库的负载指标(如每秒查询次数、响应时间等)和缓存的相关指标(如命中率、过期率等)。报警规则可以包括邮件通知、短信通知、系统内消息通知等方式,当指标超过阈值时,按照报警规则进行通知。

优点

  • 及时发现风险,通过实时监控缓存和数据库的关键指标,可以快速发现潜在的缓存雪崩风险,为及时采取措施提供依据。
  • 主动预防,设置预警阈值和报警规则后,一旦出现异常情况能及时通知相关人员进行处理,使运维人员能够在问题恶化之前采取措施,起到主动预防的作用。

缺点

  • 资源消耗,监控需要消耗一定的系统资源,包括 CPU、内存和网络带宽等,如果监控的指标过多或频率过高,可能会对系统性能产生一定影响。
  • 依赖人工处理,虽然能够及时发现问题并报警,但最终的处理还是依赖人工操作,如果相关人员未能及时响应报警信息,可能无法有效避免缓存雪崩的发生。

四、综合对比与选择

4.1 方案对比

问题解决方案优点缺点
缓存穿透缓存空对象或缺省值简单快速,减少数据库压力需更多缓存空间,空值过多浪费资源
布隆过滤器过滤效率高,空间小存在误判率,维护复杂,删除困难
监控与限流防止恶意攻击,简单易部署可能误伤用户,需合理设阈值
缓存击穿设置热点数据永不过期简单有效,避免击穿消耗更多缓存,可能数据不一致
使用互斥锁思路简单,降负载保一致性能开销大,可能死锁,高并发吞吐量低
分布式锁有效避免击穿,适用于高并发增加复杂性和延迟,需合理设参数
缓存雪崩数据预热提前加载数据,减少数据库压力需手动触发管理,不适用于动态数据
随机过期时间分散失效时间点,降低风险随机范围过大可能影响时效性
熔断降级保护系统稳定性业务功能可能受影响,配置和维护复杂
监控与预警及时发现风险,主动预防资源消耗,依赖人工处理

4.2 选择依据

在实际应用中,选择合适的解决方案需要综合考虑多个因素:

  • 业务场景特点
    • 如果业务对数据准确性要求极高,对于缓存穿透问题应避免使用布隆过滤器这种存在误判率的方案;对于缓存击穿问题,如果热点数据更新频繁,则不宜设置永不过期。
    • 如果业务中存在大量热点数据且并发量高,对于缓存击穿问题可能更倾向于分布式锁方案;对于缓存雪崩问题,数据预热和随机过期时间设置可能更为重要。
  • 系统性能要求
    • 如果系统对性能要求极高,对于缓存穿透问题的缓存空对象方案可能需要谨慎使用,因为可能占用过多缓存空间影响性能;对于缓存击穿问题,互斥锁和分布式锁的性能开销需要考虑,可能需要根据并发量等因素进行优化。
    • 对于缓存雪崩问题,熔断降级和监控预警机制可以在一定程度上保障系统性能,避免数据库因大量请求而崩溃。
  • 维护成本和复杂性
    • 布隆过滤器和分布式锁的维护相对复杂,需要考虑是否有足够的技术能力和资源进行维护。如果维护成本过高,对于缓存穿透和缓存击穿问题可能需要选择其他相对简单的方案。
    • 对于缓存雪崩问题,数据预热虽然能有效解决问题,但手动触发和管理的方式可能增加维护成本,需要根据实际情况权衡。

五、总结

        缓存穿透、缓存击穿和缓存雪崩是缓存系统中常见的三大问题。它们不仅会影响系统的性能和稳定性,还可能对业务造成严重的损失。因此,在设计和实现缓存系统时,需要充分考虑这些问题并采取相应的解决方案。本文深入探讨了缓存穿透、缓存击穿和缓存雪崩的成因、表现以及解决方案,并结合实际案例和最佳实践为开发者提供了全面的指导。

参考链接:

缓存穿透、缓存击穿、缓存雪崩的理解和解决方案[通俗易懂]-腾讯云开发者社区-腾讯云

【Redis】缓存击穿、缓存穿透、缓存雪崩原理以及多种解决方案_redis血崩和穿透-CSDN博客

redis布隆过滤器(Bloom)详细使用教程_布隆过滤器使用-CSDN博客

Redis分布式锁-这一篇全了解(Redission实现分布式锁完美方案)-CSDN博客

不用背八股文!一文搞懂redis缓存击穿、穿透、雪崩!-腾讯云开发者社区-腾讯云

【面试】redis缓存穿透、缓存击穿、缓存雪崩区别和解决方案-CSDN博客

缓存穿透、缓存击穿、缓存雪崩区别和解决方案-CSDN博客

一文彻底分清缓存穿透、缓存击穿、缓存雪崩问题(含记忆技巧)-CSDN博客

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

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

相关文章

Ansible集群服务部署案例

案例描述 本案例共讲述了多个节点部署Elk集群日志分析系统,分别在三个节点使用ansible部署Kibana、Logstash以及Elasticsearch服务。 案例准备 1. 规划节点 IP 主机名 节点 192.168.100.25 ansible Ansible节点 192.168.100.35 node1 Elasticsearch/Kiba…

shell用文件管理备份文件路径

从文件中读取文件路径 while IFS read -r s; do:这行代码启动一个 while 循环,逐行读取 001.sh 文件的内容。 IFS:将内部字段分隔符(IFS)设置为空,确保读取整行而不被默认的空格和换行符分隔。这样可以保…

知识管理数据库

知识管理数据库,可以分为几类: 灵感库、卡片库、作品库。 灵感库,通常是素材,想法。 片库,是完整的,成段落的文字。 作品库,是文章、专栏,或者书籍。 这三者的关系,好比…

java通过webhook给飞书发送群消息

现在使用飞书的人越来越多了,飞书有一个最大的好处,可以使用webhook简便的发送群消息。而在工作中,也经常会因为一些运维方面的工作,需要给飞书发送群消息,来实时提醒相关负责人,及时处理工作。 一、先看一下效果吧&a…

【计算机网络】网络层详解

文章目录 一、引言二、IP 基础知识1、IP 地址2、路由3、IP报文4、IP报文的分片与重组 三、IP 属于面向无连接型四、IP协议相关技术1、DNS2、ICMP3、NAT技术4、DHCP 一、引言 TCP/IP的心脏是网络层。这一层主要由 IP 和 ICMP 两个协议组成。网络层的主要作用是“实现终端节点之…

Visual Studio Code下载安装及汉化

官网:https://code.visualstudio.com/ 按照指示一步步操作即可: 汉化:

Stable Diffusion零基础学习

Stable Diffusion学习笔记TOP12 _插件篇之ControlNet功能篇 ControlNet目前支持的10多种预处理器,根据数据检测种类可分为两种类型: 1、功能型:拥有着不同的能力 2、构图型:控制着SD扩散图形的构图规则 Seg语义分割&#xff1a…

2025年第十届智能信息技术国际会议 (ICIIT 2025)即将召开!

第10届智能信息技术国际会议(ICIIT 2025)将于2025年2月20日至23日在越南河内举行。ICIIT系列会议将每年举行,为智能信息技术及相关领域提供互动论坛,除了越南的研究人员外,会议小组还欢迎来自世界各地的有兴趣与该地区…

SpringBoot框架快速入门

1、起步依赖 1.概述 在入门案例中,我们引入了web依赖和test依赖,这两个依赖是SpringBoot中的starter依赖,starter依赖也被称为起步依赖 SpringBoot 在配置上相比Spring要简单许多,其核心在于spring-boot-starter,在使…

Django Web开发基础介绍

概述 Django 是后端Python的 Web 开发框架,主要任务是处理与服务器和数据库相关的事务,模板渲染动态生成网页内容只是其中一部分。 Django 内置了的模板引擎,可以将 HTML 页面与 Python 代码进行分离。模板引擎提供了丰富的模板标签和过滤器…

???Ansible-使用roles

文章目录 一、Ansible的内置的或官方推荐创建的目录及文件介绍roles目录解释1、roles/自定义角色名目录下2、roles/自定义角色名目录/tasks目录下3、roles/自定义角色名目录/handlers目录下4、roles/自定义角色名目录/templates目录下5、roles/自定义项目名目录/files目录下6、…

vscode【实用插件】Notes 便捷做笔记

安装 在 vscode 插件市场的搜索 Notes点 安装 安装成功后,vscode 左侧栏会出现 使用 初次使用 需先选择一个本地目录 重启 vscode 后,得到 切换笔记目录 新建笔记 快捷键为 Alt N 默认会创建 .md 文件 配合插件 Markdown Preview Enhanced 预览 .md…

一文讲清CSS基础之浮动float原理

文章目录 前言1、演示基础代码2、块级元素和行级元素都可以开启浮动,开启后不会独占一行3、块级元素独占一行,如果上方有行级元素则空出行级元素的高度4、开启浮动后元素会脱离文档流,浮动流宽高由内容撑开5、浮动元素的宽高也可以设定6、行内…

华为GaussDB数据库(单机版)在ARM环境下的安装指南

一、软件版本 机器配置:8核16G,CPU: Huawei Kunpeng 920 2.9GHz操作系统:EulerOS 2.8 64bit with ARM数据库版本:GaussDB Kernel 505.1.0 build 44f4fa53 二、部署流程 2.1 新建用户 ① 以omm用户为例,添加一个omm用…

使用C#,MSSQL开发的钢结构加工系统

很久以前的项目,上位机使用C#开发。数据库使用mssql。控制系统选用了三菱PLC,上位机和PLC之间走ModbusTCP通讯协议。 主要功能:读取加工文件(csv格式),导入到数据库,并根据机床刀具规则&#x…

Python | Leetcode Python题解之第438题找到字符串中所有字母异位词

题目: 题解&#xff1a; class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:s_len, p_len len(s), len(p)if s_len < p_len:return []ans []count [0] * 26for i in range(p_len):count[ord(s[i]) - 97] 1count[ord(p[i]) - 97] - 1differ [c !…

Unity 热更新(HybridCLR+Addressable)-创建Addressable资源

三、创建Addressable资源 创建三个文件夹&#xff0c;放Addressable资源&#xff0c;里面对应放程序集&#xff0c;预制体以及场景 拖拽到Addressable Groups对应组中 其中文件名太长&#xff0c;带着路径&#xff0c;可以简化名字 创建一个脚本&#xff0c;对于这个脚本进行一…

在实时语音交互上超过GPT-4o,端到端语音模型Mini-Omni部署

Mini-Omni是清华大学开源的多模态大型语言模型&#xff0c;具备实时语音输入和流式音频输出的能力。 Mini-Omni模型能够一边听、一边说&#xff0c;一边思考&#xff0c;类似于ChatGPT的语言对话模式。 Mini-Omni模型的主要特点是能够直接通过音频模态进行推理&#xff0c;并…

python全栈学习记录(十六)模块与包

模块与包 文章目录 模块与包一、模块1.模块的导入方式2.模块的循环导入问题3.搜索路径与优先级 二、包1.包的使用2.绝对导入与相对导入 三、一般工程的开发目录规范 一、模块 模块是一系列功能的集合体&#xff0c;常见的模块形式&#xff08;自定义模块、第三方模块、内置模块…

重头开始嵌入式第四十三天(硬件 ARM架构 汇编语言)

目录 ARM架构补充 一&#xff0c;程序状态寄存器 二&#xff0c;处理器工作模式 三&#xff0c;异常处理 四&#xff0c;指令流水线 汇编语言 一&#xff0c;什么是汇编 二&#xff0c;汇编怎么编 三&#xff0c;ARM汇编指令集 四&#xff0c;数据处理指令 五&#…