Elasticsearch的调优思路

news2024/11/18 20:18:48
环境:centos7、elasticsearch-5.6.4

1、性能调优

1.1、Linux参数调优

1.1.1、关闭交换分区

目的是防止内存置换降低性能,将 /etc/fstab 文件中包含 swap 的行注释掉。

#执行命令:注释相关 swap的行
sed -i '/swap/s/^/#/' /etc/fstab

#将 /etc/fstab 文件中所有设置为swap的设备的交换区进行关闭
swapoff -a

1.1.2、磁盘挂载选项

  • noatime:禁止记录访问时间戳,提高文件系统读写性能

  • data=writeback:不记录 data journal,提高文件系统的写入性能

  • barrier=0:barrier 保证journal先于data刷到磁盘,如果关闭了 journal 就没必要开启barrier了

  • nobh:关闭buffer_head,防止内核打断大块数据的IO操作

示例:

mount -o noatime,data=writeback,barrier=0,nobh /dev/sda /es_data

1.1.3、调度算法调整

对于SSD磁盘,采用电梯调度算法。由于SSD提供了更智能的请求调度算法,不需要内核去做多余的调整 (仅供参考)

echo noop > /sys/block/sda/queue/scheduler

1.2、Elasticsearch节点配置

1.2.1、适当调整 buffer 和 bulk 队列长度

适当增大写入buffer和bulk队列长度,可以有效提高写入性能和稳定性。

[root@myblnp elasticsearch-5.6.4]# vim ./config/elasticsearch.yml 

#增大buffer池的大小
indices.memory.index_buffer_size: 15%

#增大bulk隊列的長度
thread_pool.bulk.queue_size: 1024

1.2.2、禁用shard元数据扫描

在规模比较大的集群中,可以防止新建shard时扫描所有shard的元数据,提升shard分配速度。该参数默认是:true

cluster.routing.allocation.disk.include_relocations: false

1.3、Elasticsearch使用方式注意

1.3.1、控制字段的存储选项

Elasticsearch底层是使用Lucene存储数据,主要包括行存(StoreFiled)、列存(DocValues)和倒排索引(InvertIndex)三部分。大多数情况下是没必要同时存储这三部分的,可以通过下面的参数做适当的调整:

1.3.1.1、StoreFiled(行存)

行存里占比最大的是source字段,它控制doc原始数据的存储。在写入数据的时候,elasticsearch会把doc原始数据的整个JSON结构体当做一个string,存储为source字段。查询的时候,可以通过source字段拿到当初写入时的整个JSON结构体。所以如果没有取出整个原始JSON结构体需求的,可以通过以下命令,在mapping中关闭source字段或者只在source字段中存储部分字段,数据查询时仍可通过ES的docvaluefields获取所有字段的值。

注意: 关闭source后, update, updatebyquery, reindex等接口将无法正常使用,所以有update等需求的index不能关闭source。

关闭source字段存储:

PUT my_index
{
    "mappings": {
        "my_type": {
            "_source": {
                "enabled": false
            }
        }
    }
}

允许source字段存储部分字段:

PUT my_index
{
  "mappings": {
    "doc": {
      "_source": {
        "includes": [
          "*.count",
          "meta.*"
        ],
        "excludes": [
          "meta.description",
          "meta.other.*"
        ]
      }
    }
  }
}

1.3.1.2、docvalues 控制列存

ES主要使用列存来支持sorting, aggregations和scripts功能,对于没有上述需求的字段,可以通过下面的命令关闭docvalues,降低存储成本。

PUT my_index
{
    "mappings": {
        "my_type": {
            "properties": {
                "session_id": {
                    "type": "keyword",
                    "doc_values": false
                }
            }
        }
    }
}

1.3.1.3、index 控制倒排索引

ES默认对于所有字段都开启了倒排索引,用于查询。对于没有查询需求的字段,可以通过下面的命令关闭倒排索引。

PUT my_index
{
    "mappings": {
        "my_type": {
            "properties": {
                "session_id": {
                    "type": "keyword",
                    "index": false
                }
            }
        }
    }
}

1.3.1.4、all字段控制

ES的一个特殊的字段,ES把用户写入json的所有字段值拼接成一个字符串后,做分词,然后保存倒排索引,用于支持整个json的全文检索。这种需求适用的场景较少,可以通过下面的命令将all字段关闭,节约存储成本和cpu开销。(ES 6.0+以上的版本不再支持_all字段,不需要设置)

