Hive-优化(语法优化篇)

列裁剪与分区裁剪

在生产环境中,会面临列很多或者数据量很大时,如果使用select * 或者不指定分区进行全列或者全表扫描时效率很低。Hive在读取数据时,可以只读取查询中所需要的列,忽视其他的列,这样做可以节省读取开销(中间表存储开销和数据整合开销)

1.列裁剪:在查询时只读取需要的列。避免select *

2.分区裁剪:在查询中只读取需要的分区。

遵循一个原则:尽量少的读入数据,尽早地数据收敛!

分组聚合优化

Map端聚合

Hive中未经优化的分组聚合,是通过一个MapReduce Job实现的。Map端负责读取数据,并按照分组字段分区,通过Shuffle,将数据发往Reduce端,各组数据在Reduce端完成最终的聚合运算。

Hive对分组聚合的优化主要围绕着减少Shuffle数据量进行,具体做法是map-side聚合。所谓map-side聚合,在Hive的Map阶段开启预聚合,先在Map阶段预聚合,然后在Reduce阶段进行全局的聚合。map-side聚合能有效减少shuffle的数据量,提高分组聚合运算的效率。

通俗理解:假设有张8000w数据表,聚合后30组数据,有10个map,若是没有开启分组聚合,则会map将8000w条数据传给reduce,开启分组聚合后,就会每个map先进行分组,10个map各有30组,再将这30*10组数据从map传给reduce,这样效率就会大大增加

map-side 聚合相关的参数如下:

--启用map-side聚合,一般默认开启

set hive.map.aggr=true;

 默认为开启状态

--用于检测源表数据是否适合进行map-side聚合。检测的方法是:先对若干条数据进行map-side聚合,若聚合后的条数和聚合前的条数比值小于该值,则认为该表适合进行map-side聚合;否则,认为该表数据不适合进行map-side聚合,后续数据便不再进行map-side聚合。

set hive.map.aggr.hash.min.reduction=0.5;

--用于检测源表是否适合map-side聚合的条数。

set hive.groupby.mapaggr.checkinterval=100000;

默认为0.5和10w条

会先从大的数据表内,先抽取10w数据进行检测,判断看(分组后的数据)/10w是否在0.5以下,若是则会启用map的分组聚合

--map-side聚合所用的hash table,占用map task堆内存的最大比例,若超出该值,则会对hash table进行一次flush。

set hive.map.aggr.hash.force.flush.memory.threshold=0.9;

优化案例

示例SQL

hive (default)> set hive.map.aggr=true/false;

explain

select t1.province_id,count(*) as cnt from ds_hive.ch12_order_detail_orc t1

group by t1.province_id

;

开启分组聚合后,执行时间26s左右  application_1716866155638_175450  

关闭分组聚合后,执行时间在60s左右,效率提升了34s  application_1716866155638_175451

由上图的详细执行过程分析可知,开启map聚合后,map输出--reduce接受的数据是340,而关闭map分组聚合后,map数据--reduce接受的数据是8000w条,传输时间大大影响

大致的运行前后的步骤对比:

Count Distinct 的优化

在Hive中,DISTINCT关键字用于对查询结果进行去重,以返回唯一的值。其主要作用是消除查询结果中的重复记录,使得返回的结果集中每个值只出现一次。

具体而言,当你在Hive中使用SELECT DISTINCT时,系统会对指定的列或表达式进行去重操作。尽管Hive中的DISTINCT关键字对于去重查询是非常有用的,但在某些情况下可能存在一些缺点:性能开销、数据倾斜、内存需求等。

group by 操作的具体实现原理

1.map阶段,将group by后的字段组合作为一个key,如果group by单个字段,那么key就一个。将group by之后要进行的聚合操作字段作为值,如果要进行count,则value是赋1;如要sum另一个字段,那么value就是该字段。

2.shuffle阶段,按照key的不同分发到不同的reducer。注意此时可能因为key分布不均匀而出现数据倾斜的问题。这个问题是我们处理数据倾斜比较常规的查找原因的方法之一,也是我们解决数据倾斜的处理阶段。(当执行过程中,出现其他任务都已完成,持续等待一个reudce过程的时候,就看出现了数据倾斜问题)

