ES高可用架构涉及常用功能整理

news2024/11/29 2:37:18

ES高可用架构涉及常用功能整理

  • 1. es的高可用系统架构和相关组件
  • 2. es的核心参数
    • 2.1 常规配置
    • 2.2 特殊优化配置
      • 2.2.1 数据分片按ip打散
      • 2.2.2 数据分片机架感知
      • 2.2.3 强制要求数据分片机架感知
      • 2.2.4 写入线程池优化
      • 2.2.5 分片balance优化
      • 2.2.6 限流控制器优化
  • 3. es常用命令
    • 3.1 常用基础命令
    • 3.2 常用运维命令
  • 4. 事务性
    • 4.1 数据写流程
      • 4.1.1 4种类型写操作
      • 4.1.2 正常写入流程
    • 4.2 数据持久化过程
      • 4.2.1 相关概念
        • 4.2.1.1 translog文件
        • 4.2.1.2 segment文件
        • 4.2.1.3 translog和segment的差异
        • 4.2.1.4 flush
        • 4.2.1.5 refresh
        • 4.2.1.6 fsync
      • 4.2.2 持久化流程
    • 4.3 数据读流程
  • 5. 日志复制流程
    • 5.1. segment文件解析
    • 5.2. es的日志复制流程
    • 5.3. es的日志清理机制
      • 5.3.1 segment合并
      • 5.3.2 translong清理
  • 6. 疑问和思考
    • 6.1 es的flush过程和linux的cache刷盘有什么区别和联系?
    • 6.2 配置按照ip打散
    • 6.3 配置机架感知的参考配置
  • 7. 参考文档

探讨es的系统架构以及以及整体常用的命令和系统分析,本文主要探讨高可用版本的es集群,并基于日常工作中的沉淀进行思考和整理。更多关于分布式系统的架构思考请参考文档关于常见分布式组件高可用设计原理的理解和思考


1. es的高可用系统架构和相关组件

es面对的使用场景是,大量数据的生产和消费,是面对大数据的消息中间件。这么巨大的业务体量,难以通过一台机器完成所有的数据写入、存储和请求,因此需要进行数据的分片,采用 分片模式 进行数据拆分,从而降低单台机器的压力,并能够提供大量的集群扩展能力。

按照 分片模式 的架构模式,在架构上需要拆分2种类型的角色

  • 具备全局视角的元数据保存组件或者角色
  • 实际的worker节点,具体负责业务的数据写入、存储和读写请求

在es的系统架构中,全局视角 并没有拆分出一个单独的组件进行完成,而是复用es进程,通过es节点内部进行选主选择出Master主节点,负责全局的元数据存储和数据视角,将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等,维护分片在节点间的分配关系
在这里插入图片描述
相关核心的组件和角色作用如下

组件部署模式组件作用备注
Master多节点部署存储集群的元数据,具体集群数据的全局视角主要职责是和集群操作相关的内容,例如创建或删除索引、跟踪哪些节点是集群的一部分,并决定哪些分片分配给相关的节点。通过Raft协议选主
Data多节点部署它负责接收、存储和管理数据接收和存储消息数据,接收来自客户端写入的数据,并将这些消息存储在自己的磁盘上。 数据节点也区分多种角色,比如热节点、冷节点等
Ingest多节点部署执行由预处理管道组成的预处理任务将数据进行清洗、集成、转换等预处理,从而提升数据的查询性能

注:客户端写入索引数据时,并不需要通过Master协调,而是ES接受到请求的节点协调,请求转发到数据Primary分片所在节点

2. es的核心参数

2.1 常规配置

elasticsearch.yml