PUT /my_index
{
    "mapping": {
        "my_type": {
            "_all": {
                "enabled": false
            }
        }
    }
}

1.3.1.5、field_names字段控制

该字段用于exists查询,来确认某个doc里面有无一个字段存在。若没有这种需求,可以将其关闭。

PUT /my_index
{
    "mapping": {
        "my_type": {
            "_field_names": {
                "enabled": false
            }
        }
    }
}

1.3.2、开启最佳压缩(弃用)

对于打开了上述_source字段的index,可以通过下面的命令来把lucene适用的压缩算法替换成 DEFLATE,提高数据压缩率。

PUT /my_index/_settings
{
    "index.codec": "best_compression"
}

1.3.3、bulk批量写入

写入数据时尽量使用下面的bulk接口批量写入,提高写入效率。每个bulk请求的doc数量设定区间推荐为1k~1w,具体可根据业务场景选取一个适当的数量。

POST _bulk
{ "index" : { "_index" : "test", "_type" : "type1" } }
{ "field1" : "value1" }
{ "index" : { "_index" : "test", "_type" : "type1" } }
{ "field1" : "value2" }

1.3.4、调整 translog 同步策略

默认情况下,translog的持久化策略是,对于每个写入请求都做一次flush,刷新translog数据到磁盘上。这种频繁的磁盘IO操作是严重影响写入性能的,如果可以接受一定概率的数据丢失(这种硬件故障的概率很小),可以通过下面的命令调整 translog 持久化策略为异步周期性执行,并适当调整translog的刷盘周期。

PUT my_index
{
    "settings": {
        "index": {
            "translog": {
                "sync_interval": "5s",
                "durability": "async"
            }
        }
    }
}

1.3.5、调整 refresh_interval

写入Lucene的数据,并不是实时可搜索的,ES必须通过refresh的过程把内存中的数据转换成Lucene的完整segment后,才可以被搜索。默认情况下,ES每一秒会refresh一次,产生一个新的segment,这样会导致产生的segment较多,从而segment merge较为频繁,系统开销较大。如果对数据的实时可见性要求较低,可以通过下面的命令提高refresh的时间间隔,降低系统开销。

PUT my_index
{
  "settings": {
    "index": {
      "refresh_interval": "30s"
    }
  }
}

1.3.6、merge 并发控制

ES的一个index由多个shard组成,而一个shard其实就是一个Lucene的index,它又由多个segment组成,且Lucene会不断地把一些小的segment合并成一个大的segment,这个过程被称为merge。默认值是Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2)),当节点配置的cpu核数较高时,merge占用的资源可能会偏高,影响集群的性能,可以通过下面的命令调整某个index的merge过程的并发度:

PUT /my_index/_settings
{
  "index.merge.scheduler.max_thread_count": 2
}

1.3.7、写入数据不指定ID,设置自动生成

当用户显示指定id写入数据时,ES会先发起查询来确定index中是否已经有相同id的doc存在,若有则先删除原有doc再写入新doc。这样每次写入时,ES都会耗费一定的资源做查询。如果用户写入数据时不指定ID,ES则通过内部算法产生一个随机的id,并且保证id的唯一性,这样就可以跳过前面查询id的步骤,提高写入效率。 所以,在不需要通过id字段去重、update的使用场景中,写入不指定id可以提升写入速率。基础架构部数据库团队的测试结果显示,无id的数据写入性能可能比有_id的高出近一倍,实际损耗和具体测试场景相关。

# _id
POST _bulk
{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "1" } }
{ "field1" : "value1" }
# _id
POST _bulk
{ "index" : { "_index" : "test", "_type" : "type1" } }
{ "field1" : "value1" }

1.3.8、配置使用 routing

对于数据量较大的index,一般会配置多个shard来分摊压力。这种场景下,一个查询会同时搜索所有的shard,然后再将各个shard的结果合并后,返回给用户。对于高并发的小查询场景,每个分片通常仅抓取极少量数据,此时查询过程中的调度开销远大于实际读取数据的开销,且查询速度取决于最慢的一个分片。

开启routing功能后,ES会将routing相同的数据写入到同一个分片中(也可以是多个,由index.routingpartitionsize参数控制)。如果查询时指定routing,那么ES只会查询routing指向的那个分片,可显著降低调度开销,提升查询效率。 routing的使用方式如下:

#
PUT my_index/my_type/1?routing=user1
{
    "title": "This is a document"
}
#
GET my_index/_search?routing=user1,user2
{
    "query": {
        "match": {
            "title": "document"
        }
    }
}

1.3.9、为string类型的字段选取合适的存储方式

1.3.9.1、设为text 类型字段

存为text类型的字段(string字段默认类型为text):

做分词后存储倒排索引,支持全文检索,可以通过下面几个参数优化其存储方式:

  1. norms:用于在搜索时计算该doc的_score(代表这条数据与搜索条件的相关度),如果不需要评分,可以将其关闭。

  1. indexoptions:控制倒排索引中包括哪些信息(docs、freqs、positions、offsets)。对于不太注重score/highlighting的使用场景,可以设为 docs来降低内存/磁盘资源消耗。

  1. fields: 用于添加子字段。对于有sort和聚合查询需求的场景,可以添加一个keyword子字段以支持这两种功能。

PUT my_index
{
    "mappings": {
        "my_type": {
            "properties": {
                "title": {
                    "type": "text",
                    "norms": false,
                    "index_options": "docs",
                    "fields": {
                        "raw": {
                            "type": "keyword"
                        }
                    }
                }
            }
        }
    }
}

1.3.9.2、设为 keyword 类型的字段

不做分词,不支持全文检索。text分词消耗CPU资源,冗余存储keyword子字段占用存储空间。如果没有全文索引需求,只是要通过整个字段做搜索,可以设置该字段的类型为keyword,提升写入速率,降低存储成本。 设置字段类型的方法有两种:一是创建一个具体的index时,指定字段的类型;二是通过创建template,控制某一类index的字段类型。

# 1. mapping tags keyword
PUT my_index
{
    "mappings": {
        "my_type": {
            "properties": {
                "tags": {
                    "type": "keyword"
                }
            }
        }
    }
}

# 2. templatemy_index*indexstringkeyword
PUT _template/my_template
{
    "order": 0,
    "template": "my_index*",
    "mappings": {
        "_default_": {
            "dynamic_templates": [
                {
                    "strings": {
                        "match_mapping_type": "string",
                        "mapping": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            ]
        }
    },
    "aliases": {}
}

1.3.10、使用 query-bool-filter 代替 query查询

默认情况下,ES通过一定的算法计算返回的每条数据与查询语句的相关度,并通过score字段来表征。但对于非全文索引的使用场景,用户并不care查询结果与查询条件的相关度,只是想精确的查找目标数据。此时,可以通过query-bool-filter组合来让ES不计算score,并且尽可能的缓存filter的结果集,供后续包含相同filter的查询使用,提高查询效率。

#
POST my_index/_search
{
    "query": {
        "term": {
            "user": "Kimchy"
        }
    }
}

# query-bool-filter
POST my_index/_search
{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "user": "Kimchy"
                }
            }
        }
    }
}

1.3.11、设置 index 按日期滚动

写入ES的数据最好通过某种方式做分割,存入不同的index。常见的做法是将数据按模块/功能分类,写入不同的index,然后按照时间去滚动生成index。

这样做的好处是各种数据分开管理不会混淆,也易于提高查询效率。同时index按时间滚动,数据过期时删除整个index,要比一条条删除数据或deletebyquery效率高很多,因为删除整个index是直接删除底层文件,而deletebyquery是查询-标记-删除。

举例说明,假如有[modulea,moduleb]两个模块产生的数据,那么index规划可以是这样的:一类index名称是modulea + {日期},另一类index名称是

module_b+ {日期}。对于名字中的日期,可以在写入数据时自己指定精确的日期,也可以通过ES的ingest pipeline中的index-name-processor实现(会有写入性能损耗)。

# module_a index
- index
PUT module_a@2018_01_01
{
    "settings": {
        "index": {
            "number_of_shards": 3,
            "number_of_replicas": 2
        }
    }
}

PUT module_a@2018_01_02
{
    "settings": {
        "index": {
            "number_of_shards": 3,
            "number_of_replicas": 2
        }
    }
}

GET module_a@*/_search
# module_b index
PUT module_b@2018_01_01
{
    "settings": {
        "index": {
            "number_of_shards": 3,
            "number_of_replicas": 2
        }
    }
}

PUT module_b@2018_01_02
{
    "settings": {
        "index": {
            "number_of_shards": 3,
            "number_of_replicas": 2
        }
    }
}


GET module_b@*/_search

1.3.12、按需控制index的分片数和副本数