3.reduce阶段,如果是count将相同key的值累加,如果是其他操作,按需要的聚合操作,得到结果。

distinct 的具体实现,当执行Distinct操作时,Hive会将操作转化为一个MapReduce作业,并按照指定的列进行分组。在Map阶段,每个Mapper会读取输入数据,并将指定的列作为输出的key,然后,通过Shuffle过程将具有相同key的数据发送到同一个Reducer中。

当distinct一个字段时,这里会将group by的字段和distinct的字段组合在一起作为map输出的key,value设置为1,同时将group by的字段定为分区键,这一步非常重要,这样就可以将GroupBy字段作为reduce的key,在reduce阶段,利用mapreduce的排序,输入天然就是按照组合key排好序的。根据分区键将记录分发到reduce端后,按顺序取出组合键中的distinct字段,这时distinct字段也是排好序的。依次遍历distinct字段,每找到一个不同值,计数器就自增1,即可得到count distinct结果。

count(distinct)全局合操作的时候,即使我们设定了reduce task的具体个数,例如set mapred.reduce.tasks=100;hive最终也只会启动一个reducer。这就造成了所有map端传来的数据都在一个tasks中执行,这唯一的Reduce Task需要Shuffle大量的数据,并且进行排序聚合等处理,这使得这个操作成为整个作业的IO和运算瓶颈。

 针对上述说的问题,我们可以修改对应的sql来进行优化, count+group by 或者sum+group by的方案来优化,在第一阶段选出全部的非重复的字段id,在第二阶段再对这些已消重的id进行计数

重到细粒度的(日),再聚合到粗粒度(省份)

(目前测试结果不能完全验证如上理论,暂放,确定后再更新)

-- count(distinct)

select count(distinct province_id) from ds_hive.ch12_order_detail_orc ;

-- 优化版 count + group by 

select count(product_id)
from (select product_id
from ds_hive.ch12_order_detail_orc
group by product_id
)t;

第一阶段我们可以通过增大Reduce的并发数,并发处理Map输出。在第二阶段,由于id已经消重,因此COUNT(*)操作在Map阶段不需要输出原id数据,只输出一个合并后的计数即可。这样即使第二阶段Hive强制指定一个Reduce Task的时候,极少量的Map输出数据也不会使单一的Reduce Task成为瓶颈。

其实在实际运行时,Hive还对这两阶段的作业做了额外的优化。它将第二个MapReduce作业Map中的Count过程移到了第一个作业的Reduce阶段。这样在第一阶Reduce就可以输出计数值,而不是消重的全部id。这一优化大幅地减少了第一个作业的Reduce输出IO以及第二个作业Map的输入数据量。最终在同样的运行环境下优化后的语句可以说是大大提升了执行效率。

Join优化

Hive拥有多种join算法,包括Common Join,Map Join,Bucket Map Join,Sort Merge Buckt Map Join等,下面对每种join算法做简要说明:

Common Join  (完整进行map-reduce阶段)

Common Join是Hive中最稳定的join算法,其通过一个MapReduce Job完成一个join操作。Map端负责读取join操作所需表的数据,并按照关联字段进行分区,通过Shuffle,将其发送到Reduce端,相同key的数据在Reduce端完成最终的Join操作。

如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。

整个过程包含Map、Shuffle、Reduce阶段

(1)Map阶段

Step1: 读取源表的数据,Map输出时候以Join on条件中的列为key,如果Join有多个关联键,则以这些关联键的组合作为key;

Step2: Map输出的value为join之后所关心的(select或者where中需要用到的)列;同时在value中还会包含表的Tag信息,用于标明此value对应哪个表;

Step3: 按照key进行排序。

(2)Shuffle阶段

根据key的值进行hash,并将key/value按照hash值推送至不同的reduce中,这样确保两个表中相同的key位于同一个reduce中。

(3)Reduce阶段

根据key的值完成join操作,期间通过Tag来识别不同表中的数据。

举个例子:

SELECT t1.stu_id

           ,t1.score

           ,t2.sex

      from ds_hive.ch7_score_info t1

  join ds_hive.ch7_stu_info  t2

        on t1.stu_id=t2.stu_id

;

执行计划如下,完整的common join 会完整的经过map-reduce阶段

 执行过程如下:

JOIN操作涉及合并两个或多个表的数据,以便通过共同的列值将它们关联起来。这样的关联操作在处理大规模数据时可能会面临一些性能挑战,因此有必要进行优化。

性能开销: JOIN操作通常涉及将分布在不同节点上的数据进行合并。在传统的MapReduce执行环境中,这意味着需要进行数据的分发、排序和聚合操作,这些操作都会带来较大的性能开销

Shuffle开销: 在传统的MapReduce中,JOIN操作的Shuffle阶段涉及将相同键的数据合并到一起。这个过程需要大量的网络通信和数据传输,尤其是当数据分布不均匀时。

内存消耗: 处理大规模数据的JOIN操作可能需要大量的内存,特别是在进行排序和合并时。这可能导致内存不足的问题,进而影响性能。

复杂度: JOIN操作可能涉及复杂的计算,特别是在关联多个表或在多列上进行关联时。这增加了查询的复杂性,可能导致较长的执行时间。

Map Join (大表join小表)

Map Join算法可以通过两个只有map阶段的Job完成一个join操作。其适用场景为大表join小表。因为只经map+map阶段,减少了shuffle的处理,reduce的读取和处理过程,从而进行性能优化。若某join操作满足要求,则:

第一个Job会读取小表数据,将其制作为hash table,并上传至Hadoop分布式缓存(本质上是上传至每个执行任务的NodeManager节点本地磁盘)。

第二个Job会先从分布式缓存中读取小表数据,并缓存在Map Task的内存中,然后扫描大表数据,这样在map端即可完成关联操作。

Map Join有两种触发方式,一种是用户在SQL语句中增加hint提示,另外一种是Hive优化器根据参与join表的数据量大小,自动触发。

1)Hint提示

用户可通过如下方式,指定通过map join算法,并且将作为map join中的小表。这种方式已经过时,不推荐使用

hive (default)>

select /*+ mapjoin(ta) */

    ta.id,

    tb.id

from table_a ta

join table_b tb

on ta.id=tb.id

;

2)自动触发

Hive在编译SQL语句阶段,起初所有的join操作均采用Common Join算法实现。

之后在物理优化阶段,Hive会根据每个Common Join任务所需表的大小判断该Common Join任务是否能够转换为Map Join任务,若满足要求,便将Common Join任务自动转换为Map Join任务。

但有些Common Join任务所需的表大小,在SQL的编译阶段是未知的(例如对子查询进行join操作),所以这种Common Join任务是否能转换成Map Join任务在编译阶是无法确定的。

针对这种情况,Hive会在编译阶段生成一个条件任务(Conditional Task),其下会包含一个计划列表,计划列表中包含转换后的Map Join任务以及原有的Common Join任务。最终具体采用哪个计划,是在运行时决定的。大致思路如下图所示:

Map join自动转换的具体判断逻辑如下图所示

参数如下:

--启动Map Join自动转换

set hive.auto.convert.join=true;

--一个Common Join operator转为Map Join operator的判断条件,若该Common Join相关的表中,存在n-1张表的大小总和<=该值,则生成一个Map Join计划,此时可能存在多种n-1张表的组合均满足该条件,则hive会为每种满足条件的组合均生成一个Map Join计划,同时还会保留原有的Common Join计划作为后备(back up)计划,实际运行时,优先执行Map Join计划,若不能执行成功,则启动Common Join后备计划。

set hive.mapjoin.smalltable.filesize=25000000;

--开启无条件转Map Join

set hive.auto.convert.join.noconditionaltask=false;

--无条件转Map Join时的小表之和阈值,若一个Common Join operator相关的表中,存在n-1张表的大小总和<=该值,此时hive便不会再为每种n-1张表的组合均生成Map Join计划,同时也不会保留Common Join作为后备计划。而是只生成一个最优的Map Join计划。

set hive.auto.convert.join.noconditionaltask.size= 20971520;

3)示例SQL

set hive.auto.convert.join=false(true);

explain
SELECT t1.province_id
,count(*) as cnt
from ds_hive.ch12_order_detail_orc t1
join ds_hive.ch12_product_info_orc t3 on t1.province_id=t3.id
group by t1.province_id
;

参数设置为false(未优化):既有map,又有reduce,然后join是在reduce阶段

执行完时间 161s

参数设置为true(优化):第一个map加载本地文件,第二个map进行join

执行时间35s

结论:未开启mapjoin,进行commonjoin,执行时间161s,使用mapjoin,执行时间35s,执行效率大大提升

接着我们再来测试另外一个参数。调整hive.auto.convert.join.noconditionaltask.size参数(小于此设置的表会识别为小表),使其小于t3 表 的大小

set hive.auto.convert.join=true;

--重要,一般企业来调整此参数来决定小表的大小,比如让一些略大于小表阈值的表进行mapjoin

set hive.auto.convert.join.noconditionaltask.size=252300;

explain
SELECT t1.user_id
,t1.create_time
,t3.id
from ds_hive.ch12_order_detail_orc t1
join ds_hive.ch12_product_info_orc t3 on t1.province_id=t3.id
;

--------此类优化用的少

set hive.auto.convert.join.noconditionaltask=false;

set hive.mapjoin.smalltable.filesize= 15230000;

第一个sql,因为设置了.noconditionaltask.size=252300,小于表的大小,最终选择了commonjoin执行,第二遍我们关闭有条件执行,由于smalltable.filesize大于小表只有commonjoin,这时候调大set hive.mapjoin.smalltable.filesize=379000002;让其小表大于smalltable.filesize,这时候最终会选择mapjoin。

Bucket Map Join(大表join大表)

两张表都相对较大,若采用普通的Map Join算法,则Map端需要较多的内存来缓存数据,当然可以选择为Map段分配更多的内存,来保证任务运行成功。但是,Map端的内存不可能无上限的分配,所以当参与Join的表数据量均过大时,就可以考虑采用Bucket Map Join算法。Bucket Map Join是对Map Join算法的改进,其打破了Map Join只适用于大表join小表的限制,可用于大表join大表的场景。

Bucket Map Join的核心思想是:若能保证参与join的表均为分桶表,且关联字段为分桶字段,且其中一张表的分桶数量是另外一张表分桶数量的整数倍,就能保证参与join的两张表的分桶之间具有明确的关联关系,所以就可以在两表的分桶间进行Map Join操作了。这样一来,第二个Job的Map端就无需再缓存小表的全表数据了,而只需缓存其所需的分桶即可。其原理如图所示:

优化条件:

1) set hive.optimize.bucketmapjoin = true;

2) 一个表的bucket数是另一个表bucket数的整数倍

3) bucket列 == join列

4) 必须是应用在map join的场景中

Bucket Map Join不支持自动转换,发须通过用户在SQL语句中提供如下Hint提示,并配置如下相关参数,方可使用。

1)Hint提示

hive (default)>

select /*+ mapjoin(ta) */

    ta.id,

    tb.id

from table_a ta

join table_b tb on ta.id=tb.id;

2)相关参数

--关闭cbo优化,cbo会导致hint信息被忽略

set hive.cbo.enable=false;

--map join hint默认会被忽略(因为已经过时),需将如下参数设置为false

set hive.ignore.mapjoin.hint=false;

--启用bucket map join优化功能

set hive.optimize.bucketmapjoin = true;

Sort Merge Bucket Map Join(大表join大表)

Sort Merge Bucket Map Join(简称SMB Map Join)基于Bucket Map Join。SMB Map Join要求,参与join的表均为分桶表,且需保证分桶内的数据是有序的,且分桶字段、排序字段和关联字段为相同字段,且其中一张表的分桶数量是另外一张表分桶数量的整数倍。

SMB Map Join同Bucket Join一样,同样是利用两表各分桶之间的关联关系,在分桶之间进行join操作,不同的是,分桶之间的join操作的实现原理。Bucket Map Join,两个分桶之间的join实现原理为Hash Join算法;而SMB Map Join,两个分桶之间的join实现原理为Sort Merge Join算法。

Hash Join和Sort Merge Join均为关系型数据库中常见的Join实现算法。Hash Join的原理相对简单,就是对参与join的一张表构建hash table,然后扫描另外一张表,然后进行逐行匹配。Sort Merge Join需要在两张按照关联字段排好序的表中进行,其原理如图所示:

Hive中的SMB Map Join就是对两个分桶的数据按照上述思路进行Join操作。可以看出,SMB Map Join与Bucket Map Join相比,在进行Join操作时,Map端是无需对整个Bucket构建hash table,也无需在Map端缓存整个Bucket数据的,每个Mapper只需按顺序逐个key读取两个分桶的数据进行join即可。

Sort Merge Bucket Map Join有两种触发方式,包括Hint提示和自动转换。Hint提示已过时,不推荐使用。下面是自动转换的相关参数:

--启动Sort Merge Bucket Map Join优化

set hive.optimize.bucketmapjoin.sortedmerge=true;

--使用自动转换SMB Join

set hive.auto.convert.sortmerge.join=true;

两张表都相对较大,除了可以考虑采用Bucket Map Join算法,还可以考虑SMB Join。相较于Bucket Map Join,SMB Map Join对分桶大小是没有要求的。

谓词下推

谓词下推(predicate pushdown)是指,尽量将过滤操作前移,以减少后续计算步骤的数据量。数仓实际开发中经常会涉及到多表关联,这个时候就会涉及到on与where的使用。一般在面试的时候会提问:条件写在where里和写在on有什么区别?

相关参数为:

--是否启动谓词下推(predicate pushdown)优化

set hive.optimize.ppd = true;

示例SQL语句

hive (default)>

explain

SELECT t1.id

,t2.province_name

from ds_hive.ch12_order_detail_orc t1

left join ds_hive.ch12_province_info_orc t2 on t1.province_id=t2.id

where t1.product_num=20 and t2.province_name='江苏'

;

关闭谓词下推优化

--是否启动谓词下推(predicate pushdown)优化

set hive.optimize.ppd = false;

--为了测试效果更加直观,关闭cbo优化

set hive.cbo.enable=false;

--为了测试效果更加直观,关闭mapjoin

set hive.auto.convert.join=false;

通过执行计划可以看到,当我们把谓词下推关闭以后,数据是所有数据关联以后才进行过滤的,这样如果量表数据量大,就大大降低了我们的执行效率

开启谓词下推优化

--是否启动谓词下推(predicate pushdown)优化

set hive.optimize.ppd = true;

--为了测试效果更加直观,关闭cbo优化

set hive.cbo.enable=false;

通过执行计划可以看出,过滤操作位于执行计划中的join操作之前。大大减少了关联的数据量。对整体执行效率有很大提升。

开启谓词执行做关联,优化一下SQL

--是否启动谓词下推(predicate pushdown)优化

set hive.optimize.ppd = true;

--为了测试效果更加直观,关闭cbo优化

set hive.cbo.enable=false;

-- 将where条件里关于t2的过滤放到on条件后

explain
    SELECT t1.id
           ,t2.province_name
      from ds_hive.ch12_order_detail_orc t1
left join ds_hive.ch12_province_info_orc  t2
        on t1.province_id=t2.id and t2.province_name='江苏'
  where t1.product_num=20
;

通过执行计划可以看出,t1和t2过滤操作都位于执行计划中的join操作之前,对俩个表都是先过滤再关联,效率更一步提升。

当我们使用左关联的时候:1.所有条件写在where中,只有左边的条件先过滤;2.当所有条件写在 on 里面只有右边的条件起作用,3.为了可以让条件都起作用,就把左表条件写在where里,右边条件写在 on 里,两者都先过滤

结论:

  1. 对于Join(Inner Join)、Full outer Join,条件写在on后面,还是where后面,性能上面没有区别,join谓词下推都生效,Full outer Join都不生效;
  2. 对于Left outer Join ,右侧的表写在on后面、左侧的表写在where后面,性能上有提高;
  3. 对于Right outer Join,左侧的表写在on后面、右侧的表写在where后面,性能上有提高;

合理选择排序

order by
全局排序,只走一个reducer,当表数据量较大时容易计算不出来,性能不佳慎用,在严格模式下需要加limit

sort by
局部排序,即保证单个reduce内结果有序,但没有全局排序的能力。

distribute by
按照指定的字段把数据划分输出到不同的reducer中,是控制数据如何从map端输出到reduce端,hive会根据distribute by后面的字段和对应reducer的个数进行hash分发

cluster by
拥有distrubute by的能力,同时也拥有sort by的能力,所以可以理解cluster by是 distrubute by+sort by

实例代码优化

-- 优化前
select
id         
,count(*) as cnt
from ds_hive.ch12_order_detail_orc t1
group by id
order by cnt
limit 100
;

执行时间109.9s

-- 优化后
select
id
,cnt
from
(select id       
        ,count(*) as cnt
   from ds_hive.ch12_order_detail_orc t1
   group by id
) t1
distribute by cnt
sort by id
limit 100
;

执行时间69s

通过优化前后时间对比,可以看到优化效果

注意实际企业运维可以通过参数 set hive.mapred.mode=strict 来设置严格模式,这个时候使用 orderby 全局排序必须加 limit;建议如果不是非要全局有序的话,局部有序的话建议使用 sortby,它会视情况启动多个 reducer 进行排序,并且保证每个 reducer 内局部有序。为了控制map 端数据分配到 reducer 的 key,往往还要配合 distribute by 一同使用。如果不加 distribute by 的话,map 端数据就会随机分配到 reducer。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【三维生成】StarGen:基于视频扩散模型的可扩展的时空自回归场景生成

标题&#xff1a;《StarGen: A Spatiotemporal Autoregression Framework with Video Diffusion Model for Scalable and Controllable Scene Generation》 项目&#xff1a;https://zju3dv.github.io/StarGen 来源&#xff1a;商汤科技、浙大CAD、Tetras.AI 文章目录 摘要一、…

vue2(笔记)4.0vueRouter.声明式/编程式导航以及跳转传参.重定向

---vueRouter 五个步骤: 两个核心: {path:路径,component:组件} 二级路由: 1.在主页路由对象中,添加children配置项 2.准备路由出口 示例代码: {path: /,component: layout,redirect: home,children: [{path: /home,component: home},{path: /card,component: card}]}, 在l…

内网渗透信息收集linuxkali扫描ip段,收集脚本(web安全)

内网ip段扫描↓ 工具1↓ nmap -sn 192.168.128.0/24工具2↓ nbtscan 192.168.128.0/24 工具↓3 arp-scan -t 1000 192.168.128.0/24 cmd命令扫描↓ for /L %I in (1,1,255) Do ping -w 1 -n 1 192.168.128.%I | findstr "TTL" 这个命令在Windows命令提示符下使…

DeepSeek崛起:如何在云端快速部署你的专属AI助手

在2025年春节的科技盛宴上&#xff0c;DeepSeek因其在AI领域的卓越表现成为焦点&#xff0c;其开源的推理模型DeepSeek-R1擅长处理多种复杂任务&#xff0c;支持多语言处理&#xff0c;并通过搜索引擎获取实时信息。DeepSeek因其先进的自然语言处理技术、广泛的知识库和高性价比…

python-leetcode 48.二叉树的最近公共祖先

题目&#xff1a; 给定一个二叉树&#xff0c;找到该树中两个指定节点的最近公共祖先 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff0…

示例:在WPF中如何使用Segoe MDL2 Assets图标和使用该图标的好处

一、目的&#xff1a;分享在WPF中如何使用Segoe MDL2 Assets图标和使用该图标的好处 在WPF中使用Segoe MDL2 Assets字体&#xff0c;可以通过设置控件的FontFamily属性来实现。Segoe MDL2 Assets是一个包含许多图标的字体&#xff0c;通常用于Windows应用程序的图标显示。 二、…

QT——基于 QListWidget 和 QStackedWidget 的页面切换

Qt 练习题&#xff1a;基于 QListWidget 和 QStackedWidget 的页面切换 Qt 练习题&#xff1a;基于 QListWidget 和 QStackedWidget 的页面切换 题目描述&#xff1a; 请使用 Qt 设计一个窗口&#xff0c;其中包含一个 QListWidget 和一个 QStackedWidget。要求实现以下功能&a…

Docker概念与架构

文章目录 概念docker与虚拟机的差异docker的作用docker容器虚拟化 与 传统虚拟机比较 Docker 架构 概念 Docker 是一个开源的应用容器引擎。诞生于 2013 年初&#xff0c;基于 Go 语言实现。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xf…

linux server docker 拉取镜像速度太慢或者超时的问题处理记录

已经按网上的帖子将镜像地址改为国内的了,用docker info命令查看,如下图所示: 但是还存在下载镜像特别卡的问题,而不是直接报错了,如下图所示: 甚至已经连续下载一晚上了,还是卡在这里,不见任何下载进展。 我在window的docker中下载了对应的镜像,并用以下语句生成了…

四十二:VSCODE打开新文件覆盖上一个文件窗口问题

VSCODE打开新文件覆盖上一个文件窗口问题_vscode enablepreview-CSDN博客

shell文本处理

shell文本处理 一、grep ​ 过滤来自一个文件或标准输入匹配模式内容。除了 grep 外&#xff0c;还有 egrep、fgrep。egrep 是 grep 的扩展&#xff0c;相当于 grep -E。fgrep 相当于 grep -f&#xff0c;用的比较少。 用法 grep [OPTION]... PATTERN [FILE]...支持的正则描述…

下载b站视频音频

文章目录 方案一&#xff1a;jjdown如何使用 方案二&#xff1a;bilibili哔哩哔哩下载助手如何使用进入插件网站插件下载插件安装 使用插件下载视频音频&#xff1a;复制音频下载地址 方案三&#xff1a;bat命令下载单个音频下载单个视频下载单个音视频 方案一&#xff1a;jjdo…

【项目管理】基于 C 语言的 QQ 聊天室实现(TCP + 多线程 + SQLite3)

基于 C 语言的 QQ 聊天室(TCP + 多线程 + SQLite3) 项目功能基础功能: 登录、注册、添加好友、私聊、创建群聊、群聊扩展功能: 删除好友、注销账号、好友在线状态、群管理(拉人/踢人)、VIP 特权、邮件通知等 功能介绍:模拟QQ聊天客户端:登录界面:1、登录2、注册 //将用…

Linux驱动开发-字符设备驱动开发

Linux驱动开发-字符设备驱动开发 一&#xff0c;Linux驱动开发二&#xff0c;字符设备驱动开发1.具体实现2.1.1驱动模块具体函数实现2.1.2 应用调试模块具体函数实现2.1.3 Makefile2.1.4 进行测试2.1.4.1创建节点2.1.4.2 加载和卸载驱动模块2.1.4.3 测试 2.字符设备驱动应用程序…

e2studio开发RA4M2(17)----ADC扫描多通道采样

e2studio开发RA4M2.17--ADC扫描多通道采样 概述视频教学样品申请硬件准备参考程序源码下载ADC属性配置回调函数主程序演示结果 概述 在嵌入式系统中&#xff0c;ADC&#xff08;模数转换器&#xff09;是一个非常重要的组件&#xff0c;它将模拟信号转换为数字信号。为了提高采…

编写一个基于OpenSSL的SSL/TLS服务端(HTTPS)可运行的完整示例

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

MyBatis的关联映射

前言 在实际开发中&#xff0c;对数据库的操作通常会涉及多张表&#xff0c;MyBatis提供了关联映射&#xff0c;这些关联映射可以很好地处理表与表&#xff0c;对象与对象之间的的关联关系。 一对一查询 步骤&#xff1a; 先确定表的一对一关系确定好实体类&#xff0c;添加关…

利用Git和wget批量下载网页数据

一、Git的下载&#xff08;参考文章&#xff09; 二. wget下载&#xff08;网上很多链接&#xff09; 三、git和wget结合使用 1.先建立一个文本&#xff0c;将代码写入文本&#xff08;代码如下&#xff09;&#xff0c;将txt后缀改为sh&#xff08;download_ssebop.sh&#xf…

deepseek助力运维和监控自动化

将DeepSeek与Agent、工作流及Agent编排技术结合&#xff0c;可实现IT运维与监控的智能化闭环管理。以下是具体应用框架和场景示例&#xff1a; 一、智能Agent体系设计 多模态感知Agent 日志解析Agent&#xff1a;基于DeepSeek的NLP能力&#xff0c;实时解析系统日志中的语义&a…

从零开始实现机器臂仿真(UR5)

1. UR5软件配置 # 安装 MoveIt! 依赖 sudo apt install ros-humble-moveit ros-humble-tf2-ros ros-humble-moveit-setup-assistant ros-humble-gazebo-ros-pkgs # 安装 UR 官方 ROS2 驱动 sudo apt update sudo apt install ros-humble-ur-robot-driver ros-humble-ur-descri…