08 septiembre 2017

Java + SQL: ¿Por qué son importantes las declaraciones preparadas (prepare statement)?

Las instrucciones de procesamiento pueden ser una operación costosa, pero las bases de datos se escriben ahora de tal manera que se minimiza esta sobrecarga. Sin embargo, estas optimizaciones necesitan ayuda de los desarrolladores de aplicaciones si queremos aprovecharlas. En este artículo se muestra cómo el uso correcto de las instrucciones preparadas puede ayudar significativamente a una base de datos realizar estas optimizaciones.
Las bases de datos tienen un trabajo duro. Ellos aceptan consultas SQL de muchos clientes simultáneamente y ejecutan las consultas de la manera más eficiente posible contra los datos. Las instrucciones de procesamiento pueden ser una operación costosa, pero las bases de datos se escriben ahora de tal manera que se minimiza esta sobrecarga. Sin embargo, estas optimizaciones necesitan ayuda de los desarrolladores de aplicaciones si queremos aprovecharlas. En este artículo se muestra cómo el uso correcto de PreparedStatements puede ayudar significativamente a una base de datos realizar estas optimizaciones.

¿Cómo ejecuta una base de datos una sentencia?

Obviamente, no esperes mucho detalle aquí; sólo examinaremos los aspectos importantes para este artículo. Cuando una base de datos recibe una sentencia, el motor de base de datos analiza primero la sentencia y busca errores de sintaxis. Una vez analizada la sentencia, la base de datos debe encontrar la forma más eficiente de ejecutar la sentencia. Esto puede ser computacionalmente bastante caro. La base de datos comprueba qué índices, si los hay, pueden ayudar o si debe realizar una lectura completa de todas las filas de una tabla. Las bases de datos utilizan estadísticas sobre los datos para averiguar cuál es la mejor manera. Una vez creado el plan de consulta, el motor de base de datos puede ejecutarlo.

Toma la energía de la CPU para hacer la generación del plan de acceso. Idealmente, si enviamos la misma declaración a la base de datos dos veces, entonces nos gustaría que la base de datos reutilizar el plan de acceso para la primera declaración. Esto utiliza menos CPU que si regeneró el plan una segunda vez.

Cachés de sentencias

Las bases de datos se sintonizan para hacer cachés de sentencias. Por lo general incluyen algún tipo de caché de instrucciones. Esta caché utiliza la instrucción en sí como una clave y el plan de acceso se almacena en la caché con la instrucción correspondiente. Esto permite al motor de base de datos reutilizar los planes para las sentencias que se han ejecutado anteriormente. Por ejemplo, si enviamos a la base de datos una sentencia como "select a, b from t where c = 2", entonces el plan de acceso calculado se almacena en caché. Si enviamos la misma sentencia más adelante, la base de datos puede volver a utilizar el plan de acceso anterior, ahorrándonos energía de la CPU.
Tenga en cuenta, sin embargo, que toda la sentencia es la clave. Por ejemplo, si luego enviamos la sentencia "seleccione a, b de t donde c = 3", no encontraría un plan de acceso. Esto se debe a que el "c = 3" es diferente del plan en caché "c = 2". Así por ejemplo:

For(int I = 0; I < 1000; ++I)
{
        PreparedStatement ps = conn.prepareStatement("select a,b from t where c = " + I);
        ResultSet rs = Ps.executeQuery();
        Rs.close();
        Ps.close();
}

Aquí no se utilizará el caché. Cada iteración del bucle envía una instrucción SQL diferente a la base de datos. Se calcula un nuevo plan de acceso para cada iteración y básicamente estamos lanzando ciclos de CPU usando este enfoque. Sin embargo, mira el siguiente fragmento:
PreparedStatement ps = conn.prepareStatement("select a,b from t where c = ?");
PreparedStatement ps = conn.prepareStatement("select a,b from t where c = ?");
For(int I = 0; I < 1000; ++I)
{
        ps.setInt(1, I);
        ResultSet rs = ps.executeQuery();
        Rs.close();
}
ps.close();

Aquí será mucho más eficiente. La sentencia enviada a la base de datos se parametriza usando el signo '?' marcador en el sql. Esto significa que cada iteración está enviando la misma sentencia a la base de datos con diferentes parámetros para el "c =?" parte. Esto permite que la base de datos reutilice los planes de acceso para la sentencia y haga que el programa se ejecute más eficientemente dentro de la base de datos. Esto básicamente permite que su aplicación se ejecute más rápido o haga más CPU disponible para los usuarios de la base de datos.

PreparedStatements y servidores J2EE

Las cosas pueden ser más complicadas cuando usamos un servidor J2EE. Normalmente, una sentencia preparada se asocia con una conexión de base de datos única. Cuando se cierra la conexión, se descarta el estado de preparación. Normalmente, una aplicación de cliente de grasa obtendría una conexión de base de datos y luego la mantendría durante toda su vida útil. También crearía todas las declaraciones preparadas con avidez o pereza. Ansiosamente significa que todos ellos se crean al mismo tiempo cuando se inicia la aplicación. Lazily significa que se crean como se utilizan. Un enfoque ansioso da un retraso cuando la aplicación se inicia, pero una vez que se inicia, entonces se realiza de manera óptima. Un enfoque lento proporciona un inicio rápido, pero a medida que se ejecuta la aplicación, las sentencias preparadas se crean cuando son utilizadas por primera vez por la aplicación. Esto da un rendimiento desigual hasta que se preparan todas las sentencias, pero la aplicación finalmente se instala y se ejecuta tan rápido como la aplicación ansiosa. Cuál es el mejor depende de si usted necesita un comienzo rápido o aún funcionamiento.
El problema con una aplicación J2EE es que no puede funcionar así. Sólo mantiene una conexión durante la duración de la solicitud. Esto significa que debe crear las instrucciones preparadas cada vez que se ejecuta la solicitud. Esto no es tan eficiente como el enfoque de cliente de grasa donde las sentencias preparadas se crean una vez, en lugar de en cada solicitud. Los proveedores de J2EE han notado esto y han diseñado la agrupación de conexiones para evitar esta desventaja de rendimiento.
Cuando el servidor J2EE da a su aplicación una conexión, no le está dando la conexión real; usted está consiguiendo un envoltorio. Puede verificar esto mirando el nombre de la clase para la conexión que se le da. No será una conexión de base de datos JDBC, será una clase creada por su servidor de aplicaciones. Normalmente, si llama cerca de una conexión, entonces el controlador jdbc cierra la conexión. Queremos que la conexión sea devuelta a la agrupación cuando close sea llamada por una aplicación J2EE. Hacemos esto haciendo una clase de conexión de proxy jdbc que parece una conexión real. Tiene una referencia a la conexión real. Cuando invocamos cualquier método en la conexión entonces el proxy reenvía la llamada a la conexión real. Pero, cuando llamamos a métodos como cerrar en lugar de llamar cerca de la conexión real, simplemente devuelve la conexión al grupo de conexiones y luego marca la conexión proxy como no válida, de modo que si la utiliza de nuevo, obtendremos una excepción.

