Parallelisation (Bash)

Uit De Vliegende Brigade
Ga naar: navigatie, zoeken

WordPress benaderen via de WP-CLI, is vreselijk langzaam. Gelukkig kun je dat zelf in Bash paralleliseren!

Voorbeeld

Zonder parallelisation

Dit commando duurt ca. 5s.:

wp wc shop_order list --user=4 --field=id | xargs -n1 wp wc shop_order delete --user=4 --force=1

Ditzelfde commando op een VPS met 4 ipv 2 CPU's, duurt even lang (zelfs iets langer). Dat was geen verbazing: Dit PHP-commando is niet echt te paralleliseren, want het is één seriele aangelegenheid. Via tops en ps kon ik zien dat er wel degelijk aparte processen aan te pas komen. Zoiets als:

  • Commando-als-geheel
  • xargs
  • php
  • MySQL.

Maar nog steeds is er effectief geen sprake van parallelisatie, omdat deze processen welliswaar apart zijn, maar nog steeds seriëel worden doorlopen. Hetzelfde probleem als dat gamers meer geholpen zijn bij hele snelle processoren, dan bij veel processoren. Helaas kan ik bij TransIP niet voor snellere processoren kiezen. Alleen voor meer processoren - Lees verder!

Parallelisatie

In Bash kun je met & aangeven dat het volgende commando kan starten voordat het huidige commando (waar de & bij hoort) beëindigt is. En daarmee blijk je prima te kunnen paralleliseren! Dit is dezelfde code als hierboven, ca. 100x toegepast:

# Parallel (2x)
########################################
#
date
	wp wc shop_order list --user=4 --field=id --per_page=50             | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=50 --offset=50 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
date
# Parallel (4x)
########################################
#
date
	wp wc shop_order list --user=4 --field=id --per_page=25             | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=25 --offset=25 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=25 --offset=50 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=25 --offset=75 | xargs -n1 wp wc shop_order delete --user=4 --force=1	
date
# Parallel (8x)
########################################
#
date
	wp wc shop_order list --user=4 --field=id --per_page=12             | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=12 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=24 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=36 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &	
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=48 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=60 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=72 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=84 | xargs -n1 wp wc shop_order delete --user=4 --force=1	
date
# Parallel (16x)
########################################
#
date
	wp wc shop_order list --user=4 --field=id --per_page=12              | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=12  | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=24  | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=36  | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=48  | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=60  | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=72  | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=84  | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=96  | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=108 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=120 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=132 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=144 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=156 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=168 | xargs -n1 wp wc shop_order delete --user=4 --force=1 &
	wp wc shop_order list --user=4 --field=id --per_page=12 --offset=180 | xargs -n1 wp wc shop_order delete --user=4 --force=1
date
  • De truuk is, dat alle regels - behalve de laatste - een & hebben. Daardoor worden er steeds het gespecificeerde aantal parallele commando's geëxecuteerd
  • Het laatste parallele commando heeft geen &. Maw. het script gaat pas verder als deze laatste regel is uitgevoerd. Daardoor zijn er steeds min-of-meer het gespecificeerde aantal parallele commando's actief (dit is niet 100% efficiënt, maar komt een heel eind)
  • Als alle regels een & hebben, dan is er geen limiet aan het aantal parallele commando's. Dat geeft twee soorten foutmeldingen: (1) ID's die niet blijken te bestaan, omdat een ander proces ze al heeft verwijderd (2) Out-of-sockets (of hoe dat moge heten) voor MySQL: Er kunnen niet meer IPC's (als dat de juiste term in) worden opgezet
  • Het is geen ramp om meer commando's parallel te executeren dan er cores zijn: Normaal doet een computer toch al een hoop dingen parallel. Dan kan dit er ook wel bij.
  • Het is cruciaal dat de workload van het oorspronkelijke commando opgesplitst kan worden (in dit geval: 100x hetzelfde commando maar met verschillende argumenten). Dat gaat hier middels --per_page en --offset
  • Waarschijnlijk is deze code efficiënter te maken, door in één commando alle argumenten te verzamelen (dat is één wp wc shop_order list-commando, en de uitkomst te distribueren over parallele wp wc shop_order delete-commando's.

Bronnen