分片(shard):一个ES的index由多个shard组成,每个shard承载index的一部分数据。

副本(replica):index也可以设定副本数(numberofreplicas),也就是同一个shard有多少个备份。对于查询压力较大的index,可以考虑提高副本数(numberofreplicas),通过多个副本均摊查询压力。

shard数量(numberofshards):设置过多或过低都会引发一些问题:shard数量过多,则批量写入/查询请求被分割为过多的子写入/查询,导致该index的写入、查询拒绝率上升;对于数据量较大index,当其shard数量过小时,无法充分利用节点资源,造成机器资源利用率不高 或 不均衡,影响写入/查询的效率。

对于每个index的shard数量,可以根据数据总量、写入压力、节点数量等综合考量后设定,然后根据数据增长状态定期检测下shard数量是否合理。推荐方案是:

  1. 对于数据量较小(100GB以下)的index,往往写入压力查询压力相对较低,一般设置3~5个shard,numberofreplicas设置为1即可(也就是一主一从,共两副本) 。

  1. 对于数据量较大(100GB以上)的index:

  1. 一般把单个shard的数据量控制在(20GB~50GB)

  1. 让index压力分摊至多个节点:可通过index.routing.allocation.totalshardsper_node参数,强制限定一个节点上该index的shard数量,让shard尽量分配到不同节点上

  1. 综合考虑整个index的shard数量,如果shard数量(不包括副本)超过50个,就很可能引发拒绝率上升的问题,此时可考虑把该index拆分为多个独立的index,分摊数据量,同时配合routing使用,降低每个查询需要访问的shard数量。

2、稳定性调优

2.1、Linux 参数调优

# 65536(表示单个进程可以打开的最大文件句柄数,即文件数量)
echo "* - nofile 655360" >>/etc/security/limits.conf
#单用户内存地址空间
echo "* - as unlimited" >>/etc/security/limits.conf
#单用户线程数
echo "* - nproc 2056474" >>/etc/security/limits.conf
#单用户文件大小
echo "* - fsize unlimited" >>/etc/security/limits.conf
#单用户锁定内存
echo "* - memlock unlimited" >>/etc/security/limits.conf
# 单进程可以使用的最大map内存区域数量
echo "vm.max_map_count = 655300" >>/etc/sysctl.conf
# TCP 100EShang
#TCP全连接队列参数设置, 这样设置的目的是防止节点数较多(比如超过100)的ES集群中,
#节点异常重启时全连接队列在启动瞬间打满,造成节点hang住,整个集群响应迟滞的情况
echo "net.ipv4.tcp_abort_on_overflow = 1" >>/etc/sysctl.conf
echo "net.core.somaxconn = 2048" >>/etc/sysctl.conf
# tcp alive time
#降低tcp alive time,防止无效链接占用链接数
echo 300 >/proc/sys/net/ipv4/tcp_keepalive_time

2.2、Elasticsearch 节点配置

2.2.1、JVM参数

-Xms和-Xmx设置为相同的值,推荐设置为机器内存的一半左右,剩余一半留给系统cache使用。

  • jvm内存建议不要低于2G,否则有可能因为内存不足导致ES无法正常启动或OOM

  • jvm建议不要超过32G,否则jvm会禁用内存对象指针压缩技术,造成内存浪费

2.2.2、Elasticsearch配置文件

  1. 设置内存熔断参数,防止写入或查询压力过高导致OOM,具体数值可根据使用场景调整。indices.breaker.total.limit: 30% indices.breaker.request.limit: 6% indices.breaker.fielddata.limit: 3%

  1. 调小查询使用的cache,避免cache占用过多的jvm内存,具体数值可根据使用场景调整。indices.queries.cache.count: 500 indices.queries.cache.size: 5%

  1. 单机多节点时,主从shard分配以ip为依据,分配到不同的机器上,避免单机挂掉导致数据丢失。

cluster.routing.allocation.awareness.attributes: ip node.attr.ip: 1.1.1.1

2.3、Elasticsearch 的使用方式

2.3.1、配置主从

ES集群的元信息管理、index的增删操作、节点的加入剔除等集群管理的任务都是由master节点来负责的,master节点定期将最新的集群状态广播至各个节点。所以,master的稳定性对于集群整体的稳定性是至关重要的。当集群的节点数量较大时(比如超过30个节点),集群的管理工作会变得复杂很多。

此时应该创建专有master节点,这些节点只负责集群管理,不存储数据,不承担数据读写压力;其他节点则仅负责数据读写,不负责集群管理的工作。

这样把集群管理和数据的写入/查询分离,互不影响,防止因读写压力过大造成集群整体不稳定。 将专有master节点和数据节点的分离,需要修改ES的配置文件,然后滚动重启各个节点。

# masterconf/elasticsearch.yml
node.master: true
node.data: false
node.ingest: false
#
node.master: false
node.data: true
node.ingest: true

2.3.2、控制 index、shard 总数量

上面提到,ES的元信息由master节点管理,定期同步给各个节点,也就是每个节点都会存储一份。这个元信息主要存储在clusterstate中,如所有node元信息(indices、节点各种统计参数)、所有index/shard的元信息(mapping, location, size)、元数据ingest等。

ES在创建新分片时,要根据现有的分片分布情况指定分片分配策略,从而使各个节点上的分片数基本一致,此过程中就需要深入遍历clusterstate。当集群中的index/shard过多时,clusterstate结构会变得过于复杂,导致遍历clusterstate效率低下,集群响应迟滞。

集群里,创建了4w+个shard,导致新建一个index需要60s+才能完成。 当index/shard数量过多时,可以考虑从以下几方面改进:

  1. 降低数据量较小的index的shard数量

  1. 把一些有关联的index合并成一个index

  1. 数据按某个维度做拆分,写入多个集群

2.3.3、Segment Memory 优化

前面提到,ES底层采用Lucene做存储,而Lucene的一个index又由若干segment组成,每个segment都会建立自己的倒排索引用于数据查询。Lucene为了加速查询,为每个segment的倒排做了一层前缀索引,这个索引在Lucene4.0以后采用的数据结构是FST (Finite State Transducer)。Lucene加载segment的时候将其全量装载到内存中,加快查询速度。这部分内存被称为SegmentMemory, heapGC。

前面提到,为利用JVM的对象指针压缩技术来节约内存,通常建议JVM内存分配不要超过32G。当集群的数据量过大时,SegmentMemory会吃掉大量的堆内存,而JVM内存空间又有限,此时就需要想办法降低SegmentMemory的使用量了,常用方法有下面几个:

  1. 定期删除不使用的index

  1. 对于不常访问的index,可以通过close接口将其关闭,用到时再打开

  1. 通过force_merge接口强制合并segment,降低segment数量

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

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

相关文章

彻底弄清FreeRTOS中的事件组(Event Groups)

​之前已经学过两个任务之间可以利用信号量、队列来通信,任务可以利用这两个机制等待某一个事件发生,但是假如需要等待多个事件发生呢?这就需要用到事件组了。 事件组可以让任务进入阻塞态,等待一个或多个事件的组合发生。当事件…

根据 cadence 设计图学习硬件知识 day02 了解飞腾 X100芯片

1. 飞腾芯片 X100的介绍 飞腾套片X100是一款微处理器的配套芯片,主要功能包括图形图像处理和接口扩展两类。在图形图像处理方面,集成了图形处理加速GPU、视频解码VPU、显示控制接口DisplayPort以及显存控制器;在接口扩展方面,支持…

【矩形面积】

题目来源:https://leetcode.cn/problems/rectangle-area/ 目录 矩形面积 矩形面积 题目介绍 给你 二维 平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形,请你计算并返回两个矩形覆盖的总面积。 每个矩形由其 左下 顶点和 右上 顶点坐标表示&#xf…

数字化转型危与机,20年老厂的升级之路

“投资大、周期长、见效慢”,是每一家企业在考虑数字化战略时,都会纠结的问题。 打江山容易,守江山难 企业在快速扩张的过程中,往往可以不需要过多的考虑细节的问题,跑马圈地的打法会更加有效。 但是市场占有量开始饱…

JS Array数组常用方法

会改变原数组的方法 1、array.push(需要在末尾添加的数据)【给数组末尾添加一个元素】 2、array.unshift(需要在首位添加的数据)【给数组首位添加一个元素】 3、array.pop()【从数组末尾删除元素,不需要传参】 4、array.shift()【从数组首位开始删除元素,不需要传参】 5、arra…

数据处理方法(LFSR)

一、线性反馈移位寄存器(LFSR)编码概述 线性反馈移位寄存器(LFSR):通常由移位寄存器和异或门逻辑组成。其主要应用在: 伪随机数,伪噪声序列,计数器,BIST,数据…

