Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit cpus and io bandwidth #271

Closed
ondrejhlavacek opened this issue Apr 19, 2018 · 50 comments
Closed

Limit cpus and io bandwidth #271

ondrejhlavacek opened this issue Apr 19, 2018 · 50 comments
Assignees

Comments

@ondrejhlavacek
Copy link
Member

--device-read-bps, --device-write-bps, --cpus

https://keboola.slack.com/archives/C03JBGZDG/p1524126714000272

mohlo by pomoct s #267

@ondrejhlavacek
Copy link
Member Author

@ondrejhlavacek
Copy link
Member Author

@ondrejhlavacek
Copy link
Member Author

Oprava. Šel jsem na to ještě jendou čistým dd. Docela zámrd byl s tím, že dd při velikosti 2G a větší dělá nějaký haluze, zřejmě mu přeteče nějaký interní počítadlo a píše nesmyslnej throughput (1,8 G/s).

US - ~250 MB/s R/W
EU - ~120 MB/s R/W

@ondrejhlavacek
Copy link
Member Author

Nastavil bych hard limit throughputu na 100 MB/s a uvedl to do limitů platformy.
CPU bych nastavil na dva.

@ondrejhlavacek
Copy link
Member Author

Tak, ale narazil jsem na to, že --device-*-bps se nastavuje per device, eg. --device-write-bps /dev/sda:50mb, a to vůbec nevím, jak v docker runneru nastavit :-(

@Halama
Copy link
Member

Halama commented Apr 23, 2018

@ondrejhlavacek máš nějaký docker command který děláš benchmark disku?

@ondrejhlavacek
Copy link
Member Author

dej mi minutku, připravím

@Halama
Copy link
Member

Halama commented Apr 23, 2018

zatím jsem si vygeneroval 1G soubor a zkouším ho v kontejneru kopírovat.

@ondrejhlavacek
Copy link
Member Author

používá se na to dd, ale zápasím s něčím spolehlivým pro read, aby to neměl nacachovaný

@ondrejhlavacek
Copy link
Member Author

ondrejhlavacek commented Apr 23, 2018

benchmark na write je takhle

docker run --rm --volume /tmp:/tmp centos sh -c "dd if=/dev/zero of=/tmp/testfile bs=1500M count=1 oflag=dsync"

@Halama
Copy link
Member

Halama commented Apr 23, 2018

možná mi to začalo fungovat:

[root@syrup-testing-syrup-docker-i-0c238bf98f8467bf1 ec2-user]# docker run --rm --volume /tmp:/tmp --device-write-bps /dev/md0:10mb php sh -c "dd if=/dev/zero of=/tmp/testfile bs=100M count=1 oflag=dsync"
1+0 records in
1+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 45.1134 s, 2.3 MB/s

@ondrejhlavacek
Copy link
Member Author

docker run --rm --volume /tmp:/tmp centos sh -c "dd if=/dev/zero of=/tmp/testfile bs=1500M count=1 oflag=direct && dd bs=1500M count=1 iflag=direct if=/tmp/testfile of=/dev/null"

write i read v jednom

@ondrejhlavacek
Copy link
Member Author

hustě!!!

@Halama
Copy link
Member

Halama commented Apr 23, 2018

jo tak asi jo, 2x jsem zvětšil a 2x to stouplo:

[root@syrup-testing-syrup-docker-i-0c238bf98f8467bf1 ec2-user]# docker run --rm --volume /tmp:/tmp --device-write-bps /dev/md0:20mb php sh -c "dd if=/dev/zero of=/tmp/testfile bs=100M count=1 oflag=dsync"
1+0 records in
1+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 22.6084 s, 4.6 MB/s

@Halama
Copy link
Member

Halama commented Apr 23, 2018

Ze začátku jsem to zkoušel tak že jsem si na hostu pomocí dd vygeneroval do /tmp soubor a ten pak zkoušel kopírovat pomocí cp v kontejneru a tam mi to nezabíralo.
Tímhle testem to ale vypadá že to limituje pro read i write z /tmp.

A s tím /dev/md0 můžeš na docker runner instancích počítat, na něj se vždy mountuje /tmp https://github.com/keboola/syrup-router/blob/ad5c724851045981418a97bf0ae6f13c94138a1e/provisioning/docker-spot-fleet.json#L606

@ondrejhlavacek
Copy link
Member Author

@Halama nenapadá tě, jak podobnej setup alespoň mocknout na devel2/3? nebo jak dynamicky zjistit ten device? propustnost testovat nebudu, ale pouští se všude stejnej command.

@Halama
Copy link
Member

Halama commented Apr 23, 2018

nevím devel2/3 považuju za věci k vypnutí:) Chceš to do testů? nebo si s tím hrát?