El empaquetado es muy útil, ya que también ayuda a los implementadores de servidores de aplicaciones J2EE a agregar soporte para sentencias preparadas de una manera sensible. Cuando una aplicación llama Connection.prepareStatement, el controlador devuelve un objeto PreparedStatement. La aplicación, a continuación, mantiene el identificador mientras tiene la conexión y lo cierra antes de que cierra la conexión cuando finaliza la solicitud. Sin embargo, después de que se devuelva la conexión a la agrupación y más tarde reutilizada por la misma u otra aplicación, idealmente, queremos que se devuelva el mismo PreparedStatement a la aplicación.

J2EE PreparedStatement Cache

J2EE PreparedStatement Cache se implementa utilizando un caché dentro del gestor de la agrupación de conexiones del servidor J2EE. El servidor J2EE mantiene una lista de instrucciones preparadas para cada conexión de base de datos en el grupo. Cuando una aplicación llama a prepareStatement en una conexión, el servidor de aplicaciones comprueba si dicha sentencia fue preparada previamente. Si lo fuera, el objeto PreparedStatement estará en el caché y éste será devuelto a la aplicación. Si no, la llamada se pasa al controlador jdbc y se agrega el objeto query / preparedstatement en esa caché de conexiones.

Necesitamos una caché por conexión, porque así funcionan los controladores jdbc. Cualquier estado de preparación devuelto es específico de esa conexión.
Si queremos aprovechar esta caché, las mismas reglas se aplican como antes. Necesitamos usar consultas parametrizadas para que coincidan con las ya preparadas en la caché. La mayoría de los servidores de aplicaciones le permitirán ajustar el tamaño de este caché de instrucciones preparado.

En resumen

En conclusión, debemos utilizar consultas parametrizadas con declaraciones preparadas. Esto reduce la carga de la base de datos permitiéndole reutilizar planes de acceso ya preparados. Esta caché es de toda la base de datos, por lo que si puede organizar todas sus aplicaciones para utilizar SQL parametrizado similar, mejorará la eficiencia de este esquema de almacenamiento en caché como una aplicación puede aprovechar las sentencias preparadas utilizadas por otra aplicación. Esta es una ventaja de un servidor de aplicaciones porque la lógica que accede a la base de datos debe centralizarse en una capa de acceso a datos (ya sea un mapeador OR, un beans de entidad o un JDBC recto).

Por último, el uso correcto de sentencias preparadas también le permite aprovechar la caché de instrucciones preparada en el servidor de aplicaciones. Esto mejora el rendimiento de su aplicación, ya que la aplicación puede reducir el número de llamadas al controlador JDBC mediante la reutilización de una llamada de sentencia previamente preparada. Esto hace que sea competitivo con los clientes de grasa en función de la eficiencia y elimina la desventaja de no poder mantener una conexión dedicada.
Si utiliza sentencias preparadas parametrizadas, mejora la eficiencia de la base de datos y del código alojado de su servidor de aplicaciones. Ambas mejoras permitirán que su aplicación mejore su rendimiento.

06 septiembre 2017

¿Hay vida más allá de Oracle? Hoy presentamos Kibana de Elastic


Kibana es una plataforma de análisis y visualización de código abierto diseñada para trabajar con Elasticsearch. Utiliza Kibana para buscar, ver e interactuar con datos almacenados en los índices de Elasticsearch. Puede realizar análisis de datos avanzados y visualizar fácilmente sus datos en una variedad de gráficos, tablas y mapas.

Kibana facilita la comprensión de grandes volúmenes de datos. Su sencilla interfaz basada en navegador le permite crear y compartir rápidamente paneles dinámicos que muestran cambios en las consultas de Elasticsearch en tiempo real.

La configuración de Kibana es muy fácil. Puedes instalar Kibana y comenzar a explorar sus índices Elasticsearch en minutos - sin código, sin infraestructura adicional requerida.

Versión Elasticsearch

Kibana debe estar configurado para ejecutarse contra un nodo Elasticsearch de la misma versión. Esta es la configuración oficialmente admitida.

No se admite la ejecución de versiones de versiones mayores de Kibana y Elasticsearch (por ejemplo, Kibana 5.x y Elasticsearch 2.x) ni una versión menor de Kibana que sea más reciente que la versión de Elasticsearch (por ejemplo, Kibana 5.1 y Elasticsearch 5.0).

Ejecutar una versión menor de Elasticsearch que sea más alta que Kibana generalmente funcionará para facilitar un proceso de actualización donde Elasticsearch se actualiza primero (por ejemplo, Kibana 5.0 y Elasticsearch 5.1). En esta configuración, se registrará una advertencia en el inicio del servidor Kibana, por lo que sólo se pretende que sea temporal hasta que Kibana se actualiza a la misma versión que Elasticsearch.

Normalmente se admite la ejecución de versiones de versión de parche diferente de Kibana y Elasticsearch (por ejemplo, Kibana 5.0.0 y Elasticsearch 5.0.1), aunque alentamos a los usuarios a ejecutar las mismas versiones de Kibana y Elasticsearch hasta la versión de revisión.

Plataformas soportadas


Los paquetes de Kibana se proporcionan y se prueban contra Linux, Darwin y Windows. Dado que Kibana se ejecuta en Node.js, incluimos los binarios Node.js necesarios para estas plataformas. Ejecutar Kibana contra una versión de Node.js mantenida por separado no es compatible.

Como instalar Kibana en Windows

Kibana se puede instalar en Windows utilizando el paquete .zip.

La última versión estable de Kibana se puede encontrar en la página de descarga de Kibana. Otras versiones se pueden encontrar en la página de Publicaciones pasadas.

Descargue e instale el paquete .zip
Descargue el archivo de Windows .zip para Kibana v5.5.2 desde https://artifacts.elastic.co/downloads/kibana/kibana-5.5.2-windows-x86.zip

Descomprimirlo con su herramienta de descompresión favorita. Esto creará una carpeta llamada kibana-5.5.2-windows-x86, a la que nos referiremos como $ KIBANA_HOME. En una ventana de terminal, CD al directorio $ KIBANA_HOME, por ejemplo:

CD c: \ kibana-5.5.2-windows-x86

Ejecutar Kibana desde la línea de comandos
Kibana se puede iniciar desde la línea de comandos de la siguiente manera:

\ bin \ kibana

De forma predeterminada, Kibana se ejecuta en primer plano, imprime sus registros en STDOUT y se puede detener presionando Ctrl-C.