path.data: /data1/1687270572000005409/es/data
# # 尽可能按照标签打散,但是如果机器不满足标签要求,也不强制打散,可以配置多个,如rack,ip
cluster.routing.allocation.awareness.attributes: ip
# node的自定义属性,从而给机器打上标签,通过标签将索引、分片打散在不同的机器上
node.attr.ip: xx
node.attr.rack: rack_1
node.attr.temperature: hot
# 默认发现的master节点列表,如果空集群会通过这个配置发现其他的master节点并通信,完成选主
discovery.zen.ping.unicast.hosts: ["xx.xx.xx.xx:9300", "xx.xx.xx.xx:9300", "xx.xx.xx.xx:9300"]
# 设置在选举 Master 节点时需要参与的最少的候选主节点数,默认为 1。
# 如果使用默认值,则当网络不稳定时有可能会出现脑裂。合理的数值为(n/2)+1
discovery.zen.minimum_master_nodes: 2

# 限流器配置,默认30%,通常调整到90%
indices.breaker.total.limit: 90%
indices.memory.index_buffer_size: 15%
indices.queries.cache.count: 500
indices.breaker.fielddata.limit: 20%
indices.breaker.request.limit: 6%
indices.fielddata.cache.size: 15%
indices.queries.cache.size: 5%

# 集群角色配置
node.master: true
node.ingest: true
node.data: true
node.name: 1687270572000005409
# 感知当前节点的磁盘使用率水位
cluster.routing.allocation.disk.watermark.low: 85%
cluster.routing.allocation.disk.watermark.high: 90%
cluster.routing.allocation.disk.watermark.flood_stage: 95%
# 网络配置
network.host: 0.0.0.0
network.publish_host: xx.xx.xx.xx
transport.tcp.port: 9300
http.port: 9200
# 写入线程池的长度,提升写入性能
thread_pool.write.queue_size: 10000
thread_pool.write.queue_size: 10000
thread_pool.search.queue_size: 500

# 提升集群恢复分片的并发度和带宽
cluster.routing.allocation.cluster_concurrent_rebalance: 50
cluster.routing.allocation.node_concurrent_recoveries: 50
cluster.routing.allocation.node_initial_primaries_recoveries: 50
indices.recovery.max_bytes_per_sec: 400mb


# 关闭系统调用过滤器
bootstrap.system_call_filter: false

# 通过集群名称标识、加入集群
cluster.name: "xx"

2.2 特殊优化配置

默认的es配置有不少默认的参数,对于es的分片分配、集群的数据写入、集群容灾恢复性能的参数不足,因此难以发挥最大的效用

2.2.1 数据分片按ip打散

es的相同shard有多副本,但是默认情况下,es在分配分片时,并不强制要求按照ip打散。如下配置可以按照ip打散,能够容忍ip级别的高可用,但是这个配置是try best模式。
如果正常启动的ip数量满足打散要求,对应的副本会主动分配到不同的机器ip上进行打散
如果正常启动的ip数量不满足打散要求,对应的副本会主动分配到的相同机器ip上,尽可能的保证副本正常启动。

# node的自定义属性,从而给机器打上标签,通过标签将索引、分片打散在不同的机器上
cluster.routing.allocation.awareness.attributes: ip
node.attr.ip: xx

也可以调用api生效

2.2.2 数据分片机架感知

如下配置可以按照机架、ip打散,能够容忍机架、ip级别的高可用,但是这个配置是try best模式。
如果rack1、rack2正常启动,对应的副本会主动分配到rack1、rack2上进行打散
如果rack2的机器没有启动,对应的副本会分配到rack1上本正常启动。

# node的自定义属性,从而给机器打上标签,通过标签将索引、分片打散在不同的机器上
cluster.routing.allocation.awareness.attributes: rack,ip
node.attr.ip: xx
node.attr.rack: rack1

2.2.3 强制要求数据分片机架感知

如下配置可以按照机架、ip打散,能够容忍机架、ip级别的高可用,但是这个配置是强制模式。
如果rack1、rack2正常启动,对应的副本会主动分配到rack1、rack2上进行打散
如果rack2的机器没有启动,对应的副本不会进行分配,而是出于unassign状态。