树脂吸附含钴废水的实际案例

三元聚合物-锂电池是指正极材料使用锂、镍、钴、锰三元正极材料的锂电池,锂离子电池的正极材料有很多种,主要有钴酸锂、锰酸锂、镍酸锂、三元材料、磷酸铁锂等。用三元材料作为正极材料的动力锂电池,近年来凭借其容量高、循环稳定性&#xff…

Java笔记一(黑马)

目录 一.标准的javaBean二.反射1.获取class对象的三种方式2.反射获取构造方法3.反射获取成员变量4.反射获取成员方法 三.网络编程TCP Serve/ClientNIO框架Netty 一.标准的javaBean package com.itheima.domain;public class Student {//1.成员变量私有化//2.空参,带…

数据结构-树及相关算法

二叉树 递归算法的关键要明确函数的定义,相信这个定义,而不要跳进递归细节。 写二叉树的算法题,都是基于递归框架的,我们先要搞清楚 root 节点它自己要做什么,然后根据题目要求选择使用前序,中序&#xff0…

colmap使用教程

COLMAP 是具有图形和命令行界面的通用运动结构 (SfM) 和多视图立体 (MVS) 管道。 它为有序和无序图像集的重建提供了广泛的功能。 常见的基于nerf算法均需要colmap来计算位姿 安装colmap: conda install colmap 需要使用python9 step1:准备多视角图…

第十三节 I/O流与文件操作

文件读写 输入输出流 文本文件 一个字节一个字节写 8位十进制最大255 int read() throws IOException 字节 java.io.OutputStream 将十进制数按字节 用文件的类 表达文件 1.txt 相对路径 :工程是同级的 绝对路径C盘下 D 万物皆对象 都能封装成对象…

xss-flash钓鱼配合msf捆绑上线

这里写目录标题 一,后门文件生成与制作二,flash安装钓鱼网站搭建三,监听四,钓鱼 一,后门文件生成与制作 打开kali,查看ip add 查看 ip 地址为 192.168.1.8 输入 msfconsole 1.生成后门 msfvenom -p window…

LeetCode 1026. Maximum Difference Between Node and Ancestor【DFS,BFS,树】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

Direct3D 12——模板——平面镜效果

1.将实物照常渲染到后台缓冲区内(不包括镜子)。注意,此步骤不修改模 板缓冲区。 2.清理模板缓冲区,将其整体置零。 将实物都绘制到后台缓冲区中,并将模板缓冲区清理为0 (用浅灰色来表示)。 绘…

socked编程

socket是什么?套接字是什么? 什么是 socket? socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台…

Motion Planning学习笔记一:配置空间、图、图搜索、图遍历

学习高飞博士的路径规划课程所总结的学习笔记。 目录 1、配置空间(Configuration Space, C-space) 2、图(Graphs) 3、图搜索(Graph Search Basis) 3.1、总体框架 3.2、两种基本的图遍历算法 3.3、启…

漫谈大数据 - HiveSQL总结(二)查询操作

导语:HiveSQL各关键字详解,hive函数大全,类似于个人记录工具书,后续遇到其他的也会继续加进来。 有关hive库表操作请见上篇:漫谈大数据 - HiveSQL总结(一)库表操作_昊昊该干饭了的博客-CSDN博客…

一条SQL如何被MySQL架构中的各个组件操作执行的?

文章目录 1. 单表查询SQL在MySQL架构中的各个组件的执行过程2. SELECT的各个关键字在哪里执行?3. 表关联查询SQL在MySQL架构中的各个组件的执行过程4. LEFT JOIN将过滤条件放在子查询中再关联和放在WHERE子句上有什么区别?5. 聚集索引和全表扫描有什么区…

推动开发者平台本土化,高通加速中国XR内容生态发展

随着VR和AR技术快速发展,产品不断成熟,体验也变得越来越优秀。据悉,Meta Quest系列VR头显出货量超2000万台,基本证明了VR开始在消费类电子产品中占据一席之地。与此同时,近两年AR眼镜也在逐渐升温,成为了创…

day17_异常

今日内容 零、 复习昨日 一、作业 二、异常 三、自定义异常 零、 复习昨日 见晨考,重点是String类的方法 StringBuffer和StringBuiler面试问 日期解析和格式化 int i Integer.parseInt(“111”); 一、作业 略,见答案二、异常 2.1 介绍 异常,就是程序出现的不正常的情况. 2.2…