虛擬cpu
虛擬的cpu代碼並發數,如果一個container擁有2個vcpu,那么該container就可以真正的在同一時間運行兩個線程,而不是靠切時間片而達到的邏輯並發。所以一般虛擬的cpu需要和物理cpu的個數保持一致
yarn的計算單元稱為YCUs,其實就是把1個cpu分為n份,通常情況控制在1:1000左右,也就是說一個一核cpu可以被yarn分為1000個左右的YCUs,並在使用yarn的時候,可以配置使用多少YCUs。例如500個YCUs,那么其實得到的大概是1/2個核的cpu。
cpu不像內存一樣,內存掌控着程序的生死,而cpu只是決定程序執行的速度。
- 通過控制cpu的功率就可以限制線程的執行速度。比如通過CGgroups限制。
- 分配給一個線程超過1個cpu是沒有意思的,純粹是浪費行為。
- 在一些IO密集型的任務里,就不需要給每個線程分配一個完整的cpu,可以嘗試着分配1/2的cpu,利用YCUs就可以做到。
虛擬內存
yarn和虛擬內存的關聯
yarn的一些關於虛擬內存的配置
| key |
默認 |
解釋 |
| yarn.nodemanager.vmem-check-enabled |
true |
是否對app進行虛擬內存監控 |
| yarn.nodemanager.vmem-pmem-ratio |
5 |
虛擬內存上限系數,乘數是應用物理內存上限 |
yarn默認開啟了對應用虛擬內存的檢測,虛擬內存可以通過top來看到VIRT,當應用使用的虛擬內存超過了yarn限制的虛擬內存上限,那么yarn會把這個應用殺死。虛擬內存上限的計算公式為:yarn.nodemanager.vmem-pmem-ratio*物理內存。遇到這類虛擬內存超過yarn限制的問題,常見的策略有:
- 關閉yarn對應用虛擬內存的檢查
也就是把`yarn.nodemanager.vmem-check-enabled`配置為false
- 調高yarn對應用虛擬內存限制的系數
把` yarn.nodemanager.vmem-pmem-ratio`配置更大一點
- 減少應用對虛擬內存的使用
這塊牽扯的內容稍微多一些,先給個結論,修改linux的環境變量`export MALLOC_ARENA_MAX=4`,下面詳細解釋一下應用的虛擬內存使用
什么是虛擬內存
操作系統將磁盤空間當做內存空間供給程序使用
# 查看某個進程的虛擬內存使用
pmap -x pid
為什么虛擬內存分配了很多
我們知道Linux下glibc的內存管理機制用了一個很奇妙的東西,叫arena。在glibc分配內存的時候,大內存從從中央分配區分配,小內存則在線程創建時,從緩存區分配。為了解決分配內存的性能的問題,就引入了這個叫做arena的memory pool,其原理就是通過為每個線程構建一個arena,來避免多線程同時競爭一個arena。而在64bit系統下面,它的缺省配置為64M。一個進程可以最多有cores*8個arena,假如服務器是4核的,那么最多有4*8=32個arena,也就是32*64 = 2048M內存
查資料發現這是 glibc 在版本 2.10 引入的 arena 新功能導致。CentOS 6/7 的 glibc 大都是 2.12/ 2.17 了,所以都會有這個問題。這個功能對每個線程都分配一個分配一個本地arena來加速多線程的執行。
在 glibc 的 arena.c 中使用的 mmap() 調用就和之前的示例代碼類似:
p2 = (char *)mmap(aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE,
MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)
之后,只有很小的一部分地址被映射到了物理內存中:
mprotect(p2, size, PROT_READ | PROT_WRITE)
因此在一個多線程程序中,會有相當多的 64MB 的 arena 被分配。這個可以用環境變量 MALLOC_ARENA_MAX 來控制。在64位系統中的默認值為 128,也就是單個進程最多可以申請128個arena。
由於Java 程序由於自己維護堆的使用,導致調用 glibc 去管理內存的次數較少。更糟的是 Java 8 開始使用 metaspace 原空間取代永久代,而元空間是存放在操作系統本地內存中,這就導致線程一多,每個線程都要使用一點元空間,也就是每個線程都分配一個64MB的 arena,導致巨大的虛擬地址被分配。
可以減小MALLOC_ARENA_MAX,比如
export MALLOC_ARENA_MAX=4
參考
https://yq.aliyun.com/articles/227924
https://unix.stackexchange.com/questions/379644/glibc-memory-alloction-arenas-and-debugging
