背景
在应用kubernetes过程中,能够通过kubectl top pod
命令能够查看到各个Pod内存应用状况,从而发现与Pod过程理论应用内存不统一,具体情况如下:
Java利用部署在
kubernetes
中,配置的JVM参数为-Xmx2048m -Xms2048m
Pod memory request设置为3G, memory limit 为 4G
查看目前Pod已应用内存
<code class="shell"># kubectl top pods gateway-5bf49bcb7-7mj99 98m 3046Mi
而后咱们通过top命令进行查看内存应用状况
<code class="shell">top - 15:29:03 up 140 days, 13:13, 0 users, load average: 0.49, 0.46, 0.51 Tasks: 5 total, 1 running, 4 sleeping, 0 stopped, 0 zombie %Cpu(s): 3.8 us, 1.8 sy, 0.0 ni, 93.8 id, 0.5 wa, 0.0 hi, 0.1 si, 0.0 st MiB Mem : 32011.6 total, 239.0 free, 13934.4 used, 17838.2 buff/cache MiB Swap: 0.0 total, 0.0 free, 0.0 used. 17679.0 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8 root 20 0 7761.2m 2.0g 15.2m S 10.3 6.3 77:27.35 java 1 root 20 0 2.3m 0.7m 0.5m S 0.0 0.0 0:00.01 sh 7 root 20 0 5.5m 1.7m 1.3m S 0.0 0.0 0:00.00 run.sh 1349 root 20 0 5.8m 2.2m 1.6m S 0.0 0.0 0:00.02 bash 1355 root 20 0 9.5m 1.8m 1.3m R 0.0 0.0 0:00.01 top
通过如上操作能够看出,通过kubectl top pods
能够看到应用内存为3046M,而通过top命令能够应用内存为2.0G,由此能够看出Pod内存要高于理论应用内存。
Pod内存指标详解
通过kubectl top pods
获取监控指标数据都是 Prometheus metrics 组件来实现,接下来介绍下比拟罕用的监控指标;
- kube_pod_container_resource_limits Pod内存限度
- kube_pod_container_resource_requests Pod所需内存
- container_memory_working_set_bytes Pod理论应用内存,也是 limit限度时的 oom 判断根据
- container_memory_rss Pod过程应用内存
Linux 缓存机制引入
缓存机制介绍
在Linux零碎中,为了进步文件系统性能,内核利用一部分物理内存调配出缓冲区,用于缓存零碎操作和数据文件,当内核收到读写的申请时,内核先去缓存区找是否有申请的数据,有的话间接返回,如果没有则通过驱动程序间接操作磁盘。
缓存机制长处: 缩小零碎调用次数,升高CPU上下文切换和磁盘拜访频率
CPU上下文切换: CPU给每个过程肯定的服务工夫,当工夫片用完后,内核从正在运行的过程中发出处理器,同时把过程以后运行状态保留下来,而后加载下一个工作,这个过程叫做上下文切换。本质上就是被终止运行过程与待运行过程的过程切换。
查看缓存区及内存应用状况
<code class="shell"># free -m total used free shared buff/cache available Mem: 3790 1914 126 3 1750 1579 Swap: 0 0
- total 总内存
- used 已应用内存
- free 闲暇内存
- shared 多个过程共享的内存总额
- buff/cache 缓存占用内存
- available 可用内存大小
从下面的命令结果显示中能够看出:总内存为4G, 已应用1914M,残余126M,不少的人都是这么看的。
但其实这样不能作为理论的使用率,因为有了缓存机制,具体算法如下:
闲暇内存=free(126)+buffers(0)+cached(1750)
已用内存=total(3790)-闲暇内存
buffers和cached
缓存(cached) 是把读取过的数据保存起来,从新读取时若命中 (找到须要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会依据读取频率进行组织,把最频繁读取的内容放在最容易找到的地位,把不再读的内容一直往后排,直至从中删除。
缓冲(buffers)是依据磁盘的读写设计额,把扩散的写操作集中进行,缩小磁盘碎片和硬盘的重复寻道,从而进步零碎性能。Linux有一个守护过程定期清理缓存内存 (即写入磁盘),也能够通过sync命令手动清空缓冲。举个例子吧:我这里有一个ext2的U盘,我往里面cp一个3M的MP3,但U盘的灯没有跳动,过了一会儿(或者手动输出sync)U盘的灯就跳动起来了。卸载设施时会清空缓冲,所以有些时候卸载一个设施时要等上几秒钟。
批改/etc/sysctl.conf中的vm.swappiness左边的数字能够在下次开机时调节swap应用策略。该数字范畴是0~100,数字越大越偏向于应用swap。默认为60,能够改一下试试。–两者都是RAM中的数据。
<u>两者都是RAM中的数据,简略来说,buffer是行将要被写入磁盘的,而cache是被从磁盘读出来的</u>
buffer是由各种过程调配的,被用在如输出队列等方面。一个简略的例子如某个过程要求有多个字段读入,在所有字段被读入残缺之前,过程把先前读入的字段放在buffer中保留。
cache常常被用在磁盘的I/O申请上,如果有多个过程都要拜访某个文件,于是该文件便被做成cache以不便下次被拜访,这样可进步零碎性能。
Cache:缓冲区,高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器。
因为CPU的速度远高于主内存,CPU间接从内存中存取数据要期待肯定工夫周期,Cache中保留着CPU刚用过或循环应用的一部分数据,当CPU再次应用该局部数据时可从Cache中间接调用,这样就缩小了CPU的等待时间,进步了零碎的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在CPU外部,L2 Cache晚期个别是焊在主板上,当初也都集成在CPU外部,常见的容量有256KB或512KB L2 Cache。它是依据程序的局部性原理而设计的,就是cpu执行的指令和拜访的数据往往在集中的某一块,所以把这块内容放入cache后,cpu就不必在拜访内存了,这就进步了访问速度。当然若cache中没有cpu所须要的内容,还是要拜访内存的。从内存读取与磁盘读取角度思考,cache能够了解为操作系统为了更高的读取效率,更多的应用内存来缓存可能被再次拜访的数据。
Cache并不是缓存文件的,而是缓存块的(块是I/O读写最小的单元);Cache个别会用在I/O申请上,如果多个过程要拜访某个文件,能够把此文件读入Cache中,这样下一个过程获取CPU控制权并拜访此文件间接从Cache读取,进步零碎性能。
Buffer:缓冲区,一个用于存储速度不同步的设施或优先级不同的设施之间传输数据的区域。
通过buffer能够缩小过程间通信须要期待的工夫,当存储速度快的设施与存储速度慢的设施进行通信时,存储慢的数据先把数据寄存到buffer,达到肯定水平存储快的设施再读取buffer的数据,在此期间存储快的设施CPU能够干其余的事件。
Buffer:个别是用在写入磁盘的,例如:某个过程要求多个字段被读入,当所有要求的字段被读入之前曾经读入的字段会先放到buffer中。Buffer是依据磁盘的读写设计的,把扩散的写操作集中进行,缩小磁盘碎片和硬盘的重复寻道,从而进步零碎性能。linux有一个守护过程定期清空缓冲内容(即写入磁盘),也能够通过sync命令手动清空缓冲。
cache是高速缓存,用于CPU和内存之间的缓冲;
buffer是I/O缓存,用于内存和硬盘的缓冲;
cache最后用于cpu cache,次要起因是cpu 与memory,因为cpu快,memory跟不上,且有些值应用次数多,所以放入cache中,次要目标是,重复使用,并且一级\二级物理cache速度快,
buffer次要用于disk与 memory,次要是爱护硬盘或缩小网络传输的次数(内存数据体现dataSet).当然也能够进步速度(不会立刻写入硬盘或间接从硬盘中读出的数据马上显示),重复使用,最后最次要的目标是爱护disk,
Free中的buffer和cache:(它们都是占用内存):
buffer : 作为buffer cache的内存,是块设施的读写缓冲区
cache: 作为page cache的内存, 文件系统的cache
如果 cache 的值很大,阐明cache住的文件数很多。如果频繁拜访到的文件都能被cache住,那么磁盘的读IO bi会十分小。
<u>上面通过一些简略艰深的例子来阐明下Cache和Buffer缓存之间的区别:</u>
1)Cache缓存
假如某地产生了自然灾害(比方地震),居民缺衣少食,于是派救火车去给若干个居民点送水。救火车达到第一个居民点,开闸放水,老百姓就拿着盆盆罐罐来接水。如果说救火车在一个居民点停留100分钟放完了水,而后从新储水花半个小时,再开往下一个居民点。这样一个白天来来来回回的,也就是4-5个居民点。
但咱们想想,救火车是何等存在,如果把水龙头齐全关上,其弱小的水压能轻易冲上10层楼以上, 10分钟就能够把水全副放完。但因为居民是拿盆罐接水,100%关上水龙头那就是给人洗澡了,所以只能关上一小部分(比方10%的流量)。但这样就升高了放水的效率(只有原来的10%了),10分钟变100分钟。
那么,咱们是否能改良这个放水的过程,让救火车以最高效率放完水、尽快赶往下一个居民点呢?
办法就是:在居民点建蓄水池。
救火车把水放到蓄水池里,因为是以100%的效率放水,10分钟完结而后走人。居民再从蓄水池里一点一点的接水。
咱们剖析一下这个例子,就能够晓得Cache的含意了。
救火车要给居民送水,居民要从救火车接水,就是说居民和救火车之间有交互,有分割。
但救火车是”高速设施”,居民是”低速设施”,低速的居民跟不上高速的救火车,所以救火车被迫升高了放水速度以适应居民。
为了防止这种状况,在救火车和居民之间多了一层”蓄水池(也就是Cache)”,它一方面以100%的高效和救火车打交道,另一方面以10%的低效和居民打交道,这就解放了救火车,让其以最高的效率运行,而不被低速的居民拖后腿,于是救火车只须要在一个居民点停留10分钟就能够了。
所以说,蓄水池是”活雷锋”,把高效留给他人,把低效留给本人。把10分钟留给救火车,把100分钟留给本人。
从以上例子能够看出,所谓Cache,就是”为了补救高速设施和低速设施之间的矛盾”而设立的一个中间层。因为在事实里经常出现高速设施要和低速设施打交道,后果被低速设施拖后腿的状况。Cache的存在是为了解决什么问题?速度太慢了,要加快速度!
以PC为例。CPU速度很快,但CPU执行的指令是从内存取出的,计算的后果也要写回内存,但内存的响应速度跟不上CPU。CPU跟内存说:你把某某地址的指令发给我。内存听到了,但因为速度慢,迟迟不见指令返回,这段时间,CPU只能鸿鹄之志的期待了。这样一来,再快的CPU也施展不了效率。
怎么办呢?在CPU和内存之间加一块”蓄水池”,也就是Cache(片上缓存),这个Cache速度比内存快,从Cache取指令不须要期待。当CPU要读内存的指令的时候先读Cache再读内存,但一开始Cache是空着的,只能从内存取,这时候确实是很慢,CPU须要期待。但从内存取回的不仅仅是CPU所须要的指令,还有其它的、以后不须要的指令,而后把这些指令存在Cache里备用。CPU再取指令的时候还是先读Cache,看看外面有没有所需指令,如果碰巧有就间接从Cache取,不必期待即可返回(命中),这就解放了CPU,进步了效率。(当然不会是100%命中,因为Cache的容量比内存小)
2)Buffer缓存
比如说吐鲁番的葡萄熟了,要用大卡车装葡萄运出去卖果园的姑娘采摘葡萄,当然不是前手把葡萄摘下来,后手就放到卡车上,而是须要一个两头过程”箩筐”:摘葡萄→放到箩筐里→把箩筐里的葡萄倒入卡车。也就是说,尽管最终目标是”把葡萄倒入卡车”,但两头必须要通过”箩筐”的转手,这里的箩筐就是Buffer。是”临时寄存物品的空间”。
留神2个关键词:临时,空间
再换句话说,为了实现最终目标:把葡萄放入卡车的空间,须要临时把葡萄放入箩筐的空间。以BT为例,BT下载须要长时间的挂机,电脑就有可能24小时连轴转,但BT下载的数据是碎片化的,体现在硬盘写入上也是碎片化的,因为硬盘是机械寻址器件,这种碎片化的写入会造成硬盘长时间高负荷的机械运动,造成硬盘过早老化损坏,当年有大量的硬盘因为BT下载而损坏。于是新出的BT软件在内存里开拓了Buffer,数据临时写入Buffer,攒到肯定的大小(比方512M)再一次性写入硬盘,这种”化零为整”的写入形式大大降低了硬盘的负荷。这就是:为了实现最终目标:把数据写入硬盘空间,须要临时写入Buffer的空间。
3)二者之间的区别总结
Cache和Buffer的相同点:都是2个层面之间的中间层,都是内存。
Cache和Buffer的不同点:Cache解决的是工夫问题,Buffer解决的是空间问题。
为了进步速度,引入了Cache这个中间层。
为了给信息找到一个暂存空间,引入了Buffer这个中间层。
为了解决2个不同维度的问题(工夫、空间),凑巧取了同一种解决办法:退出一个中间层,先把数据写到中间层上,而后再写入指标。
这个中间层就是内存“RAM”,既然是存储器就有2个参数:写入的速度有多块(速度),能装多少货色(容量)
Cache利用的是RAM提供的高读写速度,Buffer利用的是RAM提供的存储容量(空间)。
简言之:
- Buffer(缓冲区)是零碎两端处理速度均衡(从长时间尺度上看)时应用的。它的引入是为了减小短期内突发I/O的影响,起到流量整形的作用。比方生产者——消费者问题,他们产生和耗费资源的速度大体靠近,加一个buffer能够对消掉资源刚产生/耗费时的忽然变动。
- Cache(缓存)则是零碎两端处理速度不匹配时的一种折衷策略。因为CPU和memory之间的速度差别越来越大,所以人们充分利用数据的局部性(locality)特色,通过应用存储系统分级(memory hierarchy)的策略来减小这种差别带来的影响。
- 假设当前存储器拜访变得跟CPU做计算一样快,cache就能够隐没,然而buffer仍然存在。比方从网络上下载货色,刹时速率可能会有较大变动,但从长期来看却是稳固的,这样就能通过引入一个buffer使得OS接收数据的速率更稳固,进一步缩小对磁盘的挫伤。
Pod过程内存缓存解释
目前曾经对Linux缓存已有了大略理解,接下来咱们对Pod内存进行剖析了!
首先咱们通过
kubectl top pods
查看的内存指标对应的是 Prometheus metrics 组件的container_memory_working_set_bytes
指标(过程缓存应用内存 + 过程应用内存),在kubernetes集群中同时做为Pod HPA弹性伸缩与 limit限度(oom)的判断根据,当Pod内存行将达到内存限度则会回收内存。
<code class="shell"># kubectl top pods gateway-5bf49bcb7-7mj99 98m 3046Mi
能够构想下,如果limit限度的判断根据为过程理论应用内存,则Pod过程理论应用内存必定大于限度内存,这样会呈现什么状况呢?
答:如上状况,会导致Pod内存得不到限度,cache缓存有限应用内存,得不到正当的回收。所以Pod limit限度应用container_memory_working_set_bytes
指标(过程缓存应用内存 + 过程应用内存)做为判断根据再好不过了
点击 “浏览原文” 获取更好的浏览体验!