Además de la opción de usar un pipe:

10 * * * * /usr/local/bin/micomando 2>&1 | mail foo@bar.com

Podemos usar la variable MAILTO, que por defecto manda un correo a root, y poner cualquier dirección de correo. Además, si necesitamos usar un correo determinado solo para una tarea podemos hacer lo siguiente:

MAILTO=”foo@bar.com”
10 * * * * /usr/local/bin/micomando
MAILTO=”foo_perez@bar.com”
10 * * * * /usr/local/bin/miotrocomando

También podríamos usar multiples destinatarios simplemente separandolos por comas:

MAILTO=”foo@bar.com,foo_perez@bar.com”

Con la primera opción tenemos la ventaja de poder modificar el asunto, enviar copias ocultas, etcétera, con la segunda opción tenemos la ventaja de que incluso si el comando falla porque nos hemos equivocado al escribirlo, nos manda un mail con el error.

Solucion propuesta :

#!/bin/bash
source_dir=/mydir
target_dir=/newdir

###  GETTING THE LIST OF FILES  ###

find $source_dir -type f -name “*” -print0 | xargs -0 ls > $target_dir/files_list.txt

while read line
do
  size=`du $line | awk ‘{print $1}’`
  #echo $line
  #echo $size
  if [ $size -eq 0 ]
  then
      echo “DELETING $line” >> $target_dir/empty_files.txt
      rm $line
  fi

done < $target_dir/files_list.txt

Solucion propuesta:

find $source_dir -size 0 -delete

Vamos directamente a un caso practico, moviendo 500.000 ficheros con find -exec ; tardamos 88 minutos:

# find /target/tmp/ -type f | wc -l
524275
# time find /target/tmp/ -type f -name ‘*’ -exec mv {} /rescaling/test/ ;

real    88m23.913s
user    5m12.872s
sys    81m43.738s

Si usamos -exec comando + bajamos a 4m30s:

# ls -1 /target/tmp/ | wc -l
524276
# time find /target/tmp/ -type f -name ‘*’ -exec mv -t /rescaling/test/ {} +

real    4m30.750s
user    0m9.777s
sys     1m35.633s

Y como bonus final, con find | xargs, se tardan menos de 3 minutos:

# ls -1 /target/tmp/ | wc -l
524276
# time find /target/tmp -type f -print0 | xargs -P 0 -0 -I {} mv {} /rescaling/test/

real    2m42.905s
user    3m38.539s
sys    14m5.651s

La explicacion, es que en el primer comando, al usarse “-exec comando ;” , lo que ocurre es que se ejecuta un comando mv por cada fichero. Cuando se usa “-exec comando +”, cada comando es agregado al comando y se ejecuta a continuacion, por lo que, tal y como explica la pagina man de find, esto hace que el total de invocaciones es mucho menor y de ahi esa mejora enorme en el rendimiento. Este compartiendo es el mismo que cuando usamos xargs, la diferencia de rendimiento en este caso radica en usar la opcion “-P” que crea tantos procesos como les indiquemos, o infinitos si usamos “-P 0”.

En este ejemplo tenemos una maquina virtual con 8 cores:

processor       : 7
vendor_id       : GenuineIntel
cpu family      : 6
model           : 45
model name      : Intel(R) Xeon(R) CPU E5-2650 0 @ 2.00GHz
stepping        : 7
cpu MHz         : 2000.000
cache size      : 20480 KB

Y tenemos 1 filesystem con un millon de ficheros, y otro totalmente lleno (espacio o inodos) como por ejemplo:

Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/mapper/vgTemp-rescaling
                     16777216 1000012 15777204    6% /rescaling
                     
/dev/mapper/vgTarget-target
                      524288  524288       0  100% /target

Pues bien si intentamos moverlos con find+xargs:
time find /rescaling/test/ -type f -print0 | xargs -P 0 -0 -I {} mv {}  /target/tmp

Evidentemente el comando dara errores del tipo:

mv: cannot create regular file `/target/tmp/219449-mod.tiff’: No space left on device
mv: cannot create regular file `/target/tmp/171387-mod.tiff’: No space left on device

El numero de procesos se disparara:
[root@vmlbcipacl63 ~]# ps aux | grep mv | wc -l
12262

Y el load tambien:

top – 12:09:34 up 12 days, 21:04,  5 users,  load average: 11861.25, 9365.14, 5167.78

Pero si vemos las CPUs, carga real no hay:

Tasks: 12224 total,   2 running, 12222 sleeping,   0 stopped,   0 zombie
Cpu0  :  7.9%us, 25.5%sy,  0.0%ni, 63.6%id,  2.6%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu1  :  5.9%us, 19.0%sy,  0.0%ni, 69.4%id,  4.7%wa,  0.0%hi,  0.9%si,  0.0%st
Cpu2  :  2.9%us, 18.4%sy,  0.0%ni, 74.9%id,  3.2%wa,  0.0%hi,  0.6%si,  0.0%st
Cpu3  :  1.5%us, 18.8%sy,  0.0%ni, 61.5%id, 17.6%wa,  0.0%hi,  0.6%si,  0.0%st
Cpu4  :  2.3%us, 29.9%sy,  0.0%ni, 62.8%id,  4.4%wa,  0.0%hi,  0.6%si,  0.0%st
Cpu5  :  1.8%us, 11.9%sy,  0.0%ni, 76.8%id,  8.9%wa,  0.0%hi,  0.6%si,  0.0%st
Cpu6  :  3.8%us, 50.4%sy,  0.0%ni, 41.6%id,  3.5%wa,  0.0%hi,  0.6%si,  0.0%st
Cpu7  :  2.4%us, 30.4%sy,  0.0%ni, 60.5%id,  6.2%wa,  0.0%hi,  0.6%si,  0.0%st

La maquina sigue siendo totalmente usable y no hay problema ejecutando comandos, esto es debido a que el load average no es mas que la media de procesos que estan demandando atencion de la cpu, y debido a que usamos el parametro -P de xargs (numero de procesos, siendo 0 que cree todos los procesos que pueda) se crea un proceso por cada intento de mover un fichero, y aunque este solo haga uso de la cpu para notificar que no puede ejecutarse (por falta de espacio), tiene que esperar su turno correspondiente. Si hubiera espacio/inodos suficientes, la carga subiria pero no de forma tan espectacular.

Viernes, casi mediodía, aparece el CEO:
“Necesitamos recomendaciones para performance de sistemas de ficheros con millones de ficheros pequeños”, así sin vaselina ni nada.

Como no tengo una bola de cristal, lo primero que comenté fue la necesidad de tener los detalles del tipo de carga de trabajo, características de los sistemas involucrados, aplicaciones, etcétera Ya que no hay recomendaciones mágicas que sirvan para todas las condiciones.

Después de ponerme en contacto con varias personas, y de algunas reuniones, obtenemos en claro cual era el problema real.

Hay un procedimiento diario para tratamiento de ficheros de froma que procesa los ficheros desde un filesystem origen, los transforma y los “coloca” en un filesystem destino.

Evidentemente antes de mirar nada, la culpa de todo la tenia Linux y los sistemas de ficheros ext4.

Desde el principio dijimos que aunque podría haber posibles mejoras que hacer, en general ext4 es la recomendación por defecto para este tipo de carga de trabajo, pero que lo mas importante era tener los detalles del proceso para ir analizando parte por parte los posibles cuellos de botella.

Conseguimos un conjunto de ficheros de prueba, 57K, que en las pruebas iniciales tardaban 34 minutos en procesar. Como aun no teníamos los comandos para probar, lo primero que probamos fue crear 2 filesystems en ram para ver la diferencia, y en este caso se llego a procesar en 25 minutos, una mejora sustancial, pero insuficiente, y que volvía a indicar que el problema muy posiblemente no fuera de los filesystems.

Finalmente al probar con los comandos en consola, vimos que con el comando original:

“/opt/bin/app” -input “/filesys1/”* -dir “/filesys2/tmp/” 

El proceso tenia un retraso enorme en empezar a escribir en disco, del orden de mas de 20 minutos, y eso nos dio una pista del problema:

Como el parámetro para seleccionar los ficheros originales usaba el comodín ‘*’ fuera de las comillas, bash expandía el resultado de forma, que construía un comando con un argumento por cada fichero origen, es decir 57.000 argumentos. Cambiamos el comando a:

“/opt/bin/app” -input “/filesys1/*” -dir “/filesys2/tmp/” 

Y el proceso empezó a escribir en disco inmediatamente , y tardó 2m30s en lugar de los 25 minutos, una mejora del 1000%, no está nada mal para unas simples comillas :)

Esperemos que la próxima vez entiendan que antes de echar la culpa a Linux, hagan un análisis de los elementos involucrados, dividan las tareas y vayan delimitando lo máximo posible el problema.

Pegatinas patrocinadas por Alexis Solanas

Pues, tal y como dice el título, he vuelto a Red Hat. En este caso es en Madrid y como consultor de infraestructura, es decir que mi trabajo es ayudar a clientes de Red Hat a implementar sus soluciones y su forma de trabajar. Esto ultimo es muy importante para mí, que una de las tareas de mi trabajo sea fomentar el uso de Software Libre, trabajo colaborativo, etcétera es muy motivante.
La verdad es que desde que dejé Farnborough hace ya mas de 2 años, siempre había tenido la sensación de que algún día volvería a Red Hat, de hecho apenás perdí contacto con mis (ex)compañeros. Porqué en Madrid? Pues simplemente es dónde surgió la oportunidad y porque creo que el cambio para la familia  es más sencillo.

Aprovecho para contar que mis 2 años en RipLife han sido geniales, en lo profesional porque he trabajado en un entorno “heterogeneo” en el que he tenido que aprender mucho sobre la marcha, no tanto técnicamente, sino sobre todo a nivel de procedimientos:

  • Trabajo en equipo, cuando el equipo esta en oficinas en los extremos del planeta y tu turno esta a medias entre los 2.
  • Tener que aportar soluciones al instante en momentos de panico, en realidad apenas me toco vivir momentos en los que el problema fuera de sistemas, pero estar en mitad de la batalla aporta experiencia.
  • Operaciones especiales, como trabajar fines de semana casi sin parar.
  • Guardias los fines de semana para cubrir eventos que terminan a las 2 de la madrugada.

Pero como comprendereis la mayoría de estas cosas serían marrones insufribles sino fuera por el equipo humano que se formó, gente que no solo es buena tecnicamente y siempre dispuesta a ayudar, sino que siempre estaba buscando una oportunidad para bromear o hacer alguna putadilla de esas que hacen gracia.

Respecto a Madrid, la verdad es que por ahora lo que mejor conozco son los IKEAs (He estado en los 3 que hay, y varias veces), ya que los 2 primeros meses he estado compartiendo piso en pleno centro, Gran Via, pero no he tenido tiempo para hacer apenas turismo, solo un dia pude darme una vuelta tranquilo.

Como finalmente mi dedicación va a ser en exclusiva para un cliente cuyas oficinas estan en “La Finca”, pues hemos decicido alquilar un piso en Pozuelo de Alarcón, por varios motivos:

  • Zona tranquila y donde hay familias con niños, para que las peques puedan jugar.
  • Colegio Publico bilingüe con plazas para el curso de María, justo al final de la calle.
  • Apenas 25 minutos de trayecto en transporte publico a mi trabajo.
  • Farmacia, comercios y supermercados cercanos.

La mudanza la completaremos este fin de semana, yo he ido comprando los muebles en IKEA y los voy montando por la tarde/noche. Y mis mujeres vendrán el sábado junto con el resto de muebles, y por fin volveremos a estar juntos más de 2-3 seguidos :)

Seguiremos informando….

Install fabric

Use your software package manager to install it. By instance if you use Fedora just run:

yum install fabric

Create fabfile.py

from __future__ import with_statement
from fabric.api import *
import fabric.contrib

env.user = ‘jramirez’
env.password = ‘YourPassword’

def ntpd_stop():
sudo(‘/sbin/service ntpd stop’)
sudo(‘/sbin/chkconfig ntpd off’)

def ntpd_status():
run(‘/sbin/service ntpd status’)
run(‘/sbin/chkconfig –list ntpd’)

def multiplehosts():
“””Loads a group of hosts from a config file.
hostsfile: name of the group file, one host per line
“””
hostsfile = ‘TEST-nopp.txt’
base_dir = ‘./’
from os.path import join, abspath, expanduser
filename = abspath(expanduser(join(base_dir, hostsfile)))
try:
fhosts = open(filename)
except IOError:
abort(‘file not found: %s’ % filename)

def has_data(line):
“””‘line’ is not commented out and not just whitespace.”””
return line.strip() and not line.startswith(‘#’)

env.hosts = [ line.strip() for line in fhosts
if has_data(line)]

How to apply the change:

fab multiplehosts ntpd_status

With this command you use the multiplehosts function to populate the env.hosts list, that is the one use it by fabric, and the use the ntpd_status function to run some commands.
In fabric there are two basic ways of running commands:

  • run: To run the command with the user privilege
  • sudo: To run the command with root privileges, always depending of sudoers settings

Configuration:

* Set env.user with the user to login
* Set env.password with the user password
* Set hostsfile, inside multiplehosts, to set the file with the list of servers where run the commands

Extra settings:

* You can set env.warn_only = True to continue after errors

Trying it with a single or a few hosts:

fab ntpd_status -H host1,host2…

More information
Fabric official documentation

Recursos en internet para aprender Python hay infinitos, pero he recopilado unos cuantos enlaces que me parecen indispensables si quieres iniciarte en Python o incluso en la programacion en general:

– El temario de la asignatura Introduction to computer science and programming del MIT, que incluye los videos de las 24 horas de clases, las transcripciones y los ejercicios y examenes

Las clases de google: Incluye 7 videos y el codigo fuente de los ejercicios

El libro How to think like a computer Scientist

La serie “Discover Python” (ibm developerworks)

Python for system administrators (ibm developerworks)

Luego existen infinidad de otros recursos, de muchisimos niveles y especializados muchos temas, como por ejemplos los videos de ShowMeDO

Bueno, a todos aquellos que me conoceis no hace falta que os explique el porque necesito ponerme en forma :)
En primer lugar comentar que este desafío lo empezé en realidad ya hace mas de 2 meses, desde entonces he perdido unos 10 kilos. ¿Cómo? Muy fácil, descartando radicalmente de mi dieta las cosas que mas perjudican: chocolates, frutos secos, golosinas, etcetera.
No he dejado de comer lo que me apetece, pero he rebajado en algo las cantidades y sobre todo la frecuencia de las comidas que mas engordan tipo fast food, intento cenar temprano y dejar para el almuerzo lo mas pesado.
Aun me quedan hábitos que mejorar: hacer deporte semanalmente, beber mas agua, tomar alguna pieza de fruta a media mañana, pero lo siguiente es empezar una dieta guiado por un endocrino, tengo cita para el martes que viene, así que ya no tendré mas excusas.

El desafío
Para hacer todo este desafío mas interesante me comprometo a aceptar apuestas, por ejemplo, me comprometo a perder 20 kilos desde el martes 24 de Mayo, día que me pesaré en el endocrino, hasta el 31 de Diciembre de 2011. Por cada kilo que NO pierda, donaré un kilo de comida a alguna ong. Si alguien quiere apostar “contra mi”, si pierdo donaré un kilo de comida más por cada kilo no perdido, pero si gano esa persona tiene que donar 5 kilos.
Toda esta idea de las donaciones las he tomado de este blog de otro malagueño: http://www.whattimesailing.com/
Así que ya sabéis el que se quiera apuntar que deje un comentario en el blog o me mande un mail.

Traducido a partir de: http://www.cyberciti.biz/faq/linux-add-a-swap-file-howto/

Hay que usar el comando dd para crear un fichero, a continuacion usar mkswap para habilitarlo como swap, usar swapon para activarlo y configugrar fstab para hacer el cambio permanente.

a) Logearse como usuario root

b) Ejecuta el siguiente comando para crear un fichero de 1GB(1024KB * 1024):
# dd if=/dev/zero of=/swapfile1 bs=1024k count=1024

c) Habilitarlo como swap:
# mkswap /swapfile1

d) Activar /swapfile1 como swap momentaneamente:
# swapon /swapfile1

e) Para activar /swapfile1 en cada inicio, hay que agregar una entrada al fichero /etc/fstab:

/swapfile1 swap swap defaults 0 0

g) Como verificar si el fichero swap esta activado o no? Simplemente ejecuta el comando free:
$ free -m