虛擬的cpu代碼併發數,若是一個container擁有2個vcpu,那麼該container就能夠真正的在同一時間運行兩個線程,而不是靠切時間片而達到的邏輯併發。因此通常虛擬的cpu須要和物理cpu的個數保持一致node
yarn的計算單元稱爲YCUs,其實就是把1個cpu分爲n份,一般狀況控制在1:1000左右,也就是說一個一核cpu能夠被yarn分爲1000個左右的YCUs,並在使用yarn的時候,能夠配置使用多少YCUs。例如500個YCUs,那麼其實獲得的大概是1/2個核的cpu。linux
cpu不像內存同樣,內存掌控着程序的生死,而cpu只是決定程序執行的速度。緩存
yarn的一些關於虛擬內存的配置服務器
key多線程 |
默認併發 |
解釋app |
yarn.nodemanager.vmem-check-enabled性能 |
truespa |
是否對app進行虛擬內存監控操作系統 |
yarn.nodemanager.vmem-pmem-ratio |
5 |
虛擬內存上限係數,乘數是應用物理內存上限 |
yarn默認開啓了對應用虛擬內存的檢測,虛擬內存能夠經過top來看到VIRT,當應用使用的虛擬內存超過了yarn限制的虛擬內存上限,那麼yarn會把這個應用殺死。虛擬內存上限的計算公式爲:yarn.nodemanager.vmem-pmem-ratio*物理內存。遇到這類虛擬內存超過yarn限制的問題,常見的策略有:
也就是把`yarn.nodemanager.vmem-check-enabled`配置爲false
把` 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