@ondrejhlavacek
Copy link
Member Author

Bude to fungovat v kontejneru i mimo /tmp?

@ondrejhlavacek
Copy link
Member Author

Do testů to nepotřebuju, ale potřebuju, aby se na devel2/3 pouštěly kontejnery stejným docer run commandem jako na produkci.

@ondrejhlavacek
Copy link
Member Author

Note to self: je to v bps, takže 100 MB/s = 800 mbps.

@Halama
Copy link
Member

Halama commented Apr 23, 2018

Tohle nastavení se vztahuje jenom na /tmp. Můžu zkusit jestli půjde varianta že by to limitovalo uvnitř kontejneru?

@ondrejhlavacek
Copy link
Member Author

Jo, mělo by se to limitovat všude, kde ten kontejner může něco zapisovat/číst.

@Halama
Copy link
Member

Halama commented Apr 23, 2018

^ tím /tmp myslím na hostu, takže v docker runneru se to bude vztahovat na vše pod /data

@Halama
Copy link
Member

Halama commented Apr 23, 2018

ok, vyzkouším to. předtím mi to nešlo, ale to bylo zas s tím cp.

@Halama
Copy link
Member

Halama commented Apr 23, 2018

Do testů to nepotřebuju, ale potřebuju, aby se na devel2/3 pouštěly kontejnery stejným docer run commandem jako na produkci.

Tomuhle nerozumím, k čemu to teda potřebuješ?

@ondrejhlavacek
Copy link
Member Author

Tohle je single-point-of-truth pro docker run commandy.

public function getRunCommand($containerId)
{
setlocale(LC_CTYPE, "en_US.UTF-8");
$envs = "";
$dataDir = $this->dataDir;
foreach ($this->runCommandOptions->getEnvironmentVariables() as $key => $value) {
$envs .= " --env \"" . str_replace('"', '\"', $key) . "=" . str_replace('"', '\"', $value). "\"";
}
$command = "sudo timeout --signal=SIGKILL {$this->getImage()->getSourceComponent()->getProcessTimeout()} docker run";
$labels = '';
foreach ($this->runCommandOptions->getLabels() as $label) {
$labels .= ' --label ' . escapeshellarg($label);
}
$command .= " --volume " . escapeshellarg($dataDir . ":/data")
. " --memory " . escapeshellarg($this->getImage()->getSourceComponent()->getMemory())
. " --memory-swap " . escapeshellarg($this->getImage()->getSourceComponent()->getMemory())
. " --cpu-shares " . escapeshellarg($this->getImage()->getSourceComponent()->getCpuShares())
. " --net " . escapeshellarg($this->getImage()->getSourceComponent()->getNetworkType())
. $envs
. $labels
. " --name " . escapeshellarg($containerId)
. " " . escapeshellarg($this->getImage()->getFullImageId());
return $command;
}

Pokud tam přidám --device-write-bps /dev/md0:20mb, tak to na develu shnije. Na develu2/3 je ještě komplet dev/testing.

[ondra@kbc-devel-03 ~]$ sudo docker run --rm --volume /tmp:/tmp --device-write-bps /dev/md0:20mb php sh -c "dd if=/dev/zero of=/tmp/testfile bs=100M count=1 oflag=dsync"
docker: Error response from daemon: linux runtime spec resources: no such file or directory.

@ondrejhlavacek
Copy link
Member Author

Ještě zkoumám možnost, že by se nějak dynamicky generoval list deviců a daly se tam prostě všechny.