Configuración de Kibana
El servidor Kibana lee las propiedades del archivo kibana.yml al inicio. La configuración predeterminada configura Kibana para ejecutarse en localhost: 5601. Para cambiar el host o el número de puerto, o conectarse a Elasticsearch que se ejecuta en una máquina diferente, deberá actualizar su archivo kibana.yml. También puede habilitar SSL y establecer una variedad de otras opciones.

Puerto de servicio:
Valor predeterminado: 5601 Kibana es servido por un servidor back-end. Esta configuración especifica el puerto que se va a usar.

server.host:
Valor predeterminado: "localhost" Esta configuración especifica el host del servidor back-end.

server.basePath:
Permite especificar una ruta de acceso para montar Kibana en si se está ejecutando detrás de un proxy. Esto sólo afecta a las URL generadas por Kibana, se espera que su proxy elimine el valor de basePath antes de reenviar las solicitudes a Kibana. Esta configuración no puede terminar en una barra (/).

server.maxPayloadBytes:
Valor predeterminado: 1048576 El tamaño máximo de la carga útil en bytes para las solicitudes de servidor entrantes.

nombre del servidor:
Predeterminado: "your-hostname" Un nombre de visualización legible por humanos que identifica esta instancia de Kibana.

server.defaultRoute:
Valor predeterminado: "/ app / kibana" Esta configuración especifica la ruta predeterminada al abrir Kibana. Puede utilizar esta configuración para modificar la página de destino al abrir Kibana.

elasticsearch.url:
Predeterminado: "http: // localhost: 9200" La URL de la instancia de Elasticsearch para usar en todas sus consultas.

elasticsearch.preserveHost:
Valor predeterminado: true Cuando el valor de esta configuración es true Kibana utiliza el nombre de host especificado en la configuración server.host. Cuando el valor de esta configuración es false, Kibana utiliza el nombre de host del host que se conecta a esta instancia de Kibana.

kibana.index:
Default: ".kibana" Kibana usa un índice en Elasticsearch para almacenar búsquedas, visualizaciones y cuadros de mando guardados. Kibana crea un nuevo índice si el índice ya no existe.

kibana.defaultAppId:
Predeterminado: "discover" La aplicación predeterminada para cargar.

tilemap.url:
La URL del servicio de mosaico que Kibana utiliza para mostrar los mosaicos de mapa en las visualizaciones de mosaico. De forma predeterminada, Kibana lee esta url de un servicio de metadatos externo, pero los usuarios pueden reemplazar este parámetro para usar su propio servicio de mapa de mosaico. Por ejemplo: "https://tiles.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana"

tilemap.options.minZoom:
Valor predeterminado: 1 El nivel de zoom mínimo.

tilemap.options.maxZoom:
Valor predeterminado: 10 El nivel de zoom máximo.

tilemap.options.attribution:
Valor predeterminado: "© Elastic Maps Service (https://www.elastic.co/elastic-maps-service)" La cadena de asignación de mapas.

tilemap.options.subdomains:
Una matriz de subdominios utilizada por el servicio de mosaico. Especifique la posición del subdominio la URL con el token {s}.

mapa de regiones

Especifica capas de vectores adicionales para su uso en las visualizaciones de Mapa de Región. Cada objeto de capa apunta a un archivo vectorial externo que contiene una FeatureCollection geojson. El archivo debe utilizar el sistema de referencia de coordenadas WGS84 y sólo incluir polígonos. Si el archivo está alojado en un dominio separado de Kibana, el servidor debe estar habilitado para CORS para que Kibana pueda descargar el archivo. El campo url también sirve como un identificador único para el archivo. Cada capa puede contener varios campos para indicar qué propiedades de las características de geojson desea exponer. El field.description es el texto legible por el usuario que se muestra en el menú de campo de la visualización del Mapa de Región. También se puede agregar un valor de atribución opcional. El siguiente ejemplo muestra una configuración de mapa de región válida.

regionmap: layers: - name: "Departments of France" url: "http://my.cors.enabled.server.org/france_departements.geojson" attribution: "INRAP" fields: - name: "department" description: "Full department name" - name: "INSEE" description: "INSEE numeric identifier"


elasticsearch.username: y elasticsearch.password:
Si su Elasticsearch está protegida con autenticación básica, estos valores proporcionan el nombre de usuario y la contraseña que el servidor Kibana utiliza para realizar el mantenimiento en el índice Kibana al inicio. Sus usuarios de Kibana aún necesitan autenticarse con Elasticsearch, que se comunica a través del servidor Kibana.

server.ssl.enabled
Predeterminado: "false" Habilita SSL para las solicitudes salientes desde el servidor Kibana al navegador. Cuando se establece en true, se requieren server.ssl.certificate y server.ssl.key
server.ssl.certificate: y server.ssl.key:
Rutas para el certificado SSL de formato PEM y archivos de clave SSL, respectivamente.

server.ssl.keyPassphrase
La frase de contraseña que se utilizará para descifrar la clave privada. Este valor es opcional ya que la clave no puede ser cifrada.

server.ssl.certificateAutoridades
Lista de rutas de acceso a archivos de certificados codificados por PEM que se deben confiar.

protocolos server.ssl.supported
Valor predeterminado:

  • TLSv1
  • TLSv1.1
  • TLSv1.2 

Protocolos compatibles con versiones. Protocolos válidos: TLSv1, TLSv1.1, TLSv1.2
server.ssl.cipherSuites
Por defecto:

  • ECDHE-RSA-AES128-GCM-SHA256, 
  • ECDHE-ECDSHA-AES128-GCM-SHA256, 
  • ECDHE-RSA-AES256-GCM- SHA384, 
  • ECDHE- ECDSA- AES256- GCM- SHA384, 
  • DHE- RSA- AES128- GCM- RSA-AES256-SHA256, 
  • DHE-RSA-AES256-SHA256, 
  • DHE-RSA-AES256-SHA256, 
  • DHE-RSA-AES256-SHA256, 
  • DHE-RSA-AES256-SHA256, 
  • HIGH,
  • ! ANULL,
  • ! ENULL,
  • ! EXPORT,
  • ! DES,
  • ! RC4,
  • ! MD5,
  • ! PSK,
  • ! SRP,
  • ! CAMELLIA. 

Los detalles sobre el formato y las opciones válidas están disponibles a través de la documentación del formato de la lista de cifrado de OpenSSL (https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT)

elasticsearch.ssl.certificate: y elasticsearch.ssl.key:
Ajustes opcionales que proporcionan las rutas al certificado SSL de formato PEM ya los archivos de claves. Estos archivos validan que el backend de Elasticsearch utiliza los mismos archivos de claves.

elasticsearch.ssl.keyPassphrase
La frase de contraseña que se utilizará para descifrar la clave privada. Este valor es opcional ya que la clave no puede ser cifrada.

elasticsearch.ssl.certificateAutoridades:
Opcional que le permite especificar una lista de rutas de acceso al archivo PEM para la autoridad de certificación de su instancia de Elasticsearch.

elasticsearch.ssl.verificationMode:
Valor predeterminado: full Controla la verificación de certificados. Los valores válidos son none, certificate y full. completa realiza la verificación de nombre de host y el certificado no.

elasticsearch.pingTimeout:
Valor predeterminado: el valor de la configuración elasticsearch.requestTimeout Tiempo en milisegundos para esperar que Elasticsearch responda a pings.

elasticsearch.requestTimeout:
Predeterminado: 30000 Tiempo en milisegundos para esperar las respuestas del back-end o Elasticsearch. Este valor debe ser un entero positivo.

elasticsearch.requestHeadersWhitelist:
Valor predeterminado: ['autorización'] Lista de encabezados de cliente de Kibana para enviar a Elasticsearch. Para enviar ningún encabezado del lado del cliente, establezca este valor en [] (una lista vacía).

elasticsearch.customHeaders:
Valor predeterminado: {} Nombres de encabezado y valores que se enviarán a Elasticsearch. Los encabezados personalizados no pueden ser sobrescritos por los encabezados del cliente, independientemente de la configuración elasticsearch.requestHeadersWhitelist.

elasticsearch.shardTimeout:
Valor predeterminado: 0 Tiempo en milisegundos para que Elasticsearch espere las respuestas de los fragmentos. Establezca en 0 para deshabilitar.

elasticsearch.startupTimeout:
Valor predeterminado: 5000 Tiempo en milisegundos para esperar a Elasticsearch en el inicio de Kibana antes de volver a intentarlo.

pid.file:
Especifica la ruta donde Kibana crea el archivo de ID de proceso.

path.data
Default: ./data La ruta donde Kibana almacena los datos persistentes no guardados en Elasticsearch

logging.dest:
Valor predeterminado: stdout Permite especificar un archivo en el que Kibana almacena la salida del registro.

logging.silent:
Valor predeterminado: false Establezca el valor de este valor en true para suprimir toda la salida de registro.

logging.quiet:
Valor predeterminado: false Establezca el valor de esta configuración en true para suprimir toda la salida de registro distinta de los mensajes de error.

logging.verbose
Valor predeterminado: false Establezca el valor de esta configuración en true para registrar todos los eventos, incluida la información de uso del sistema y todas las solicitudes.

opsinterval
Valor predeterminado: 5000 Establece el intervalo en milisegundos para muestrear métricas de rendimiento del sistema y del proceso. El valor mínimo es 100.

status.allowAnonymous
Predeterminado: false Si la autenticación está habilitada, establecer esta opción en true permite a usuarios no autenticados acceder a la API de estado del servidor Kibana y la página de estado.

cpu.cgroup.path.override
Anular para la ruta de la cpu de cgroup cuando se monta de manera que es inconsistente con / proc / self / cgroup

cpuacct.cgroup.path.override
Anular para cgroup cpuacct path cuando está montado de manera que es inconsistente con / proc / self / cgroup

console.enabled
Valor predeterminado: true Establece en false para deshabilitar la consola. Alternar esto hará que el servidor para regenerar los activos en el próximo arranque, lo que puede causar un retraso antes de que las páginas comienzan a ser servido.

elasticsearch.tribe.url:
URL opcional de la instancia de tribu Elasticsearch para usar en todas sus consultas.

elasticsearch.tribe.username: y elasticsearch.tribe.password:
Si su Elasticsearch está protegido con autenticación básica,estos valores proporcionan el nombre de usuario y la contraseña que el servidor Kibana utiliza para realizar el mantenimiento en el índice Kibana al inicio. Sus usuarios de Kibana aún necesitan autenticarse con Elasticsearch, que se proxiene a través del servidor Kibana.

elasticsearch.tribe.ssl.certificate: y elasticsearch.tribe.ssl.key:
Ajustes opcionales que proporcionan las rutas al certificado SSL de formato PEM ya los archivos de claves. Estos archivos validan que el backend de Elasticsearch utiliza los mismos archivos de claves.

elasticsearch.tribe.ssl.keyPassphrase
La frase de contraseña que se utilizará para descifrar la clave privada. Este valor es opcional ya que la clave no puede ser cifrada.

elasticsearch.tribe.ssl.certificateAuthorities:
Opcional configuración que le permite especificar una ruta de acceso al archivo PEM para la autoridad de certificación de su tribu Elasticsearch instancia.

elasticsearch.tribe.ssl.verificationMode:
Valor predeterminado: full Controla la verificación de certificados. Los valores válidos son none, certificate y full. completa realiza la verificación de nombre de host y el certificado no.

elasticsearch.tribe.pingTimeout:
Valor predeterminado: el valor de la configuración elasticsearch.tribe.requestTimeout Tiempo en milisegundos para esperar que Elasticsearch responda a pings.

elasticsearch.tribe.requestTimeout:
Predeterminado: 30000 Tiempo en milisegundos para esperar las respuestas del back-end o Elasticsearch. Este valor debe ser un entero positivo.

elasticsearch.tribe.requestHeadersWhitelist:
Valor predeterminado: ['autorización'] Lista de encabezados de cliente de Kibana para enviar a Elasticsearch. Para enviar ningún encabezado del lado del cliente, establezca este valor en [] (una lista vacía).

elasticsearch.tribe.customHeaders:
Valor predeterminado: {} Nombres de encabezado y valores que se enviarán a Elasticsearch. Los encabezados personalizados no pueden ser sobrescritos por los encabezados del cliente, independientemente de la configuración elasticsearch.tribe.requestHeadersWhitelist.

En siguientes artículos veremos como empezar a visualizar datos con Kibana.


04 septiembre 2017

Portar desde Oracle PL / SQL a PL/pgSQL (Primera parte)

¿Qué es PL/pgSQL?

PL/pgSQL (Procedural Language/PostgreSQL Structured Query Language) es un lenguaje imperativo provisto por el gestor de base de datos PostgreSQL. Permite ejecutar comandos SQL mediante un lenguaje de sentencias imperativas y uso de funciones, dando mucho más control automático que las sentencias SQL básicas.

Desde PL/pgSQL se pueden realizar cálculos complejos y crear nuevos tipos de datos de usuario. Como un verdadero lenguaje de programación, dispone de estructuras de control repetitivas y condicionales, además de la posibilidad de creación de funciones que pueden ser llamadas en sentencias SQL normales o ejecutadas en eventos de tipo disparador (trigger).

Una de las principales ventajas de ejecutar programación en el servidor de base de datos es que las consultas y el resultado no tienen que ser transportadas entre el cliente y el servidor, ya que los datos residen en el propio servidor. Además, el gestor de base de datos puede planificar optimizaciones en la ejecución de la búsqueda y actualización de datos.

Las funciones escritas en PL/pgSQL aceptan argumentos y pueden devolver valores de tipo básico o de tipo complejo (por ejemplo, registros, vectores, conjuntos o incluso tablas), permitiéndose tipificación polimórfica para funciones abstractas o genéricas (referencia a variables de tipo objeto).

Migrar desde Oracle PL / SQL a PL /pgSQL

Esta entrada en el blog explica las diferencias entre el lenguaje PL / pgSQL de PostgreSQL y el lenguaje PL / SQL de Oracle, para ayudar a los desarrolladores que portan aplicaciones desde Oracle a PostgreSQL.

PL / pgSQL es similar a PL / SQL en muchos aspectos. Es un lenguaje estructurado en bloques, imperativo, y todas las variables tienen que ser declaradas. Asignaciones, bucles, condicionales son similares. Las principales diferencias que debe tener en cuenta al trasladar de PL / SQL a PL / pgSQL son:
  • Si un nombre utilizado en un comando SQL puede ser un nombre de columna de una tabla o una referencia a una variable de la función, PL / SQL lo trata como un nombre de columna. Esto corresponde al comportamiento plpgsql.variable_conflict = use_column de PL / pgSQL, que no es el predeterminado, como se explica en la Sección 41.10.1. A menudo es mejor evitar esas ambigüedades en primer lugar, pero si tiene que cargar una gran cantidad de código que depende de este comportamiento, establecer variable_conflict puede ser la mejor solución.
  • En PostgreSQL el cuerpo de la función debe escribirse como una cadena literal. Por lo tanto, necesita usar cotizaciones en dólares o escapar de comillas simples en el cuerpo de la función. 
  • Los nombres de tipo de datos a menudo necesitan traducción. Por ejemplo, en los valores de cadena de Oracle se declaran normalmente como de tipo varchar2, que es un tipo no estándar de SQL. En PostgreSQL, utilice el tipo varchar o texto. De forma similar, reemplace el número de tipo por numérico o utilice otro tipo de datos numéricos si hay otro más apropiado.
  • En lugar de paquetes, utilice esquemas para organizar sus funciones en grupos.
  • Puesto que no hay paquetes, tampoco hay variables a nivel de paquete. Esto es algo molesto. Puede guardar el estado por sesión en tablas temporales en su lugar.
  • Integer Los bucles FOR con REVERSE funcionan de manera diferente: PL / SQL cuenta desde el segundo número hasta el primero, mientras que PL / pgSQL cuenta desde el primer número hasta el segundo, requiriendo que los límites del loop sean intercambiados al portar. Esta incompatibilidad es lamentable, pero es improbable que se cambie.
  • Los bucles FOR sobre consultas (que no sean cursores) también funcionan de manera diferente: la variable o variables de destino deben haber sido declaradas, mientras que PL / SQL las declara siempre implícitamente. Una ventaja de esto es que los valores de las variables siguen siendo accesibles después de que el bucle salga.
  • Existen varias diferencias de notación para el uso de variables de cursor.

En próximas entradas nos ocuparemos de hacer un ejemplo para mostrar como migrar funcionalidad de una base de datos a otra.

¿Hay vida más allá de Oracle? Hoy presentamos REDIS

Breve introducción a Redis

Redis es un motor de base de datos en memoria, basado en el almacenamiento en tablas de hashes (clave/valor) pero que opcionalmente puede ser usada como una base de datos durable o persistente. Está escrito en ANSI C por Salvatore Sanfilippo quien fue patrocinado por VMware y, a partir de 2013, por Pivotal Software

Está liberado bajo licencia BSD por lo que es considerado software de código abierto.

Al no pertenecer al mundo relacional automáticamente entra en el grupo de bases de datos libres de tipo NoSQL.

Redis no es un almacén plano del clave-valor, él es realmente un servidor de las estructuras de datos, apoyando diversos tipos de valores. Lo que esto significa es que, mientras que en los almacenes de clave-valor tradicionales asoció a las cadenas de claves a cadenas de valores, en Redis el valor no se limita a una cadena simple, sino que también puede contener estructuras de datos más complejas. 

Se puede ejecutar operaciones atómicas sobre estos tipos, como agregar elementos a una cadena; incrementar el valor de un hash, integrandolo a una lista; intersección de conjuntos de computación, unión y diferencia, o conseguir el miembro de más alto rango en un conjunto ordenado.

¿Para qué vale Redis?

Redis resuelve de manera sencilla y eficiente problemas que no necesitan la complejidad de las bases de datos relacionales, como lo es en la mayoría de los casos de usos el almacén y gestión de estructuras de datos temporales, por lo cual Redis es mayoritariamente usado para incorporar soluciones sofisticadas de cache de datos ó como backend de operaciones en linea en escenarios de alta demanda. Redis no pierde tiempo pensando  en relaciones, restricciones ni tipos de datos, se enfoca en hacer eficientemente su trabajo que es establecer y recuperar (set y get) datos sobre las estructuras con las que cuenta.
Como ejemplos podemos citar:
  • Gestión de sesiones de usuarios y soluciones de cache, entre muchas otras.
  • incorporar mensajería instantánea en una aplicación, derivas la gestión de chat a Redis y luego resumes la mensajería del dia y la insertas como histórico a tu base de datos principal.
  • Suponga que tiene un portal web con mucha trayectoria y miles de millones de contenidos, así como millones de visitas diarias, cuya pagina de inicio abarca el 90% de las visitas de su web, su pagina de inicio solo son 30 contenidos y otros elementos, pues en vez de recorrer su base de datos tradicional con los millones de contenidos en busca de los 30, simplemente los pone a disposición de la manera mas rápida posible.

Modelo de datos

El modelo de datos de Redis se basa en la estructura de datos del tipo diccionario o tabla de hashes que relaciona una llave a un contenido almacenado en un índice. La principal diferencia entre Redis y otros sistemas similares es que los valores no están limitados a ser de tipo string, otros tipos de datos están soportados:
  • Listas (Lists) de strings
  • Sets de strings (colecciones de elementos desordenados no repetidos)
  • hashes donde la llave y el valor son del tipo string
El tipo de valor determina las operaciones (los comandos) que son disponibles. Redis soporta operaciones atómicas de alto nivel del lado del servidor, como inserciones, unions, y diferencias entre sets y listas ordenadas. Desde la versión 2.6, liberada a finales de octubre de 2012, se introduce una funcionalidad clave, la posibilidad de ejecutar Scripts en el servidor Redis, escritos en lenguaje Lua.
La siguiente es la lista de todas las estructuras de datos soportadas por Redis, que se tratarán por separado en este tutorial:
  • Cadenas binarias seguras.
  • Listas: colecciones de elementos de cadenas ordenadas según el orden de inserción. Son básicamente listas enlazadas.
  • Conjuntos: colecciones de elementos de cadena únicos sin clasificar.
  • Conjuntos ordenados, similares a Conjuntos pero donde cada elemento de cadena está asociado a un valor numérico flotante, llamado puntuación. Los elementos siempre se toman ordenados por su puntuación, por lo que a diferencia de los conjuntos es posible recuperar un rango de elementos (por ejemplo, puede pedir: darme el top 10 o el 10 inferior).
  • Hashes, que son mapas compuestos de campos asociados con valores. Tanto el campo como el valor son cadenas. Esto es muy similar a los hashes de Ruby o Python.
  • Arrays de bits (o simplemente mapas de bits): es posible, mediante comandos especiales, manejar valores de cadena como una matriz de bits: puede establecer y borrar bits individuales, contar todos los bits establecidos en 1, encontrar el primer conjunto o bit sin configurar, Etcétera.
  • HyperLogLogs: es una estructura de datos probabilística que se utiliza para estimar la cardinalidad de un conjunto. No tengas miedo, es más simple de lo que parece ... Un ejemplo de caso de uso para esta estructura de datos es contar las consultas únicas realizadas por los usuarios en un formulario de búsqueda todos los días.

Persistencia

Redis normalmente guarda la información en la memoria RAM, pero en versiones superiores a la 2.4 se puede configurar para utilizar Memoria virtual pero ahora esto está desactualizado. Se puede hacer que los datos sean persistentes de dos formas:
  • Una es hacer snapshots (capturas), aunque no sería realmente durable ya que estos son asíncronos al transferir la memoria al disco cada cierto tiempo. 
  • Desde la versión 1.1 la mejor alternativa es usar un archivo del tipo appendonly gracias a un sistema de Journaling el cual escribe en este archivo cada modificación que se realice sobre los datos en memoria pudiendo regenerar los datos. Esto genera un costo en el rendimiento, pero se puede configurar de dos formas, always, que escribirá cualquier cambio en el instante, o everysec que lo hará segundo tras segundo.

Replicación

Redis soporta la replicación del tipo maestro-esclavo, pudiéndose replicar los datos de un servidor a muchos esclavos, también un esclavo puede ser maestro para otro esclavo, lo que permite soportar en Redis una replicación en forma de árbol. Los esclavos permiten la escritura de datos, lo que puede ocasionar inconsistencias en los datos no intencionales.
La función de publicación/subscripción esta totalmente soportada, cuando un cliente esclavo se subscribe a un canal este recibe un feed completo de publicaciones del maestro, replicando así en todo el árbol.
La replicación es útil para escalar la lectura (no la escritura) y/o redundar los datos.

Rendimiento

Para escenarios de datos solo usando memoria RAM el rendimiento puede ser extremo, comparado con motores de bases de datos, tampoco hay una notable diferencia entre lectura y escritura de datos, en disco.

02 septiembre 2017

Batería de scripts útiles.


Algunas consultas SQL muy útiles para el administrador de Oracle (estado de la base de datos Oracle, parámetros generales, ficheros de control, conexiones actuales a Oracle, nombre del ejecutable que se utiliza, nombre del usuario, diccionario de datos, …)
Vista que muestra el estado de la base de datos:

Select * from v$instance;
Consulta que muestra si la base de datos está abierta
select status from v$instance;
Vista que muestra los parámetros generales de Oracle
select * from v$system_parameter;
Versión de Oracle
select value from v$system_parameter where name = 'compatible';
Ubicación y nombre del fichero spfile
select value from v$system_parameter where name = 'spfile';
Ubicación y número de ficheros de control
select value from v$system_parameter where name = 'control_files';
Nombre de la base de datos
select value from v$system_parameter where name = 'db_name';
Vista que muestra las conexiones actuales a Oracle Para visualizarla es necesario entrar con privilegios de administrador
select osuser, username, machine, program  order by osuser;
Vista que muestra el número de conexiones actuales a Oracle agrupado por aplicación que realiza la conexión
select program Aplication, count(program) Numero_Sesiones from v$session group by program order by Numero_Sesiones 
Vista que muestra los usuarios de Oracle conectados y el número de sesiones por usuario
select username Usuario_Oracle, count(username) Numero_Sesiones from v$session group by username order by Numero_Sesiones desc;
Propietarios de objetos y número de objetos por propietario
select owner, count(owner) Numero from dba_objects group by owner order by Numero desc 
Diccionario de datos (incluye todas las vistas y tablas de la Base de Datos)
select * from dictionary
select table_name from dictionary
Muestra los datos de una tabla especificada (en este caso todas las tablas que lleven la cadena "EMPLO"
select * from ALL_ALL_TABLES where upper(table_name) like '%EMPLO%' 
Tablas propiedad del usuario actual
select * from user_tables 
Todos los objetos propiedad del usuario conectado a Oracle
select * from user_catalog  
Consulta SQL para el DBA de Oracle que muestra los tablespaces, el espacio utilizado, el espacio libre y los ficheros de datos de los mismos:
select t.tablespace_name  "Tablespace",  t.status "Estado",                                                                                                                                                                                                                      
    ROUND(MAX(d.bytes)/1024/1024,2) "MB Tamaño",                                                                                                                                                                                                                                 
    ROUND((MAX(d.bytes)/1024/1024) -                                                                                                                                                                                                                                             
    (SUM(decode(f.bytes, NULL,0, f.bytes))/1024/1024),2) "MB Usados",                                                                                                                                                                                                            
    ROUND(SUM(decode(f.bytes, NULL,0, f.bytes))/1024/1024,2) "MB Libres",                                                                                                                                                                                                        
    t.pct_increase "% incremento",                                                                                                                                                                                                                                               
    SUBSTR(d.file_name,1,80) "Fichero de datos"                                                                                                                                                                                                                                  
FROM DBA_FREE_SPACE f, DBA_DATA_FILES d,  DBA_TABLESPACES t                                                                                                                                                                                                                      
WHERE t.tablespace_name = d.tablespace_name  AND                                                                                                                                                                                                                                 
    f.tablespace_name(+) = d.tablespace_name                                                                                                                                                                                                                                     
    AND f.file_id(+) = d.file_id GROUP BY t.tablespace_name,                                                                                                                                                                                                                     
    d.file_name,   t.pct_increase, t.status ORDER BY 1,3 DESC;  
Productos Oracle instalados y la versión:
select * from product_component_version 
Roles y privilegios por roles:
select * from role_sys_privs  
Reglas de integridad y columna a la que afectan:
select constraint_name, column_name from sys.all_cons_columns  
Tablas de las que es propietario un usuario, en este caso "HR":
select table_owner, table_name from sys.all_synonyms where table_owner like 'HR'
Otra forma más efectiva (tablas de las que es propietario un usuario):
select DISTINCT TABLE_NAME                                                                                                                                                                                                                                                       
FROM ALL_ALL_TABLES                                                                                                                                                                                                                                                              
WHERE OWNER LIKE 'HR' 
Parámetros de Oracle, valor actual y su descripción:
select v.name, v.value value, decode(ISSYS_MODIFIABLE, 'DEFERRED',                                                                                                                                                                                                               
     'TRUE', 'FALSE') ISSYS_MODIFIABLE,  decode(v.isDefault, 'TRUE', 'YES',                                                                                                                                                                                                      
     'FALSE', 'NO') "DEFAULT",  DECODE(ISSES_MODIFIABLE,  'IMMEDIATE',                                                                                                                                                                                                           
     'YES','FALSE',  'NO',  'DEFERRED', 'NO', 'YES') SES_MODIFIABLE,                                                                                                                                                                                                             
     DECODE(ISSYS_MODIFIABLE, 'IMMEDIATE', 'YES',  'FALSE', 'NO',                                                                                                                                                                                                                
     'DEFERRED', 'YES','YES') SYS_MODIFIABLE ,  v.description                                                                                                                                                                                                                    
FROM V$PARAMETER v                                                                                                                                                                                                                                                               
WHERE name not like 'nls%'   ORDER BY 1
Usuarios de Oracle y todos sus datos (fecha de creación, estado, id, nombre, tablespace temporal,...):
select  * FROM dba_users
Tablespaces y propietarios de los mismos:
select owner, decode(partition_name, null, segment_name,                                                                                                                                                                                                                         
   segment_name || ':' || partition_name) name,                                                                                                                                                                                                                                  
   segment_type, tablespace_name,bytes,initial_extent,                                                                                                                                                                                                                           
   next_extent, PCT_INCREASE, extents, max_extents                                                                                                                                                                                                                               
from dba_segments                                                                                                                                                                                                                                                                
Where 1=1 And extents > 1 order by 9 desc, 3 
Últimas consultas SQL ejecutadas en Oracle y usuario que las ejecutó:
select distinct vs.sql_text, vs.sharable_mem,                                                                                                                                                                                                                                    
  vs.persistent_mem, vs.runtime_mem,  vs.sorts,                                                                                                                                                                                                                                  
  vs.executions, vs.parse_calls, vs.module,                                                                                                                                                                                                                                      
  vs.buffer_gets, vs.disk_reads, vs.version_count,                                                                                                                                                                                                                               
  vs.users_opening, vs.loads,                                                                                                                                                                                                                                                    
  to_char(to_date(vs.first_load_time,                                                                                                                                                                                                                                            
  'YYYY-MM-DD/HH24:MI:SS'),'MM/DD  HH24:MI:SS') first_load_time,                                                                                                                                                                                                                 
  rawtohex(vs.address) address, vs.hash_value hash_value ,                                                                                                                                                                                                                       
  rows_processed  , vs.command_type, vs.parsing_user_id  ,                                                                                                                                                                                                                       
  OPTIMIZER_MODE  , au.USERNAME parseuser                                                                                                                                                                                                                                        
from v$sqlarea vs , all_users au                                                                                                                                                                                                                                                 
where (parsing_user_id != 0)  AND                                                                                                                                                                                                                                                
(au.user_id(+)=vs.parsing_user_id)                                                                                                                                                                                                                                               
and (executions >= 1) order by   buffer_gets/executions desc  
Todos los ficheros de datos y su ubicación:
select * from V$DATAFILE   
Ficheros temporales:
select * from V$TEMPFILE  
Tablespaces:
select * from V$TABLESPACE  
Otras vistas muy interesantes:
select * from V$BACKUP; 
select * from V$ARCHIVE; 
select * from V$LOG;   
select * from V$LOGFILE;
select * from V$LOGHIST; 
select * from V$ARCHIVED_LOG; 
select * from V$DATABASE; 
Memoria Share_Pool libre y usada
select name,to_number(value) bytes                                                                                                                                                                                                                                               
from v$parameter where name ='shared_pool_size'                                                                                                                                                                                                                                  
union all                                                                                                                                                                                                                                                                        
select name,bytes                                                                                                                                                                                                                                                                
from v$sgastat where pool = 'shared pool' and name = 'free memory'   
Cursores abiertos por usuario
select b.sid, a.username, b.value Cursores_Abiertos                                                                                                                                                                                                                              
      from v$session a,                                                                                                                                                                                                                                                          
           v$sesstat b,                                                                                                                                                                                                                                                          
           v$statname c                                                                                                                                                                                                                                                          
      where c.name in ('opened cursors current')                                                                                                                                                                                                                                 
      and   b.statistic# = c.statistic#                                                                                                                                                                                                                                          
      and   a.sid = b.sid                                                                                                                                                                                                                                                        
      and   a.username is not null                                                                                                                                                                                                                                               
      and   b.value >0                                                                                                                                                                                                                                                           
      order by 3 
Aciertos de la caché (no debe superar el 1 por ciento)
select sum(pins) Ejecuciones, sum(reloads) Fallos_cache,                                                                                                                                                                                                                         
trunc(sum(reloads)/sum(pins)*100,2) Porcentaje_aciertos                                                                                                                                                                                                                          
from v$librarycache                                                                                                                                                                                                                                                              
where namespace in ('TABLE/PROCEDURE','SQL AREA','BODY','TRIGGER');  
Sentencias SQL completas ejecutadas con un texto determinado en el SQL
select c.sid, d.piece, c.serial#, c.username, d.sql_text                                                                                                                                                                                                                         
FROM v$session c, v$sqltext d                                                                                                                                                                                                                                                    
WHERE  c.sql_hash_value = d.hash_value                                                                                                                                                                                                                                           
and upper(d.sql_text) like '%WHERE CAMPO LIKE%'                                                                                                                                                                                                                                  
ORDER BY c.sid, d.piece   
Una sentencia SQL concreta (filtrado por sid)
select c.sid, d.piece, c.serial#, c.username, d.sql_text                                                                                                                                                                                                                         
FROM v$session c, v$sqltext d                                                                                                                                                                                                                                                    
WHERE  c.sql_hash_value = d.hash_value                                                                                                                                                                                                                                           
and sid = 105                                                                                                                                                                                                                                                                    
ORDER BY c.sid, d.piece                                                                                                                                                                                                                                                          
Tamaño ocupado por la base de datos  
select sum(BYTES)/1024/1024 MB from DBA_EXTENTS
Tamaño de los ficheros de datos de la base de datos
select sum(bytes)/1024/1024 MB from dba_data_files
Tamaño ocupado por una tabla concreta sin incluir los índices de la misma
select sum(bytes)/1024/1024 MB from user_segments                                                                                                                                                                                                                               
 where segment_type='TABLE' and segment_name='NOMBRETABLA' 
Tamaño ocupado por una tabla concreta incluyendo los índices de la misma
select sum(bytes)/1024/1024 Table_Allocation_MB from user_segments                                                                                                                                                                                                               
 where segment_type in ('TABLE','INDEX') and                                                                                                                                                                                                                                     
(segment_name='NOMBRETABLA' or segment_name in                                                                                                                                                                                                                                   
select index_name from user_indexes where table_name='NOMBRETABLA')) 
Tamaño ocupado por una columna de una tabla
select sum(vsize('NOMBRECOLUMNA'))/1024/1024 MB from NOMBRETABLA 
Espacio ocupado por usuario
select owner, SUM(BYTES)/1024/1024 FROM DBA_EXTENTS MB group by owner; 
Espacio ocupado por los diferentes segmentos (tablas, índices, undo, rollback, cluster, ...)
select SEGMENT_TYPE, SUM(BYTES)/1024/1024 FROM DBA_EXTENTS MB                                                                                                                                                                                                                    
group by SEGMENT_TYPE 
Espacio ocupado por todos los objetos de la base de datos, muestra los objetos que más ocupan primero
select SEGMENT_NAME, SUM(BYTES)/1024/1024 FROM DBA_EXTENTS MB                                                                                                                                                                                                                    
group by SEGMENT_NAME                                                                                                                                                                                                                                                            
order by 2 desc  
Obtener todas las funciones de Oracle: NVL, ABS, LTRIM, ...
select distinct object_name                                                                                                                                                                                                                                                      
FROM all_arguments                                                                                                                                                                                                                                                               
WHERE package_name = 'STANDARD'  
order by object_name