# node的自定义属性,从而给机器打上标签,通过标签将索引、分片打散在不同的机器上
cluster.routing.allocation.awareness.attributes: rack
node.attr.rack: rack1
# 强制要求按照rack1、rack2分配打散
cluster.routing.allocation.awareness.force.rack.values: rack1,rack2

注: 这里没有要求cluster.routing.allocation.awareness.attributes:rack,ip,原因是cluster.routing.allocation.awareness.attributes:rack已经能够保证1个rack只启动1个副本

2.2.4 写入线程池优化

# 写入线程池的长度,提升写入性能
thread_pool.write.queue_size: 10000
thread_pool.write.queue_size: 10000
thread_pool.search.queue_size: 500

可以调用api热生效

curl -XPUT 'http://127.0.0.1:9200/_cluster/settings'   -H 'Content-Type: application/json' -d '{
  "persistent": {
    "thread_pool.write.queue_size": 10000,
    "thread_pool.write.queue_size": 10000,
    "thread_pool.search.queue_size": 500
  }
}'

2.2.5 分片balance优化

# 提升集群恢复分片的并发度和带宽,默认配置是2
cluster.routing.allocation.cluster_concurrent_rebalance: 50
cluster.routing.allocation.node_concurrent_recoveries: 50
cluster.routing.allocation.node_initial_primaries_recoveries: 50
indices.recovery.max_bytes_per_sec: 400mb

可以调用api热生效

curl -XPUT 'http://127.0.0.1:9200/_cluster/settings'   -H 'Content-Type: application/json' -d '{
  "persistent": {
    "cluster.routing.allocation.cluster_concurrent_rebalance": "50",
    "cluster.routing.allocation.node_concurrent_recoveries": "50",
    "cluster.routing.allocation.node_initial_primaries_recoveries": "50",
    "indices.recovery.max_bytes_per_sec": "100mb"
  }
}'

2.2.6 限流控制器优化

indices.breaker.total.limit: 90%
curl -XPUT 'http://127.0.0.1:9200/_cluster/settings'   -H 'Content-Type: application/json' -d '{
  "persistent": {
    "indices.breaker.total.limit": "90%"
  }
}'

3. es常用命令

3.1 常用基础命令

参考文档 ES常用操作和经典case整理

3.2 常用运维命令

4. 事务性

4.1 数据写流程

4.1.1 4种类型写操作

操作说明
create创建文档
delete删除文档,ES对文档的删除是懒删除机制,即标记删除
index这里的index是动词,表示创建索引
update文档更新

这几种写操作都会触发es的索引数据写流程

4.1.2 正常写入流程

整体写流程如下
在这里插入图片描述
ES的写入有两种方式

  • 逐个文档写入(index)
  • 多个文档批量写入(bulk)

对于这两种写入方式,ES都会将其转换为bulk写入,写操作一般会经历三种节点:协调节点、主分片所在节点、从分片所在节点。

  1. 客户端发起请求,连接到的NODE1,NODE1可视为协调节点,协调节点接收到请求后,根据算法 shard_num=hash(_routing)%num_primary_shards (_routing 的默认值是文档的 id) 计算出属于分片0,跟根据元数据信息找到分片0的Primary节点NODE3
  2. 将请求转发到分片0的主分片所在的节点NODE3,NODE3完成写入后
  3. 将请求转发给分片0所属的从分片所在的节点NODE1和NODE2,等待所有副本(具体等待多少副本取决于wait_for_active_shards的配置值)完成写入并返回给NODE3 ACK后,NODE3则认为整个写入成功
  4. NODE3将结果反馈给协调节点NODE1,协调节点NODE1再将结果返回客户端

注意: 客户端收到协调节点NODE1的返回结果后,表示数据写入成功,但是并不代表客户端就可以马上查询到这些数据。因为ES返回客户端表示数据写入完成后,在ES还需要进行fresh动作,把ES的缓存事务刷新到操作系统Cache中,才能提供给客户端读取,这个过程跟写过程解耦,refresh的默认周期是1s,所以才称之为近实时数据库

