【Elasticsearch】几点核心概念

news2024/11/24 14:22:42

文章目录

    • 核心概念
    • 系统架构
    • 分布式集群
      • 单节点集群
      • 故障转移
      • 水平扩容
      • 应对故障
    • 路由计算(确定哪个主分片)
    • 分片控制(确定哪个节点)
      • 创建个集群
      • 如何查看数据呢?
      • 写流程
      • 读流程
      • 更新流程
    • 分片原理
      • 倒序索引
      • 文档搜索
      • 动态更新索引
      • 持久化变更
    • 文档分析
      • 内置分析器
      • 分析器使用场景
      • 测试分析器
      • IK分词器
      • 自定义分析器
    • 文档处理
      • 文档冲突(为上述的更新流程案例)
      • 乐观并发控制

核心概念

  • 索引

    一个索引就是一个拥有几分相似特征的文档的集合。

    Eg:一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。

    能搜索的数据必须索引,这样的好处是可以提高查询速度

  • 类型

    一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。

    ES6.x之后一个索引只能有一个type

  • 文档

    一个文档是一个可被索引的基础信息单元,也就是一条数据

    文档以 JSON(Javascript Object Notation)格式来表示,而 JSON 是一个到处存在的互联网数据交互格式。

  • 字段

    相当于是数据表的字段,对文档数据根据不同属性进行的分类标识。

  • 映射

    mapping 是处理数据的方式和规则方面做一些限制,如:某个字段的数据类型、默认值、分析器、是否被索引等等。

  • 分片

    应用场景:一个索引可以存储超出单个节点硬件限制的大量数据。

    分片很重要,主要有两方面的原因:

    1)允许你水平分割 / 扩展你的内容容量。

    2)允许你在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量。

  • 副本(复制分片)

    Elasticsearch 允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片(副本)。

    复制分片主要原因:

    • 在分片/节点失败的情况下,提供了高可用;so不能把复制分片与原分片置于用一个节点上
    • 扩展你的搜索量/吞吐量,因为搜索可以在所有的副本上并行运行。

    默认情况下,Elasticsearch 中的每个索引被分片 1 个主分片和 1 个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有 1 个主分片和另外 1 个复制分片(1 个完全拷贝),这样的话每个索引总共就有 2 个分片,我们需要根据索引需要确定分片个数。

  • 分配

    将分片分配给某个节点的过程,包括分配主分片或者副本。如果是副本,还包含从主分片复制数据的过程。这个过程是由 master 节点完成的。

系统架构

说明

  • 这三个节点拥有相同的cluster.name配置,所以他们组成一个集群共同承担数据和负载的压力。
  • 如图所示:node1节点被选举成为主节点,将负责管理集群范围内的所有的变更,文档的增删、节点的增删等
  • 当一个主节点确定后,会将主节点的分片进行备份,也即是保存副本

分布式集群

单节点集群

我们在包含一个空节点的集群内创建名为users的索引,为了演示目的,我们将分配3个主分片和一份副本(每个主分片拥有一个副本分片)

  • 请求方式

    向 ES 服务器发 GET 请求 :http://127.0.0.1:1001/users

  • 请求体

    {
        "settings": {
            "number_of_shards": 3,
            "number_of_replicas": 1  // 这个number_of_replicas参数控制着一个主节点下有几份副本
        }
    }
    
  • 通过 elasticsearch-head 插件查看集群情况

    • node-1(绿色的):表示3个主分片正常
    • unassigned:表示三个副本分片没有被分配到任何节点,原因是:同一个节点既保存原始数据又保存副本毫无意义

故障转移

启动第二台节点机器(拥有同样cluster.name配置的机器)

  • 同一台机器上启动第二个节点,会自动发现集群并加入其中(同一台机器上会自动加入)
  • 不同的机器上启动节点时,为了加入到同一个集群,需要配置一个可连接到的单播主机列表,之所以配置是为了使用单播发现,以防止节点无意中加入集群。
  • 通过 elasticsearch-head 插件查看集群情况

    • node-1节点:表示三个主分片(P1、P2、P3)
    • node-2节点:当第二个节点加入到集群后,3 个副本分片将会分配到这个节点上——每个主分片对应一个副本分片。这意味着当集群内任何一个节点出现问题时,我们的数据都完好无损。所有新近被索引的文档都将会保存在主分片上,然后被并行的复制到对应的副本分片上。这就保证了我们既可以从主分片又可以从副本分片上获得文档。

