Redis: Almacenamiento de datos NoSQL clave-valor en memoria

Redis

Redis (REmote DIctionary Server) es un sistema de almacenamiento en memoria volátil en RAM basado en registros clave-valor NoSQL (opcionalmente podemos hacer que sea persistente o durable). También soporta la replicación de datos maestro-esclavo. Actualmente Redis es usado por: TwitterInstagramGitHubFlickr, o Digg.

¿Pero en que casos puede ser necesario un sistema así?

Por ejemplo para el análisis y procesamiento de datos en tiempo real, supongamos que obtenemos muestreos periódicos de un sensor y cada nueva lectura vuelve a calcular un valor basándonos en las lecturas previas, en ese caso un sistema de gestión de base de datos clásico como MySQL realizando transacciones a disco puede no ser muy eficiente comparado con Redis (tiempos de respuesta menores).

Un sistema de comunicaciones basado en mensajería por ejemplo.

Redis incluye clientes para la mayoría de los lenguajes de programación conocidos (PHP y C# entre ellos claro).

Redis está escrito en C y está ideado para sistemas Linux, aún así existe un desarrollo para sistemas MS Windows.

Instalación en Windows

Podemos descargar versiones binarias del instalador del siguiente enlace en GitHub. La versión que he descargado es Redis-x64-3.2.100.zip.

 

 

El paquete apenas ocupa 5MB.  Una vez descomprimido tenemos todos los binarios y utilidades básicas necesarias.

Abrimos una consola DOS y ejecutamos redis-server.exe.

Una vez ejecutado la consola nos muestra información valiosa, se está ejecutando a la escucha en el puerto 6379, para que ejecute el fichero de configuración copiamos el fichero redis.windows.conf a redis.conf y ejecutamos:

C:\> redis-server.exe redis.conf

Redis incluye la utilidad redis-benchmark.exe para poner a prueba su velocidad, simula la ejecución de comandos de forma simultanea desde varios clientes.

Enlaces externos

 

NLog: Sistema de logging gratuito y de código abierto para .Net

Siempre que comienzo proyectos de envergadura antes me pongo al día de las utilidades básicas que necesita mi aplicación, un sistema de logging para mi es esencial para seguir la ejecución del código, en lenguaje C otras veces he usado liblogger, es bastante básico pero cumple con mis propósitos, se integra fácilmente con el código principal y es capaz de escribir los logs en ficheros de texto plano en disco.

Para C# uso NLog, es muy flexible en su configuración, puede enviar los logs al clásico fichero, con innumerables opciones de configuración para dar nombre al fichero destino, rotar ficheros cuando alcanzan determinado tamaño y todo lo que nos ocurra. Pero a parte de trabajar con ficheros como toda la vida también puede enviar los logs a una base de datos, al sistema de eventos de windows o usando la red local a un servidor en otra máquina por ejemplo (ver apartado “Targets” en GitHub).

La instalación de NLog es muy sencilla usando el gestor de paquetes de Visual Studio, escribimos las siguientes líneas (previamente creamos un proyecto de consola):

PM> Install-Package NLog -Version 4.4.11

PM> Install-Package NLog.Config

NLog.Config es para poder configurar NLog para nuestra aplicación en un fichero XML, cuando lo instalamos añade automáticamente un fichero NLog.config al proyecto, borramos su contenido y copiamos las siguientes líneas:


<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" > <!-- permite cambiar configuración sin parar ejecución! -->

<!-- crea subcarpeta por día por ejemplo logs/2017-07-23/ -->
<variable name="logDirectory" value="${basedir}/logs/${shortdate}"/>
<!-- Fichero con fecha Ejemplo logs/2010-06-08.log -->
<!-- <variable name="logDirectory" value="${basedir}/${shortdate}.log"/> -->

<targets>
<target xsi:type="NLogViewer"
name="viewer"
includeSourceInfo="true"
address="udp://127.0.0.1:9999"/>
<target xsi:type="ColoredConsole" name="colored_console"/>

<target
layout="${longdate} ${logger} ${message}"
name="file1" xsi:type="File" fileName="${logDirectory}/log.log"/>

</targets>

<rules>
<logger name="*"
minlevel="Trace"
writeTo="viewer,colored_console,file1" />
</rules>
</nlog>

No voy a entrar a describir en detalle todos los campos (para eso está la documentación oficial), lo que hacemos es definir 3 destinos para los logs.

El primero NLogViewer envía los logs a un visor externo en una dirección IP y un puerto determinado, yo lo he usado para enviar los logs a una aplicación gráfica llamada Sentinel. Las primeras pruebas que he realizado funciona de maravilla.

El siguiente destino es la consola coloreada el nivel de logs:

El tercero es el clásico fichero, he usado algunas propiedades para que se guarde en una carpeta con la fecha actual.

Por último la sección “rules” permite filtrar los logs de salida por tipo y que destinos se usan, en un momento dado tal vez queramos desactivar la salida por consola por ejemplo.

El parámetro “autoReload” a True permite que cambiemos el fichero de configuración sin necesidad de detener la aplicación.

Para realizar unas pruebas muy sencillas editamos Program.cs y lo dejamos así:

Un ejemplo del fichero NLog.config que me he topado por Internet incluso pemite enviar los logs a GMail. Me parece extremadamente útil para enviar errores fatales a los administradores de la aplicación que normalmente no estarán todo el día leyendo los logs esperando a que pase algo.

 

Por último debemos tomar en cuenta si queremos que el procesamiento sea asíncrono (para evitar bloqueos de nuestra aplicación  principal ,

C# BasicMSMQClient: Ejemplo básico de envío de mensaje a una cola MSMQ

Con el servicio MSMQ arrancado en el PC local Win7 (ver “MSMQ: Microsoft Message Queuing“) vamos a crear una aplicación C# mínima para publicar un mensaje en la cola “test_queue”.

Para  poder usar el espacio de nombres “System.Messaging” y sus clases una vez creado el proyecto debemos añadir la referencia en el explorador de soluciones (CTRL+ALT+L).

Después añadimos el espacio de  nombres “using System.Messaging;” que nos proporciona las clases necesarias para trabajar con MSMQ.

La única clase que vamos a necesitar para un ejemplo mínimo es MessageQueue. Esta clase nos permite acceder a una cola existente o incluso crearla. Al constructor de la case le pasamos una cadena con la ruta de la cola. Cuando una cola es privada como la del ejemplo esta no se pública en los servicios de AD (Active Directory),  una cola privada es para ser empleada solo en el ámbito del PC local (entre dos aplicaciones en el mismo servidor por ejemplo).

El método send manda un mensaje no transaccional con una etiqueta.

Aquí tenéis el ejemplo:

Cada vez que ejecutamos la aplicación un nuevo mensaje se almacena en la cola (gestionar las colas ejecutando con compmgmt.msc).

Podemos abrir cada mensaje para ver sus campos:

 

 

 

 

 

 

 

C# BasicLinkedList: Listas enlazadas

Vamos a seguir desarrollando el post anterior (“C# Clases autorreferenciadas“) para generar una lista enlazada, una lista enlazada es una colección lineal o una secuencia de nodos representados con clases autorreferenciadas. El acceso a la lista se realiza desde el primero nodo (raíz o head) y se recorre accediendo al miembro que apunta al siguiente nodo y así hasta el final (el miembro del último nodo que apunta al siguiente se define como null para evitar errores). Normalmente las listas tienen las operaciones comunes para trabajar con sus nodos, vamos a definir métodos para:

  • Construir una lista vacía y darle un nombre.
  • Insertar un nodo en la cabecera.
  • Insertar un nodo al final.
  • Eliminar el primer nodo de la lista.
  • Eliminar un nodo del final de la lista.
  • Comprobar si una lista está vacía.
  • Imprimir por pantalla el contenido.
  • Obtener el número de elementos o nodos de la lista.

Clase para definir un nodo

Similar al ejemplo anterior definimos una clase que represente un nodo. Definimos dos constructores, el segundo permite crear un nodo y definir el nodo al que apunta como siguiente elemento en la lista.

Lo más remarcable de la clase es la referencia object. Nos permite almacenar tipos de datos simples como si fueran objetos. El tipo object es un alias para Object en .NET. Todos los tipos de variables son herencia directa de este tipo. Podemos asignar valores de cualquier tipo a variables de tipo object. Cuando una variable se convierte a un tipo object a esta operación se le llama boxing o boxed. Cuando se realiza la operación inversa se denomina unboxing.

Clase lista

La clase lista tiene contiene como miembros head y tail. Son respectivamente referencias al primer y último nodo de la lista, también definimos una variable string para asignar un nombre a la lista.

 

Definimos un método que nos resultará de utilidad más adelante, el método IsListEmpty retorna true si la cabeza de lista apunta a null.

Ahora definimos un método para operar sobre la lista insertando un nuevo nodo al inicio de la misma.  Si la lista esta recién creada o vacía la cabeza y la cola apunta al nuevo y único la misma. En caso contrario la cabeza apunta al nuevo nodo y le pasamos el nodo de cabeza actual como miembro para que quede en segundo lugar.

Para añadir un nodo al final definimos el siguiente método:

Antes de continuar con un método para borrar un elemento del inicio de la lista vamos a definir una clase EmptyListException para lanzar una excepción cuando se producen operaciones ilegales sobra la lista, por ejemplo si la lista está vacía. Usamos System.ApplicationException para excepciones generadas por nuestra programa.

Ahora ya podemos crear un método para borrar un elemento de la cabecera de la lista. Si la lista está vacía lanza una excepción que podemos capturar y tratar desde el programa principal. Después obtenemos el miembro del nodo de cabecera y restablece las referencias del primer y último nodo (si solo hay un nodo en la lista head y last quedaran a null, si hay más de un elemento avanzamos al siguiente nodo la cabecera).

Visto el anterior ejemplo borrar el último nodo es similar. Pero en este caso el método que debemos seguir  nodo no es muy eficiente (esto se solucionaría con una lista doblemente enlazada). Recorremos desde el primero nodo uno de detrás de otro hasta que el nodo siguiente no sea el último, de esta manera hacemos que apunte a null quedando fuera el último nodo.

Ahora solo nos queda un método para imprimir los nodos de la lista.

Ahora veamos como se puede utilizar:

Referencias externas

 

C# Clases autorreferenciadas

Una clase autorreferenciada es muy común para almacenar datos de forma dinámica y consumirlos a medida que los necesitamos en otro proceso, una clase autorreferenciada contiene un miembro de la clase que hace referencia a un objeto del mismo tipo. La unión de las clases referenciadas crea una lista de nodos que podemos recorrer accediendo de forma sucesiva desde el nodo raíz  al miembro del nodo que apunta al siguiente y así sucesivamente.

El ejemplo de abajo es como se organiza un array bidimensional en memoria, realmente se reservan zonas de memoria contiguas como en un array de una dimensión.

Frente a un array estático (los elementos se organizan en memoria de forma contigua y su tamaño se reserva en la declaración de la variable)  con un número de elementos determinados tiene una importante ventaja, una lista basada en nodos autoenlazados puede modificar su tamaño de forma dinámica en tiempo de ejecución (aunque también tiene un coste computacional que puede afectar al rendimiento de nuestro programa el manejo de grandes estructuras de memoria que reservan y liberan memoria según su necesidad).

El ejemplo de arriba es un ejemplo muy básico de un clase autorreferenciada, por supuesto los nodos pueden contener todos los datos que necesitemos de cualquier tipo.

Para ir añadiendo nuevos nodos durante la ejecución de nuestro programa haremos uso de la reserva de memoria dinámica con el operador new, este operador recibe como operando el tipo de objeto que se asignará de forma dinámica y devuelve una referencia a un objeto de este tipo.

Basándonos en esta arquitectura podemos crear listas enlazadas, colas o arboles. Cada tipo de estructura tiene propósitos diferentes y puede ser aplicado según el problema que debamos resolver.

 

 

C# SerialConsoleApp4: Mejoras gestión línea serie, pines RTS (Request to Send) y CTS (Clear to Send)

El conector RS232 incluye dos pines físicos del conector DB9, RTS (Request To Send) y CTS (Clear To Send).

Estos dos hilos permiten al receptor y emisor avisarse el uno al otro sobre su estado.

Cuando el emisor quiere enviar información activa el pin RST que produce interrupción en el receptor, si el receptor está preparado para recibir le responde usando el pin CTS.  Este es un sistema de control del flujo de información mediante hardware.

La clase SerialPort define atributos para habilitar / deshabilitar este control, RtsEnable (Obtiene o establece un valor que indica si la señal Solicitud de envío (RTS) está habilitada durante la comunicación en serie) y DtrEnable (Obtiene o establece un valor que habilita la señal Terminal de datos preparado (DTR) durante la comunicación en serie).

Añadimos las siguientes líneas al método OpenCOMPort:

Definimos un método delegado COMPortEvtPinChanged para que reciba los cambios de estado de los pines.