4.2 数据持久化过程

4.2.1 相关概念

在介绍流程之前,有几个概念需要提前介绍(文件类和动作类),才能更好理解整个持久化过程。

4.2.1.1 translog文件

根据官网的介绍,translog又叫事务日志或者传输日志。

所有索引和删除操作都会在es内部索引处理后但在被commit之前写入 translog。如果发生崩溃,当分片恢复时,已确认但尚未包含在上次 Lucene 提交中的最近操作将从 translog 中恢复。因为translog是append操作,触发磁盘的顺序写入,因此能够获取很高的磁盘io性能,所以通过translog能够实现低成本、高效的保证数据不丢失。

需要注意的是,translog的刷盘方式有两种:同步(request)和异步(async),由index.translog.durability参数决定。

  • index.translog.durability: 默认request
    request(默认):fsync并在每次请求后提交。如果发生硬件故障,所有确认的写入都已经提交到磁盘。
    async:fsync 并在后台提交每个 sync_interval`. 如果发生故障,自上次自动提交以来所有确认的写入都将被丢弃。

虽然linux本身也会针对page cache中的数据落盘,但是对于es来说,如果把flush的使命全部交给linux,明显不是一种可控的行为,因此es本身在异步(async)情况下,针对translog落盘,有es的相关方式

  • index.translog.flush_threshold_ops: 执行多少次操作后执行一次flush,生成新的commit,默认无限制
  • index.translog.flush_threshold_size: translog一旦达到最大大小,就会发生flush,生成新的commit (生成commit文件,并删除commit事务前的translog),默认为512mb
  • index.translog.flush_threshold_period: 每隔多长时间执行一次flush操作, 默认是30min:
  • index.translog.sync_interval: 默认5s
    将事务日志fsync写入磁盘并提交的频率,无论写入操作如何。默认为5s. 100ms不允许 小于小于的值

两种方式各有千秋,同步刷盘具备更强数据可靠性保障,但同时带来更高的IO开销,性能更低。异步刷盘牺牲了一定的可靠性保障,但是降低了IO的开销,性能更佳,因此需要根据不同的场景需求选择合适的方式。

注: 在异步(async)模式下,由于translog也只是把数据写入到linux的page cache,并最大5s触发一次刷盘。因此这种模式下,最多可能出现5s数据丢失(机器宕机后恢复)。

4.2.1.2 segment文件

segment是es数据索引分片的真实数据存储文件,记录真实的文档数据,并按照文档排序。每个片段代表了索引中的一个独立部分,并且可以独立地被存储、加载和搜索
在这里插入图片描述

4.2.1.3 translog和segment的差异

segment文件和translog文件最大的差异就是

  • translog只是通过记录更新的事务操作,并不会组织相关的数据结构,因此能够通过append,写入磁盘的性能高,写入的性能几乎跟内存相近!
  • segment文件需要针对数据进行排序和组织相关的数据结构,因此是一个复杂的数据文件,无法通过append写入磁盘,磁盘的读写io相对随机,因此完成一次segment写入要比translog的时间和成本要高很多,甚至可能会可能会达到几十倍!

这也是为什么已经有了segment,还需要费劲设计translog的原因!

4.2.1.4 flush

在ES中,当写入一个新文档时,进行数据commit时

  • 首先被写入到ES内存的索引缓存中,并写入translog,此时这个数据还不能被查询
  • 将ES内存中的索引缓存定期刷新到Linux的Page Cache,生成segment(此时只是在Linux的Page Cache中,并没有持久化到磁盘中),默认刷新周期是1s,此时数据能够被客户端查询
  • 完成refresh后,对应在ES内存中的索引缓存会被清空回收

es 默认每隔 30 分钟或者操作数据量达到 512mb ,会将内存 buffer 的数据全都写入新的 segment 中,内存 buffer 被清空,一个 commit point 被写入磁盘,并将 filesystem cache 中的数据通过 fsync 刷入磁盘,同时清空 translog 日志文件,这个过程叫做 flush;

相关参数

index.translog.flush_threshold_ops: 执行多少次操作后执行一次flush,生成新的commit,默认无限制
index.translog.flush_threshold_size: translog一旦达到最大大小,就会发生flush, (生成commit文件,并删除commit事务前的translog),默认为512mb

此时有一些聪明的读者可能会意识到,数据没有落盘,如果机器宕机,那数据不就丢了吗? 是的。这条链路是可能会丢数据的,而且丢失的时间长达30min,这是不能接受的。为了弥补这个缺陷,translog的设计就尤为重要。

4.2.1.5 refresh

refresh是将es中的索引缓存周期性的写入到Liunx的Page Cache的过程,默认周期是1s

设计refresh,为了合并数据写入操作,统一refresh到磁盘生成segment文件能够极大的提升ES的数据写入能力。通过1s的近实时(数据可查询延迟了1s)作为代价换取强大的数据写入能力。事实上,ES会默认定期30min,主动触发commit,将Linux Page Cache中的数据刷新大磁盘中。

1s的相关配置是每个索引的默认配置,但是也可以更改,以索引作为修改单元

curl -XPUT -H "Content-Type: application/json" http://localhost:9200/$index/_settings -d '{
    "refresh_interval": "1s"
}'

所以translog的重要度就体现出来了, 由于在写入数据时,分为2条链路

  • 1条是写入ES内存进行索引缓存,并刷新到Linux Page Cache,此时数据可读
  • 1条是写入到translog,如果ES异常,translog不会受到任何影响。如果Linux宕机重启,ES会重新读取加载translog进行数据回放,从而保证了数据不丢失(同步-request模式)或者更小成本的丢失(异步-async模式,最大丢失5s)
4.2.1.6 fsync

fsync 是一个 Unix 系统调用函数, 用来将内存 buffer 中的数据存储到文件系统. 这里作了优化, 是指将 filesystem cache 中的所有 segment 刷新到磁盘的操作;

4.2.2 持久化流程

es是近实时搜索机制,原因就是持久化过程有相关的refresh和flush过程。整体流程如下。
在这里插入图片描述

  1. 数据首先写入内存缓存区和translog日志文件中。当你写一条数据doc的时候,一方面写入到内存缓冲区中,一方面同时写入到Translog日志文件中。
  2. 内存缓存区满了或者每隔1秒(默认1秒),refresh将内存缓存区的数据生成index segment文件并写入文件系统缓存区,此时index segment可被打开以供search查询读取,这样文档就可以被搜索到了(注意,此时文档还没有写到磁盘上);然后清空内存缓存区供后续使用。可见,refresh实现的是文档从内存缓存区移到文件系统缓存区的过程。
  3. 重复上两个步骤,新的segment不断添加到文件系统缓存区,内存缓存区不断被清空,而translog的数据不断增加,随着时间的推移,translog文件会越来越大。
  4. 当translog长度达到一定程度的时候,会触发flush操作,否则默认每隔30分钟也会定时flush,其主要过程:
  • 执行refresh操作将内存缓存区中的数据写入到新的segment并写入文件系统缓存区,然后打开本segment以供search使用,最后再次清空内存缓存区。
  • 一个commit point被写入磁盘,这个commit point中标明所有的index segment。
  • 文件系统中缓存的所有的index segment文件被fsync强制刷到磁盘,当index segment被fsync强制刷到磁盘上以后,就会被打开,供查询使用。
  • translog被清空和删除,创建一个新的translog。

4.3 数据读流程

es的读取流程相对写流程要简单很多。

在这里插入图片描述

  1. 查询可发送到任意节点,接收到某查询的节点会作为该查询的协调节点。
  2. 协调节点解析查询,向对应数据分片分发查询子任务。
  3. 各数据分片检索本地数据并返回协调节点,经汇聚处理后返回用户。

5. 日志复制流程

5.1. segment文件解析

在这里插入图片描述
Segment 直接提供了搜索功能的,ES 的一个 Shard (Lucene Index)中是由大量的 Segment 文件组成的,且每一次 fresh 都会产生一个新的 Segment 文件,这样一来 Segment 文件有大有小,相当碎片化。有一个文件,用来记录所有 Segments 信息,叫做Commit Point。ES 内部则会开启一个线程将小的 Segment 合并(Merge)成大的 Segment,减少碎片化,降低文件打开数,提升 I/O 性能。

segment是不能更改的,那么如何删除或者更新文档?

  • .del文件,文件内记录了在某个segment内某个文档已经被删除。在segment中,被删除的文档依旧是能够被搜索到的,不过在返回搜索结果前,会根据.del把那些已经删除的文档从搜索结果中过滤掉。

  • 当一个文档发生更新时,首先会在.del中声明这个文档已经被删除,同时新的文档会被存放到一个新的segment中。这样在搜索时,虽然新的文档和老的文档都会被匹配到,但是.del会把老的文档过滤掉,返回的结果中只包含更新后的文档。
    在这里插入图片描述

5.2. es的日志复制流程

在这里插入图片描述

  1. 客户端发起请求,连接到的NODE1,NODE1可视为协调节点,协调节点接收到请求后,根据算法 shard_num=hash(_routing)%num_primary_shards (_routing 的默认值是文档的 id) 计算出属于分片0,跟根据元数据信息找到分片0的Primary节点NODE3
  2. 将请求转发到分片0的主分片所在的节点NODE3,NODE3完成写入后
  3. 将请求转发给分片0所属的从分片所在的节点NODE1和NODE2,等待所有副本(具体等待多少副本取决于wait_for_active_shards的配置值)完成写入并返回给NODE3 ACK后,NODE3则认为整个写入成功
  4. NODE3将结果反馈给协调节点NODE1,协调节点NODE1再将结果返回客户端

5.3. es的日志清理机制

5.3.1 segment合并

为什么要进行段合并?

  • 索引段的个数越多,搜索性能越低并且消耗更多的内存。
  • 索引段是不可变的,你并不能物理上从中删除信息。
  • 可以物理上删除document,但只是做了删除标记,物理上并没有删除。
  • 当段合并时,这些被标记为删除的文档并没有被拷贝至新的索引段中,这样,减少了最终的索引段中的 document 数目。

在 ES 后台会有一个线程进行 segment 合并

  • 合并进程选择一小部分大小相似的 segment,并且在后台将它们合并到更大的 segment 中,此合并进程,并不会中断索引和搜索。
  • 新的 segment 被刷新(flush)到了磁盘,同时生成一个新的commit point(记录了新的segment和要被排除的segment是哪些)
  • 老的 segment 被删除

合并segment的相关参数,可以参考 Elasticsearch 性能调优:段合并(Segment merge)

5.3.2 translong清理

很显然,我们不可能让translog无限制的增长下去。事实上,当segment数据完成落盘后,translog已经完成了他的职责,就可以清理了。因此触发清理translog的操作有

  • flush操作,将segment落盘,生成commit,并清理translog,新增的事务写入到新的translog中

导致flush操作的条件有

  • es 默认每隔 30 分钟
  • 操作数据量达到 512mb

相关参数如有

  • index.translog.flush_threshold_ops: 执行多少次操作后执行一次flush,生成新的commit,默认无限制
  • index.translog.flush_threshold_size: translog一旦达到最大大小,就会发生flush,生成新的commit (生成commit文件,并删除commit事务前的translog),默认为512mb
  • index.translog.flush_threshold_period: 每隔多长时间执行一次flush操作, 默认是30min:

6. 疑问和思考

6.1 es的flush过程和linux的cache刷盘有什么区别和联系?

  • linux本身的page cache也能够触发数据刷盘动作,具体可以参考 Linux 内核源码分析-Page Cache 刷脏源码分析 但是这是linux/unix本身的行为,很有可能无法达成es的预期目标。
  • 因此es自己设置了flush的机制,确保能够按照预设的目标进行操作

6.2 配置按照ip打散

# node的自定义属性,从而给机器打上标签,通过标签将索引、分片打散在不同的机器上
cluster.routing.allocation.awareness.attributes: ip
node.attr.ip: xx

6.3 配置机架感知的参考配置

# node的自定义属性,从而给机器打上标签,通过标签将索引、分片打散在不同的机器上
cluster.routing.allocation.awareness.attributes: rack
node.attr.rack: rack1
# 强制要求按照rack1、rack2分配打散
cluster.routing.allocation.awareness.force.rack.values: rack1,rack2

注: 这里没有要求cluster.routing.allocation.awareness.attributes:rack,ip,原因是cluster.routing.allocation.awareness.attributes:rack已经能够保证1个rack只启动1个副本

7. 参考文档

  • Elasticsearch深入:数据持久化过程
  • ES写入过程和写入原理调优及如何保证数据的写一致性

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

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

相关文章

超低价搭建cyberpanel+LiteSpeed企业版web服务器

注意,这里的企业版使用的是官方提供的免费密钥,在密钥激活后有一个月的有效时间,到期后官方会自动续期你的密钥 教学用配置: image1097698 126 KB 优惠链接:雨云 - 新一代云服务提供商 3 这是LiteSpeed(以…

vue3 源码解析(5)— patch 函数源码的实现

什么是 patch 在 vue 中 patch 函数的作用是在渲染的过程中,比较新旧节点的变化,通过打补丁的形式,进行新增、删除、移动或替换操作,此过程避免了大量的 dom 操作,提升了运行的性能。 patch 执行流程 patch 函数整体…

0-MQTT基础使用教程【学习】

文件路径 MQTT基础使用教程1. MQTT1.1 MQTT简介1.1.1 什么是MQTT1.1.2 设计原则1.1.3 应用领域1.2 MQTT协议相关概念1.2.1 MQTT协议实现方式1.2.2 MQTT协议中的方法1.3 消息服务质量QoS1.3.1 消息服务质量QoS三个等级1.3.2 发布与订阅QoS1.4 Topic通配符匹配规则2. EMQX2.1 EMQ…

100183. 最大好子数组和

题目: 给你一个长度为 n 的数组 nums 和一个 正 整数 k 。 如果 nums 的一个子数组中,第一个元素和最后一个元素 差的绝对值恰好 为 k ,我们称这个子数组为 好 的。换句话说,如果子数组 nums[i..j] 满足 |nums[i] - nums[j]| k…

Python基于时间序列分析的大气污染预测的设计与实现,附源码

1 简介 Python基于时间序列分析的大气污染预测的设计与实现 摘要:随着当今社会工业的发展,世界各地的空气质量都下降的非常明显,大气的污染对人们的身体健康会产生极大的危害。所以从20世纪初我国就十分关注空气质量的治理问题,…

【Java】Redis入门

1. Redis入门 1.1 Redis简介 Redis是一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。 官网:https://redis.io 中文网:https://www.redis.net.cn/ key-value结构存储: 主要特点: 基于内…

【Android】使用Termux终端的SSH服务与电脑传输文件

在Android手机上有一个Termux APP,可运行类似 Linux 终端的模拟器,记得之前有讲过用电脑远程控制手机终端命令,那现在,怎样实现电脑与手机直接传输文件呢,且看这篇文章。 文章目录 Termux安装功能ssh服务从远程下载从本…

深度学习入门笔记(六)线性回归模型

本节,我们用线性回归为例子,回顾一些基本概念 6.1 相关性 相关性的取值范围是-1 到 1,越接近 1 或者-1 代表越相关,越接近 0 则越不相关。相关系数大于 0 称为正相关,小于 0 称为负相关。 假如 A 与 B 正相关&#…

[Linux 进程控制(二)] 写时拷贝 - 进程终止

文章目录 1、写时拷贝2、进程终止2.1 进程退出场景2.1.1 退出码2.1.2 错误码错误码 vs 退出码2.1.3 代码异常终止引入 2.2 进程常见退出方法2.2.1 exit函数2.2.2 _exit函数 本片我们主要来讲进程控制,讲之前我们先把写时拷贝理清,然后再开始讲进程控制。…

VMware无法检测到插入的USB设备,虚拟机插拔USB无反应

原本正常使用的VMware虚拟机,在进行了重装软件后,发现虚拟机插拔USB设备都无法检测到,没有任何的反应和提示。 通过一系列的操作发现,在新安装了VMware workstation 软件后,存在一定的概率性会发生VMware虚拟机无法自…

牛客网-------------------------长方体

解题思路: 设棱长为x,y,z;假设已知面积为a,b,c 那么,xya;yzb;xzc; 一式除二式得x/za/b x(a/b)*z 联立xzc 代入得(a/b)z^2c z^2c*b/a z根号下&…

pdf怎么转成高清图?pdf在线转换器推荐分享

在日常的工作或者学习中,有时候会需要将编辑好的pdf转高清图片,这样更方便我们后续使用,那么怎么将pdf转图片(https://www.yasuotu.com/pdftopic)还能保持清晰呢?下面介绍一款pdf转换工具,支持p…

某头部股份制银行基于 Data Fabric 的敏捷数据准备创新实践

【背景】 随着数字化转型的持续深入,某头部股份制银行把“依托数据洞察提升管理和营销的精准度、实现经营与服务的精细化与个性化”作为参与下一阶段数字化业务竞争的核动力。经过多年的探索,该头部股份制银行数字化技术与业务场景的融合逐渐进入了深水…

中科大计网学习记录笔记(三):接入网和物理媒体

前言: 学习视频:中科大郑烇、杨坚全套《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》课程 该视频是B站非常著名的计网学习视频,但相信很多朋友和我一样在听完前面的部分发现信…

《学成在线》微服务实战项目实操笔记系列(P1~P49)【上】

《学成在线》项目实操笔记系列【上】,跟视频的每一P对应,全系列12万字,涵盖详细步骤与问题的解决方案。如果你操作到某一步卡壳,参考这篇,相信会带给你极大启发。同时也欢迎大家提问与讨论,我会尽力帮大家解…

高通android设备themal读取cpu温度

以msm8953的themal分布信息,主要是下图的位置: 这其中 cpu相关的themal的位置有: 读取thermal 温度数据可以通过以下几个步骤: 获取sensor_info rootmsm8953_64:/ # cat /sys/module/msm_thermal/sensor_info tsens:tsens_tz_se…

数据结构 - 线段树

1. 预制值: 构建的数组为,nums:【2, 5, 1, 4, 3】区间和问题,假设求区间 [1,3] 的和 2. 建树 2.1 构建线段树数组 int[] segT new int[4*n](为什么数组大…

Vivado Tri-MAC IP的例化配置(三速以太网IP)

目录 1 Tri-MAC IP使用RGMII接口的例化配置1.1 Data Rate1.2 interface配置1.3 Shared Logic配置1.4 Features 2 配置完成IP例化视图 1 Tri-MAC IP使用RGMII接口的例化配置 在网络设计中,使用的IP核一般为三速以太网IP核,使用时在大多数场景下为配置为三…

【计算机图形学】实验一 DDA算法、Bresenham算法

🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…

【Git】05 分离头指针

文章目录 一、分离头指针二、创建分支三、比较commit内容四、总结 一、分离头指针 正常情况下,在通过git checkout命令切换分支时,在命令后面跟着的是分支名(例如master、temp等)或分支名对应commit的哈希值。 非正常情况下&…