水平扩容

启动第三台节点机器:为了分散负载而对分片进行重新分配(原分片不全丢在同一个篮子里了)

  • 通过 elasticsearch-head 插件查看集群情况

    • 可以看到node-1、node-2上各有一个分片被迁移到新的node-3节点上,现在每个节点上由开始的三个分片下降到两个分片,即硬件资源被更少的分片所共享,提升性能
  • 副本扩容到6个分片

    即一个原分片被复制2份,更安全,搜索的时候在任一节点上都能找到所有的分片信息,按照下面的节点配置,我们可以在失去 2 个节点的情况下不丢失任何数据。

    当然,如果只是在相同节点数目的集群上增加更多的副本分片并不能提高性能,因为每个分片从节点上获得的资源会变少。

    在运行中的集群上是可以动态调整副本分片数目的,我们可以按需伸缩集群。

    • 请求头

      向 ES 服务器发 PUT 请求 :http://127.0.0.1:1001/users/_settings

    • 请求体

      ```
      {
      "number_of_replicas": 2
      }
      ```
      
      • 通过 elasticsearch-head 插件查看集群情况

应对故障

Node-1(主节点)异常关闭

前置条件:集群必须拥有一个主节点来保证正常工作

  • ES内部处理机制

    1. 选举一个新的主节点: Node-3 。
    2. 将Node-3身上的副本提升至主分片。
  • 通过 elasticsearch-head 插件查看集群情况

  • 关于集群状态说明

    按理说,当前node-3拥有所有的主分片,梦回之前两个节点的情况,相差无二

    但是,之前我们设置了number_of_replicas为2,这时插件就会查询到每个主分片应当对应两份副本,而此时只有一份,so,报yellow状态

  • 重启原主节点

    1. 与当前主分片对比,复制发生修改的数据文件到自己这
    2. master节点不会动,原master节点回来也只能当从节点,与redis类似

路由计算(确定哪个主分片)

都知道,文档要被储存到主分片中,但是主分片有很多啊,Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?

首先这肯定不会是随机的,否则将来要获取文档的时候我们就不知道从何处寻找了。实际上,这个过程是根据下面这个公式决定的:

shard = hash(routing) % 每个主分片的副本分片数量(number_of_primary_shards) -> [0,1,2] -> [P0, P1, P2]

  • routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值。
  • 从公式中不难看出,创建索引的时候,每个主分片的副本分片数量(number_of_primary_shards)这个值一旦确定,就不能改变,一旦改变,之前的路由的值全都无效了,文档就找不到了。
  • 概念澄清:
    • number_of_primary_shards 定义了每个主分片的副本数量
    • number_of_replicas 定义了每个主分片的复制数量。

分片控制(确定哪个节点)

创建个集群

创建一个索引:emps,集群由三个节点组成,有两个主分片,每个主分片拥有两个副本

向 ES 服务器发 PUT 请求 :http://127.0.0.1:1001/emps

  • 请求体

    {
        "settings": {
            "number_of_shards": 2,
            "number_of_replicas": 2
        }
    }
    
  • 通过插件查看集群情况

如何查看数据呢?

这时候我们对集群的任一节点发送查询请求,每个节点都有能力处理这些请求。

每个节点都知道集群中任一文档位置,所以可以直接将请求转发到需要的节点上。

当发送请求的时候, 为了扩展负载,更好的做法是轮询集群中所有的节点。