@Halama
Copy link
Member

Halama commented Apr 23, 2018

to bych nedělal. Počkej mmnt já se k tomu pak vrátím a chci zkusit jestli to bude fungovat i na ten pool. Jak namapovat dynamicky ten tmp pak bude jednoduchý, i když mi to přijde zbytečný.

@ondrejhlavacek
Copy link
Member Author

[root@kbc-devel-03 ondra]# lsblk --nodeps --output NAME --noheadings 2>/dev/null
xvda
xvdb
xvdh
xvdi

@Halama
Copy link
Member

Halama commented Apr 23, 2018

to schválně pak zkusím jestli to funguje i přímo na tech devices.

@ondrejhlavacek
Copy link
Member Author

S těma bps a b/s to není tak jednoznačný. použil jsem teď --device-write-bps /dev/xvda:10m a dostávám

1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 10.0322 s, 10.5 MB/s

@ondrejhlavacek
Copy link
Member Author

jo, fungue to i přímo na devicech

@ondrejhlavacek
Copy link
Member Author

[ondra@kbc-devel-03 ~]$ sudo docker run --rm --volume /tmp:/tmp --device-write-bps /dev/xvda:10m --device-write-bps /dev/xvdb:10m --device-write-bps /dev/xvdh:10m --device-write-bps /dev/xvdi:10m centos sh -c "dd if=/dev/zero of=/tmp/testfile bs=100M count=1 oflag=dsync"
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 10.0322 s, 10.5 MB/s
[ondra@kbc-devel-03 ~]$ sudo docker run --rm --volume /tmp:/tmp --device-write-bps /dev/xvda:20m --device-write-bps /dev/xvdb:20m --device-write-bps /dev/xvdh:20m --device-write-bps /dev/xvdi:20m centos sh -c "dd if=/dev/zero of=/tmp/testfile bs=100M count=1 oflag=dsync"
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 5.03839 s, 20.8 MB/s

@Halama
Copy link
Member

Halama commented Apr 23, 2018

jj, jede to:

docker run --rm --volume /tmp:/tmp --device-write-bps /dev/xvdh:40mb --device-write-bps /dev/xvdg:40mb php sh -c "dd if=/dev/zero of=/tmp/testfile bs=100M count=1 oflag=dsync"
1+0 records in
1+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 1.3112 s, 80.0 MB/s

Jenom je potřeba počítat s tím že jsou v raid takže to dává 2x více.

@ondrejhlavacek
Copy link
Member Author

Takže kdyby do RAIDu přibylo víc disků, tak to zase vyletí nahoru.

@Halama
Copy link
Member

Halama commented Apr 23, 2018

Uvnitř kontejneru mi to zatím nelimituje:

docker run --rm --volume /tmp:/tmp --device-write-bps /dev/xvdh:40mb --device-write-bps /dev/xvdg:40mb --device-write-bps /dev/xvdi:40mb --device-write-bps /dev/xvdj:40mb php sh -c "dd if=/dev/zero of=/testfile bs=100M count=1 oflag=dsync"
1+0 records in
1+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.739438 s, 142 MB/s

@Halama
Copy link
Member

Halama commented Apr 23, 2018

hmm, tak jak na to uvnitř kontejneru nevím...

@ondrejhlavacek
Copy link
Member Author

Ok, nechám to pár dní být a pak se k tomu zkusím vrátit. To je docela divný, ale potvrzuju, taky mi to nezalimitovalo!

@ondrejhlavacek
Copy link
Member Author

ondrejhlavacek commented Apr 27, 2018

nelimituje

sudo docker run --rm \
  --volume /tmp:/tmp \
  --device-write-bps /dev/xvda:10m \
  --device-write-bps /dev/xvdb:10m \
  --device-write-bps /dev/xvdh:10m \
  --device-write-bps /dev/xvdi:10m \
  centos \
  sh -c "\
    dd if=/dev/zero of=/testfile bs=100M count=1 oflag=dsync && \
    dd if=/dev/zero of=/testfile bs=100M count=1 oflag=dsync \
  "
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 1.03887 s, 101 MB/s
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 1.18871 s, 88.2 MB/s