29 agosto 2017

¿Hay vida más allá de Oracle? Hoy presentamos PrestoDB

Este artículo está hecho para que los posibles administradores y usuarios finales sepan qué esperar de Presto.


Definición

Presto es un motor de consulta SQL distribuido diseñado para consultar conjuntos de datos grandes distribuidos sobre una o más fuentes de datos heterogéneas.


Lo que no es Presto DB en la actualidad

Debido a que Presto está siendo llamado una base de datos por muchos miembros de la comunidad, tiene sentido comenzar con una definición de lo que Presto no es.

No confunda el hecho de que Presto entiende SQL con él que proporciona las características de una base de datos estándar. Presto no es una base de datos relacional de uso general. No es un reemplazo para bases de datos como MySQL, PostgreSQL u Oracle. Presto no fue diseñado para procesar transacciones en línea (OLTP). Esto también es cierto para muchas otras bases de datos diseñadas y optimizadas para data warehouse o análisis de datos.

¿Qué es Presto?

Presto es una herramienta diseñada para consultar eficientemente grandes cantidades de datos mediante consultas distribuidas. Si trabaja con terabytes o petabytes de datos, es probable que utilice herramientas que interactúen con Hadoop y HDFS. Presto fue diseñado como una alternativa a las herramientas que consultan HDFS usando tuberías de trabajos de MapReduce como Apache Hive o Pig, pero Presto no se limita a acceder a HDFS. Presto puede ser ampliado para operar sobre diferentes tipos de fuentes de datos, incluyendo bases de datos relacionales tradicionales y otras fuentes de datos como Cassandra.

Presto fue diseñado para manejar data warehousing y análisis: análisis de datos, agregando grandes cantidades de datos y produciendo reportes. Estas cargas de trabajo se clasifican a menudo como procesamiento analítico en línea (OLAP).

¿Quién usa Presto?


Presto es un proyecto de código abierto que funciona bajo los auspicios de Facebook. Fue inventado en Facebook y el proyecto continúa siendo desarrollado por los desarrolladores internos de Facebook y un número de desarrolladores de terceros en la comunidad. En mi último trabajo se usó para sustituir a la base de datos que soportaba el modelo de datawarehouse, debido a coste económico del mantenimiento.

Presto es un sistema distribuido que se ejecuta en un grupo de máquinas. Una instalación completa incluye un coordinador y varios trabajadores. Las consultas se envían desde un cliente como la CLI Presto al coordinador. El coordinador analiza, analiza y planifica la ejecución de la consulta, luego distribuye el procesamiento a los trabajadores.

Requisitos

Presto tiene algunos requisitos básicos: 
  • Linux o Mac OS X
  • Java 8, 64 bits
  • Python 2.4+



Conectores

Presto admite conectores enchufables que proporcionan datos para consultas. Los requisitos varían según el conector.

HADOOP / HIVE

Presto admite la lectura de datos de cola de las siguientes versiones de Hadoop: 
    • Apache Hadoop 1.x
    • Apache Hadoop 2.x
    • Cloudera CDH 4
    • Cloudera CDH 5

Se admiten los siguientes formatos de archivo: Texto, Archivo secuencial, RCFile, ORC y Parquet.

Además, se requiere un metastore remoto de colmena. No se admite el modo local o incorporado. Presto no usa MapReduce y por lo tanto sólo requiere HDFS.

CASSANDRA

Se requiere Cassandra 2.x. Este conector es completamente independiente del conector Hive y sólo requiere una instalación de Cassandra existente.

TPC-H

El conector TPC-H genera dinámicamente datos que pueden utilizarse para experimentar y probar Presto. Este conector no tiene requisitos externos.

Despliegue

Consulte Implementación de Presto para obtener instrucciones completas de implementación.

Ejecución de consultas

Puede ejecutar consultas utilizando la Interfaz de línea de comandos después de implementar Presto.
La CLI de Presto proporciona un shell interactivo basado en terminal para ejecutar consultas. La CLI es un archivo JAR que se ejecuta automáticamente, lo que significa que actúa como un ejecutable normal de UNIX.

Descargar presto-cli-0.183-ejectable.jar, renombrarlo a presto, hacerlo ejecutable con chmod + x, luego ejecutarlo:

./presto --server localhost: 8080 --cambio de catálogo --schema default

Ejecute la CLI con la opción --help para ver las opciones disponibles.


De forma predeterminada, los resultados de las consultas se paginan utilizando el programa menos que está configurado con un conjunto cuidadosamente seleccionado de opciones. Este comportamiento se puede sobreescribir estableciendo la variable de entorno PRESTO_PAGER al nombre de un programa diferente como, por ejemplo, más o establecerlo en un valor vacío para desactivar completamente la paginación.