写流程

  1. 客户端向 Node 2 发送新建、索引或者删除请求。

  2. 节点使用文档的 _id 确定文档属于分片 0 。请求会被转发到 Node 1,因为分片 0 的主分片目前被分配在 Node 1 上。

  3. Node 1 在主分片上面执行请求。如果成功了,它将请求并行转发到 Node 2 的副本分片上。一旦所有的副本分片都报告成功, Node 1 将向协调节点报告成功,协调节点向客户端报告成功。

    关于第三步,提升性能的方式:牺牲数据安全这个代价,即不需要等所有的副本分片都OK,协调节点才向客户端报告OK

    参数含义
    consistencyconsistency,即一致性。在默认设置下,即使仅仅是在试图执行一个操作之前,主分片都会要求必须要有规定数量(quorum)(或者换种说法,也即必须要有大多数)的分片副本处于活跃可用状态,才会去执行 操作(其中分片副本可以是主分片或者副本分片)。这是为了避免在发生网络分区故障(networkpartition)的时候进行写操作,进而导致数据不一致。
    规定数量 即:int( (primary + number of replicas) / 2 ) + 1
    consistency 参数的值可以设为 one (只要主分片状态 ok 就允许执行 写 操作),all (必须要主分片和所有副本分片的状态没问题才允许执行 写 操作),或quorum 。默认值为 quorum,即大多数的分片副本状态没问题就允许执行_写操作。注意,规定数量 的计算公式中 number of replicas 指的是在索引设置中的设定副本分片数,而不是指当前处理活动状态的副本分片数。如果你的索引设置中指定了当前索引拥有三个副本分片,那规定数量的计算结果即:
    int( (primary + 3 replicas) / 2 ) + 1 = 3
    如果此时你只启动两个节点,那么处于活跃状态的分片副本数量就达不到规定数量,也因此您将无法索引和删除任何文档。
    timeout如果没有足够的副本分片会发生什么? Elasticsearch 会等待,希望更多的分片出现。默认情况下,它最多等待 1 分钟。 如果你需要,你可以使用 timeout 参数使它更早终止: 100表示100 毫秒,30s 是 30 秒。

读流程

  1. 客户端向 Node 1 发送获取请求。

  2. 节点使用文档的 _id 来确定文档属于分片 0 。分片 0 的副本分片存在于所有的三个节点上。 在这种情况下,它将请求转发到 Node 2 。

  3. Node 2 将文档返回给 Node 1 ,然后将文档返回给客户端。

更新流程

高并发的情况下,容易出现问题

  1. 客户端向 Node 2 发送更新请求。

  2. 它将请求转发到主分片所在的 Node 1 。

  3. Node 1 从主分片检索文档,修改 _source 字段中的 JSON ,并且尝试重新索引主分片的文档。如果文档已经被另一个进程修改,它会重试步骤 3 ,超过 retry_on_conflict 次后放弃。

  4. 如果 Node 1 成功地更新文档,它将新版本的文档并行转发到 Node 2 的副本分片,重新建立索引。一旦所有副本分片都返回成功, Node 1 向协调节点也返回成功,协调节点向客户端返回成功。

分片原理

分片是 Elasticsearch 最小的工作单元。

倒序索引

传统的数据库每个字段存储单个值,但这对全文检索并不够。文本字段中的每个单词需要被搜索,对数据库意味着需要单个字段有索引多值的能力。最好的支持是一个字段多个值需求的数据结构是倒排索引。

所谓的正向索引,就是搜索引擎会将待搜索的文件都对应一个文件 ID,搜索时将这个ID 和搜索关键字进行对应,形成 K-V 对,然后对关键字进行统计计数

  • 举个例子

    建两个文档

    • The quick brown fox jumped over the lazy dog
    • Quick brown foxes leap over lazy dogs in summer

    搜索quick、brown

    分析:

    两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单相似性算法,那么我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。

  • 引入新问题

    • Quick 和 quick 以独立的词条出现,然而用户可能认为它们是相同的词。
    • fox 和 foxes 非常相似, 就像 dog 和 dogs ;他们有相同的词根。
    • jumped 和 leap, 尽管没有相同的词根,但他们的意思很相近。他们是同义词。

文档搜索

早期的全文检索会为整个文档集合建立一个很大的倒排索引并将其写入到磁盘。 一旦新的索引就绪,旧的就会被其替换,这样最近的变化便可以被检索到。

倒排索引被写入磁盘后是 不可改变的,它永远不会修改。

  • 不变的好处

    • 不需要锁。如果你从来不更新索引,你就不需要担心多进程同时修改数据的问题。
    • 一旦索引被读入内核的文件系统缓存,便会留在哪里,由于其不变性。只要文件系统缓存中还有足够的空间,那么大部分读请求会直接请求内存,而不会命中磁盘。这提供了很大的性能提升。
    • 其它缓存(像 filter 缓存),在索引的生命周期内始终有效。它们不需要在每次数据改变时被重建,因为数据不会变化。
    • 写入单个大的倒排索引允许数据被压缩,减少磁盘 I/O 和 需要被缓存到内存的索引的使用量。
  • 不变的坏处

    主要事实是它是不可变的! 你不能修改它。如果你需要让一个新的文档 可被搜索,你需要重建整个索引。这要么对一个索引所能包含的数据量造成了很大的限制,要么对索引可被更新的频率造成了很大的限制。

动态更新索引

保留不变性的前提下,实现倒排索引的更新

  • 用更多的索引。通过增加新的补充索引来反映新近的修改,而不是直接重写整个倒排索引。每一个倒排索引都会被轮流查询到,从最早的开始查询完后再对结果进行合并。

持久化变更

文档分析

分析包含下面的过程:

  • 将一块文本分成适合于倒排索引的独立的词条
    • 字符过滤器:他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉 HTML,或者将 & 转化成 and。
    • 分词器:一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。
  • 将这些词条统一化为标准格式以提高它们的“可搜索性”,或者 recall
    • Token 过滤器:这个过程可能会改变词条(例如,小写化Quick ),删除词条(例如, 像 a, and, the 等无用词),或者增加词条(例如,像 jump 和 leap 这种同义词)。

内置分析器

下面几种分析其都会针对"Set the shape to semi-transparent by calling set_trans(5)"进行分词

  • 标准分析器

    • 原理

      它根据 Unicode 联盟 定义的 单词边界 划分文本。删除绝大部分标点。最后,将词条小写。

    • 结果

      set, the, shape, to, semi, transparent, by, calling, set_trans, 5

  • 简单分析器

    • 原理

      在任何不是字母的地方分隔文本,将词条小写。

    • 结果

      set, the, shape, to, semi, transparent, by, calling, set, trans

  • 空格分析器

    • 原理

      在空格的地方划分文本。

    • 结果

      Set, the, shape, to, semi-transparent, by, calling, set_trans(5)

  • 语言分析器

    • 原理

      特定语言分析器可用于 很多语言。它们可以考虑指定语言的特点。例如, 英语 分析器附带了一组英语无用词(常用单词,例如 and 或者 the ,它们对相关性没有多少影响),它们会被删除。 由于理解英语语法的规则,这个分词器可以提取英语单词的 词干 。

    • 结果

      set, shape, semi, transpar, call, set_tran, 5

      • transparent->transpar(词根)
      • calling->call(词根)
      • set_trans->set_tran(词根)

分析器使用场景

当我们 索引 一个文档,它的全文域被分析成词条以用来创建倒排索引。

但是,当我们在全文域搜索的时候,我们需要将查询字符串通过相同的分析过程,以保证我们搜索的词条格式与索引中的词条格式一致。

  • 当你查询一个全文域时, 会对查询字符串应用相同的分析器,以产生正确的搜索词条列表
  • 当你查询一个精确值域时,不会分析查询字符串,而是搜索你指定的精确值。

测试分析器

向 ES 服务器发 GET 请求 :http://localhost:9200/_analyze

  • 请求

    {
     "analyzer": "standard",
     "text": "Text to analyze"
    }
    
  • 响应

    {
        "tokens": [
            {
                "token": "text",
                "start_offset": 0,
                "end_offset": 4,
                "type": "<ALPHANUM>",
                "position": 1
            },
            {
                "token": "to",
                "start_offset": 5,
                "end_offset": 7,
                "type": "<ALPHANUM>",
                "position": 2
            },
            {
                "token": "analyze",
                "start_offset": 8,
                "end_offset": 15,
                "type": "<ALPHANUM>",
                "position": 3
            }
        ]
    }
    
    • token 是实际存储到索引中的词条。
    • position 指明词条在原始文本中出现的位置。
    • start_offset 和 end_offset 指明字符在原始字符串中的位置。

IK分词器

ES 的默认分词器无法识别中文中测试、单词这样的词汇,而是简单的将每个字拆完分为一个词。这样的结果显然不符合我们的使用要求,所以我们需要下载 ES 对应版本的中文分词器。

  • 下载

    github下载地址:https://github.com/medcl/elasticsearch-analysis-ik

  • 使用

    将解压后的后的文件夹放入 ES 根目录下的 plugins 目录下,重启 ES 即可使用。

  • 验证

    GET http://localhost:9200/_analyze

    • 请求

      {
          "text":"测试单词",
          "analyzer":"ik_max_word"
      }
      
      • ik_max_word:会将文本做最细粒度的拆分
      • ik_smart:会将文本做最粗粒度的拆分
    • 响应

      {
          "tokens": [
              {
                  "token": "测试",
                  "start_offset": 0,
                  "end_offset": 2,
                  "type": "CN_WORD",
                  "position": 0
              },
              {
                  "token": "单词",
                  "start_offset": 2,
                  "end_offset": 4,
                  "type": "CN_WORD",
                  "position": 1
              }
          ]
      }
      
  • 自定义拓展词汇

    • 进入 ES 根目录中的 plugins 文件夹下的 ik 文件夹,进入 config 目录,创建 custom.dic文件,写入{自定义拓展词汇}。

    • 打开 IKAnalyzer.cfg.xml 文件,将新建的 custom.dic 配置其中,重启 ES 服务器。

自定义分析器

一个分析器就是在一个包里面组合了三种函数的一个包装器, 三种函数按照顺序被执行:

  • 字符过滤器

    字符过滤器 用来 整理 一个尚未被分词的字符串。例如,如果我们的文本是 HTML 格式的,它会包含像 <p> 或者 <div> 这样的 HTML 标签,这些标签是我们不想索引的。我们可以使用 html 清除 字符过滤器 来移除掉所有的 HTML 标签,并且像把 Á 转换为相对应的 Unicode 字符 Á 这样,转换 HTML 实体。一个分析器可能有 0 个或者多个字符过滤器。

  • 分词器

    一个分析器 必须有一个唯一的分词器。 分词器把字符串分解成单个词条或者词汇单元。 标准 分析器里使用的 标准 分词器 把一个字符串根据单词边界分解成单个词条,并且移除掉大部分的标点符号,然而还有其他不同行为的分词器存在。
    例如,关键词分词器完整地输出 接收到的同样的字符串,并不做任何分词。 空格分词器只根据空格分割文本。正则分词器根据匹配正则表达式来分割文本。
    
  • 词单元过滤器

    经过分词,作为结果的词单元流 会按照指定的顺序通过指定的词单元过滤器。词单元过滤器可以修改、添加或者移除词单元。我们已经提到过lowercase和stop词过滤器,但是在Elasticsearch里面还有很多可供选择的词单元过滤器。词干过滤器 把单词遏制为词干。ascii_folding 过滤器移除变音符,把一个像"très"这样的词转换为"tres"。ngram和edge_ngram 词单元过滤器 可以产生适合用于部分匹配或者自动补全的词单元。

  • 自定义的分析器

    创建索引 PUT http://localhost:9200/my_index

    • 请求

      {
          "settings": {
              "analysis": {
                  "char_filter": {
                      "&_to_and": {
                          "type": "mapping",
                          "mappings": [
                              "&=> and "
                          ]
                      }
                  },
                  "filter": {
                      "my_stopwords": {
                          "type": "stop",
                          "stopwords": [
                              "the",
                              "a"
                          ]
                      }
                  },
                  "analyzer": {
                      "my_analyzer": {
                          "type": "custom",
                          "char_filter": [
                              "html_strip",
                              "&_to_and"
                          ],
                          "tokenizer": "standard",
                          "filter": [
                              "lowercase",
                              "my_stopwords"
                          ]
                      }
                  }
              }
          }
      }
      

    使用analyze API来测试这个新的分析器 GET http://127.0.0.1:9200/my_index/_analyze

    • 请求

      {
          "text":"The quick & brown fox",
          "analyzer": "my_analyzer"
      }
      
    • 部分响应

      {
          "tokens": [
              {
                  "token": "quick",
                  "start_offset": 4,
                  "end_offset": 9,
                  "type": "<ALPHANUM>",
                  "position": 1
              },
              {
                  "token": "and",
                  "start_offset": 10,
                  "end_offset": 11,
                  "type": "<ALPHANUM>",
                  "position": 2
              },
              ...
          ]
      }
      

文档处理

文档冲突(为上述的更新流程案例)

当我们使用 index API更新文档,可以一次性读取原始文档,做我们的修改,然后重新索引整个文档。最近的索引请求将获胜:无论最后哪一个文档被索引,都将被唯一存储在Elasticsearch中。如果其他人同时更改这个文档,他们的更改将丢失。

解决方式:加锁

  • 悲观并发控制

    这种方法被关系型数据库广泛使用,它假定有变更冲突可能发生,因此阻塞访问资源以防止冲突。 一个典型的例子是读取一行数据之前先将其锁住,确保只有放置锁的线程能够对这行数据进行修改。

  • 乐观并发控制

    Elasticsearch 中使用的这种方法假定冲突是不可能发生的,并且不会阻塞正在尝试的操作。 然而,如果源数据在读写当中被修改,更新将会失败。应用程序接下来将决定该如何解决冲突。 例如,可以重试更新、使用新的数据、或者将相关情况报告给用户。

乐观并发控制

当我们之前讨论 index ,GET 和 delete 请求时,我们指出每个文档都有一个 _version (版本)号,当文档被修改时版本号递增。 Elasticsearch 使用这个 version 号来确保变更以正确顺序得到执行。如果旧版本的文档在新版本之后到达,它可以被简单的忽略。

我们可以利用 version 号来确保 应用中相互冲突的变更不会导致数据丢失。我们通过指定想要修改文档的 version 号来达到这个目的。 如果该版本不是当前版本号,我们的请求将会失败。

老的版本 es 使用 version,但是新版本不支持了,会报下面的错误,提示我们用 if_seq_no 和 if_primary_term

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

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

相关文章

“Lunar Lobster “现已经可以下载

Canonical近日发布了Ubuntu 23.04&#xff08;Lunar Lobster&#xff09;操作系统&#xff0c;这是对其流行的GNU/Linux发行版的一次重大更新&#xff0c;带来了一些最新和最伟大的技术和开源软件。 被称为 “Lunar Lobster”&#xff0c;Ubuntu 23.04由最新的Linux 6.2内核系列…

【计算机网络】学习笔记:第五章 传输层【王道考研】

基于本人观看学习b站王道计算机网络课程所做的笔记&#xff0c;不做任何获利 仅进行交流分享 特此鸣谢王道考研 若有侵权请联系&#xff0c;立删 如果本篇笔记帮助到了你&#xff0c;还请点赞 关注 支持一下 ♡>&#x16966;<)!! 主页专栏有更多&#xff0c;如有疑问欢迎…

【数据结构与算法】哈希—— 位图 | 布隆过滤器 | 哈希切割

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《数据结构与算法》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 哈希是一种映射思想&#xff0c;这里再讲解两种应用哈希思想的数据结构。 哈希—— 位图 | …

边学边记——数据结构☞堆(包括优先级队列的介绍)

目录 一、堆&#xff08;二叉堆&#xff09; 堆是用来干什么的&#xff1f; 堆是用什么存储结构存储的&#xff1f; 1. 堆的概念 2. 堆的性质 3. 堆的存储方式 下标之间的规则&#xff1a; 4. 堆的基本操作 (1). 向下调整/堆化操作 (2).堆的创建 (3).堆的插入 (4…

2023-04-30:用go语言重写ffmpeg的resampling_audio.c示例,它实现了音频重采样的功能。

2023-04-30&#xff1a;用go语言重写ffmpeg的resampling_audio.c示例&#xff0c;它实现了音频重采样的功能。 答案2023-04-30&#xff1a; resampling_audio.c 是 FFmpeg 中的一个源文件&#xff0c;其主要功能是实现音频重采样。 音频重采样是指将一段音频数据从一个采样率…

duubo+zookeeper

1、Dubbo简介 1. Dubbo是什么&#xff1f; 高性能、轻量级、开源、基于java Dubbo 是阿里集团开源的远程服务调用的分布式框架&#xff08;告别Web Service模式中的WSDL&#xff0c;以服务者与消费者的方式在dubbo上注册&#xff09; 协议和序列化框架都可以插拔是及其鲜明…

【办公类-22-04】周计划系列(4)-生成“周计划”(提取旧docx指定段落的内容,写入EXCLE模板,再次生成新docx)

代码相当复杂&#xff0c;操作很繁琐&#xff0c;自己都要研究半天T_T 文件夹展示 01提取提取新表的已有内容&#xff08;提取大8班、大7班的新版本里面的额内容&#xff09; &#xff08;需要里面的一些反思&#xff0c;用来占位&#xff09; 这里有一份根据新模板用Python批…

spring2:创建和使用

目录 1.创建Spring项目 1.1创建Maven类 1.2添加Spring支持框架 1.3添加启动类 2.存储Bean对象 2.0 spring项目中添加配置文件(第一次) 2.1创建Bean 2.2把Bean注册到容器中 3.获取并使用Bean对象 3.1创建上下文 3.2获取指定Bean对象 getBean()方法 --> 获取什么…

双周赛103(模拟、网格图BFS、树状数组)

文章目录 双周赛103[6406. K 个元素的最大和](https://leetcode.cn/problems/maximum-sum-with-exactly-k-elements/)模拟 [6405. 找到两个数组的前缀公共数组](https://leetcode.cn/problems/find-the-prefix-common-array-of-two-arrays/)模拟 [6403. 网格图中鱼的最大数目](…

Java 基础进阶篇(一)——— static 静态关键字与单例模式

文章目录 一、static 静态关键字1.1 静态成员变量与实例成员变量1.2 静态成员方法与实例成员方法1.3 static 访问注意事项1.4 内存使用情况 二、工具类三、代码块四、单例模式4.1 饿汉单例4.2 懒汉单例 一、static 静态关键字 static&#xff1a;代表静态的意思&#xff0c;可…

【博学谷学习记录】超强总结,用心分享丨人工智能 AI项目 collate_fn函数理解与记录

目录 Dataloader取数据过程使用报错&#xff1a;默认collate_fn处理不同长度的数据自定义collate_fn伪代码示例 Dataloader取数据过程 取出大小等同于batch size的index列表;将列表列表中的index输入到dataset的getitem()函数中&#xff0c;取出该index对应的数据;对每个index…

一种基于坑位模版的分页方案

一. 概述 1.1 业务诉求 想象一个向用户展示数据的下拉列表&#xff0c;数据的来源有多种方式。支持在每一页都按固定的数据源类型及顺序展示。 1.2 业务场景 up主的主页展示带货商品列表 商品来源有多种&#xff1a;up主自选、官方推荐的、根据up主风格AI推荐用户推荐视频列表…

【编辑刷新数据-汽车品牌展示 Objective-C语言】

一、我们这个利用可重用cell展示汽车品牌案例,就说完了,然后我们再给大家说一个什么东西,就是这个刷新数据这个东西, 1.刷新数据这个东西,我们用的就是代理,再把代理相当于是再给大家复习一下,再把代理复习一下,顺便再说一下怎么刷新数据, 2.接下来,要实现一个什么功…

基于UDQ的并网单相逆变器控制【同步参考系下单相并网全桥正弦PWM逆变器闭环控制】(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

day9 实现UDP通信

目录 socket函数拓展 UDP通信实现过程 代码实现 socket函数拓展 send与recv函数&#xff1a; /*用于发送数据*/ ssize_t send(int sockfd, const void *buf, size_t len,int flags);/*用于接收数据*/ ssize_t recv(int sockfd, void *buf, size_t len,int flags);/*前三个…

无敌0代码ESP8266接入homeassistant的新方法,完美解决新版homeassistant无法自定义MQTT设备的问题

记得之前想要在homeassistant中添加MQTT设备只要在配置文件 configuration.yaml 中配置如下代码即可 但是现在这种方法已经行不通&#xff0c;设备也步显示出来&#xff0c;这给很多homeassistant的忠实粉丝带来巨大不便&#xff0c;作为粉丝的一份子&#xff0c;我绝步允许这种…

Python进阶篇(四)-- ICMP Ping服务程序框架

Ping是一个网络应用程序&#xff0c;用于测试某个主机在IP网络中是否可访问。它也用于测试计算机的网卡或测试网络延迟。Ping的实现通常使用ICMP协议。ICMP协议在协议族中的地位如下图所示&#xff1a; 通过本文&#xff0c;你将更好地理解因特网控制报文协议&#xff08;ICMP&…

TCP协议的特性

目录 TCP协议的特性TCP的首部长度2.TCP如何实现可靠传输2.1 确认应答 2.2 超时重传3.建立连接3.1 三次握手3.2 四次挥手 4.滑动窗口5.流量控制6.拥塞控制7.延时应答8.捎带应答9.面向字节流10.异常情况1.进程关闭 /进程崩溃2.主机关机(正常流程关机)3.主机掉电 TCP协议的特性 TC…

预训练模型之BERT、Transformer-XL、XL-Net等

文章目录 预训练模型&#xff08;Pre-trained Models, PTMs&#xff09;前置知识BERTTransformer-XLXLNetTransformer-XL类似工作&#xff08;Scalable Transformer&#xff09;1. 《Scaling Transformer to 1M tokens and beyond with RMT》2. 《》 预训练模型&#xff08;Pre…

IPsec中IKE与ISAKMP过程分析(主模式-消息5和消息6)

IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息1&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息2&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息3&#xff09;_搞搞搞高傲的博客…