@ondrejhlavacek
Copy link
Member Author

Ještě jsem se v tom vrtal podle https://ogavrisevs.github.io/2016/07/11/isolation-in-docker/#disk-usage-base-device ale neúspěšně. Podle mě failuju na tom, že neumím identifikovat device, kterej používá storage driver pro / (třeba /dev/dm-0), nebo je taky možný, že se bypassuje.

@Halama
Copy link
Member

Halama commented Apr 27, 2018

pro / se používa device docker poolu

@ondrejhlavacek
Copy link
Member Author

A jak zjístím, kterej to je?

@ondrejhlavacek
Copy link
Member Author

Z tohodle nic nevykoukám

Storage Driver: devicemapper
 Pool Name: docker-thinpool-tpool
 Pool Blocksize: 524.3 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: xfs
 Data file: 
 Metadata file: 
 Data Space Used: 17.83 GB
 Data Space Total: 102 GB
 Data Space Available: 84.17 GB
 Metadata Space Used: 6.169 MB
 Metadata Space Total: 1.07 GB
 Metadata Space Available: 1.063 GB
 Udev Sync Supported: true
 Deferred Removal Enabled: true
 Deferred Deletion Enabled: false
 Deferred Deleted Device Count: 0
 Library Version: 1.02.89-RHEL6 (2014-09-01)

@ondrejhlavacek
Copy link
Member Author

ondrejhlavacek commented Apr 27, 2018

mám tam symlinky na /dev/dm-* a ty jsem měl zalimitovaný všechny a nepomohlo to

# ls /dev/mapper/ -la
total 0
drwxr-xr-x  2 root root     160 Apr 27 12:05 .
drwxr-xr-x 17 root root    3160 Apr 27 12:05 ..
crw-------  1 root root 10, 236 May 13  2016 control
lrwxrwxrwx  1 root root       7 Apr  6 10:01 docker-202:1-294926-7197dc0c036efa8d2a4546962f6caf8ab23f2a652a3ffd9c9b1936f44f499ed7 -> ../dm-7
lrwxrwxrwx  1 root root       7 Jun 10  2016 docker-thinpool -> ../dm-6
lrwxrwxrwx  1 root root       7 Jun 10  2016 docker-thinpool_tdata -> ../dm-4
lrwxrwxrwx  1 root root       7 Jun 10  2016 docker-thinpool_tmeta -> ../dm-3
lrwxrwxrwx  1 root root       7 Jun 10  2016 docker-thinpool-tpool -> ../dm-5

Pro jistotu jsem zkusil teda i ty symlinky

  --device-write-bps /dev/mapper/docker-thinpool:10m --device-read-bps /dev/mapper/docker-thinpool:10m \
  --device-write-bps /dev/mapper/docker-thinpool_tdata:10m --device-read-bps /dev/mapper/docker-thinpool_tdata:10m \
  --device-write-bps /dev/mapper/docker-thinpool-tpool:10m --device-read-bps /dev/mapper/docker-thinpool-tpool:10m \

a taky nic

@ondrejhlavacek
Copy link
Member Author

ondrejhlavacek commented Apr 27, 2018

Ale myslím, že můžeme udělat docela rozumnej workaround. Kontejner má omezení na 10 GB, do něj se mountuje /data a /tmp a ty už omezit umíme. Kdyby někdo četl nebo zapisoval nekonečnou smyčku, tak mu v / dojde velice rychle místo a v /tmp nebo /data už bude bandwidth omezená.

@Halama
Copy link
Member

Halama commented Apr 27, 2018

jo to by mohlo být ok

@ondrejhlavacek
Copy link
Member Author

--cpus 2 se bude muset revidovat
https://keboola.slack.com/archives/C02CGRFHN/p1525174913000069

@ondrejhlavacek
Copy link
Member Author

#289 - omezil jsem defaultně IO na 50 MB/s

@odinuv
Copy link
Member

odinuv commented May 13, 2018

merged in 51373ee

@odinuv odinuv closed this as completed May 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants