Posts anteriores:
Hola
Una vez repasado en los post anteriores los requisitos que necesarios a nivel de directorio activo, red y almacenamiento, vamos a pasar a exponer cómo instalar los hosts con Hyper-V, tanto en configuraciones stand-alone como en cluster. Si bien a estas alturas creo que escribir un paso a paso sobre cómo instalar Windows Server 2008 R2 está de más, vamos a centrarnos en una serie de consejos prácticos que pueden ayudar a que este sea el paso más sencillo y rápido del montaje de todo el entorno, y que agregar nuevos hosts sea cuestión de pinchar un pendrive e irnos a tomar un café. Los interesados en el paso a paso detallado pueden consultar:
Antes de nada, vamos a repasar rápidamente las tres opciones que tenemos para montar Hyper-V en un servidor:
Gran parte de la configuración posterior puede realizarse también de manera centralizada desde Virtual Machine Manager, pero en este caso vamos a realizarla manualmente.
Automatización de la instalación de los hosts mediante un pendrive y un fichero autounattend.xml
Una vez en nuestro poder los DVDs o imágenes ISO necesarias es el momento de ponerse manos a la obra con la instalación. Si bien todos los fabricantes de servidores incluyen herramientas para poder montar medios virtuales por la red, mi experiencia es que lleva más tiempo lograr que la conexión remota funcione bien y que los ficheros se copien por la red que lo que se tarda realmente en instalar y configurar el sistema.
Por tanto solemos tener a mano uno o varios pendrives sobre los que hemos volcado todos los ficheros del medio de instalación, de manera que, si hacemos arrancar de dicho dispositivo al servidor, la instalación se realiza de manera mucho más rápida en cuestión de pocos minutos. Estos son los pasos para preparar previamente el pendrive (de 4GB mínimo) en un equipo con Windows Vista/7/2008/2008 R2
Con esto tendremos ya listo un pendrive arrancable que se comportará exactamente igual que el DVD si hacemos que el servidor arranque de él. Nos pedirá la configuración de idioma, teclado, edición de Windows Server 2008 R2 a instalar, si full o si core, el disco y la partición y el proceso terminará solicitando que introduzcamos una contraseña compleja para el administrador local. El sistema quedará instalado con un nombre aleatorio, sin ningún tipo de configuración predefinida y sin funcionalidades ni características. Hemos quedado en que nos apetece un café o dedicarnos a tareas un poco más gratificantes, así es que vamos a automatizar un poco más el proceso.
El proceso de instalación de los sistemas operativos a partir de Windows Vista buscan al principio de la instalación un fichero autounattend.xml con las opciones de instalación desatendida en dos sitios: el propio medio de instalación y luego en un medio externo que puede ser un dispositivo de almacenamiento USB o un disquete. Aprovechando que en el pendrive que hemos preparado es fácil crear y copiar un fichero, colocaremos el autounattend.xml en su carpeta raíz.
Esto es lo que vamos a automatizar en el caso de que queramos utilizar el role de Hyper-V incluido en Windows Server 2008 R2, usando para la partición padre una instalación bien “Full” bien “Server Core”. Puede hacerse algo similar para Hyper-V Server 2008 R2 (descarga gratuita), si bien la instalación del mismo ya esta bastante automatizada de por sí:
NOTA: El proceso de instalación tiene un reinicio. Si hemos configurado el servidor para que siempre arranque del dispositivo extraíble y hemos llegado a automatizar el proceso completamente, la instalación se llevará a cabo una y otra vez de manera iterativa mientras disfrutamos de nuestro café. Dependiendo de la BIOS del servidor, es posible seleccionar el dispositivo extraíble como medio de arranque ocasional, de modo que la instalación continúe sin problemas en el siguiente reinicio, ya desde el almacenamiento local o de la SAN del servidor.
1.- Fichero autounattend.xml para Windows Server 2008 R2 Datacenter “Full”. En rojo lo que tenemos que modificar para ajustarlo a cada servidor en particular:
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<servicing>
<package action="configure">
<assemblyIdentity name="Microsoft-Windows-Foundation-Package" version="6.1.7600.16385" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="" />
<selection name="Microsoft-Hyper-V" state="true" />
<selection name="Microsoft-Hyper-V-Management-Clients" state="true" />
<selection name="VmHostAgent" state="true" />
<selection name="MultipathIo" state="true" />
<selection name="TelnetClient" state="true" />
<selection name="WindowsServerBackup" state="true" />
<selection name="WindowsServerBackupCommandlet" state="true" />
<selection name="FailoverCluster-AdminPak" state="true" />
<selection name="FailoverCluster-FullServer" state="true" />
</package>
</servicing>
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SetupUILanguage>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
<SystemLocale>es-ES</SystemLocale>
<UserLocale>es-ES</UserLocale>
<InputLocale>040a;0000040a</InputLocale>
<UILanguage>en-US</UILanguage>
<UILanguageFallback></UILanguageFallback>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserData>
<ProductKey>
<WillShowUI>Never</WillShowUI>
</ProductKey>
<AcceptEula>true</AcceptEula>
<FullName>Nombre</FullName>
<Organization>Empresa</Organization>
</UserData>
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Value>Windows Server 2008 R2 SERVERDATACENTER</Value>
<Key>/IMAGE/NAME</Key>
</MetaData>
</InstallFrom>
</OSImage>
</ImageInstall>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<fDenyTSConnections>false</fDenyTSConnections>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ComputerName>Servidor1</ComputerName>
<RegisteredOwner>Emresa</RegisteredOwner>
<TimeZone>Romance Standard Time</TimeZone>
</component>
<component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Identification>
<Credentials>
<Domain>Dominio</Domain>
<Username>administrator</Username>
<Password>password</Password>
</Credentials>
<JoinDomain>dominio.local</JoinDomain>
</Identification>
</component>
</settings>
<cpi:offlineImage cpi:source="wim:j:/sources/install.wim#Windows Server 2008 R2 SERVERDATACENTER" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>
2.- Fichero autounattend.xml para Windows Server 2008 R2 Datacenter “Server Core”.
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<servicing>
<package action="configure">
<assemblyIdentity name="Microsoft-Windows-ServerCore-Package" version="6.1.7600.16385" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="" />
<selection name="FailoverCluster-Core" state="true" />
<selection name="Microsoft-Hyper-V" state="true" />
<selection name="MultipathIo" state="true" />
<selection name="WindowsServerBackup" state="true" />
<selection name="WindowsServerBackupCommandlet" state="true" />
<selection name="NetFx2-ServerCore" state="true" />
<selection name="MicrosoftWindowsPowerShell" state="true" />
<selection name="TelnetClient" state="true" />
</package>
</servicing>
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SetupUILanguage>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
<SystemLocale>es-ES</SystemLocale>
<UserLocale>es-ES</UserLocale>
<InputLocale>040a;0000040a</InputLocale>
<UILanguage>en-US</UILanguage>
<UILanguageFallback></UILanguageFallback>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserData>
<ProductKey>
<WillShowUI>Never</WillShowUI>
</ProductKey>
<AcceptEula>true</AcceptEula>
<FullName>Nombre</FullName>
<Organization>Empresa</Organization>
</UserData>
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Value>Windows Server 2008 R2 SERVERDATACENTERCORE</Value>
<Key>/IMAGE/NAME</Key>
</MetaData>
</InstallFrom>
</OSImage>
</ImageInstall>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<fDenyTSConnections>false</fDenyTSConnections>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ComputerName>Servidor1</ComputerName>
<RegisteredOwner>Nombre</RegisteredOwner>
<TimeZone>Romance Standard Time</TimeZone>
</component>
<component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Identification>
<Credentials>
<Domain>dominio</Domain>
<Username>administrator</Username>
<Password>password</Password>
</Credentials>
<JoinDomain>dominio.local</JoinDomain>
</Identification>
</component>
</settings>
<cpi:offlineImage cpi:source="wim:j:/sources/install.wim#Windows Server 2008 R2 SERVERDATACENTERCORE" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>
Tenéis más información sobre todos estos temas aqui:
Una vez terminado el proceso de instalación, ya tendremos el servidor corriendo Hyper-V, configurado con su propio nombre, metido en el dominio y con todo lo necesario para pasar a configurar la red y el almacenamiento tal y como hemos planificado en los posts anteriores. Deberemos configurar el direccionamiento IP deseado en cada interfaz según el uso al que se vaya a dedicar y preparar los volúmenes que nos vienen desde el almacenamiento compartido.
Configuración de Hyper-V
Dado que Hyper-V ya deberá estar corriendo por debajo de la partición padre, solo necesitaremos crear manualmente los switches virtuales a los que conectaremos las máquinas virtuales y elegir en que carpetas del almacenamiento guardaremos los ficheros de configuración de las máquinas virtuales, sus discos y las snapshots.
Como decíamos en los posts anteriores, es muy importante acostumbrarse a ser consistente con estas nomenclaturas, incluso en entornos de laboratorio.
Creación del cluster
En Windows Server 2008 y Windows Server 2008 R2 es posible crear sistemas cluster con servidores bastante diferentes entre si. Sin embargo para formar un cluster con Hyper-V deberemos elegir nodos lo más homogéneos posible, dentro de que es posible cierta disparidad. En cualquier caso no será posible tener ni Quick ni Live Migration entre sistemas con diferente fabricante de procesador (Intel y AMD) y para procesadores de diferentes familias dentro del mismo fabricante, es posible habilitar en el procesador de las máquinas virtuales el modo de compatibilidad para que los movimientos entre hosts sean posibles.
Podemos crear el cluster desde cualquier equipo en el que hayamos instalado la consola, que puede ser uno de los nodos que lo conformarán. Este es el proceso paso a paso:
Primeramente agregamos los servidores que conformarán el cluster y pasamos el proceso de validación sobre ellos.
Una vez validado el sistema (en este ejemplo faltaban por presentar los discos y por configurar la red interna y de ahí la advertencia), podemos pasar a crear al cluster en tres sencillos pasos que se reducen a elegir su nombre y su dirección IP:
Tras este proceso ya tendremos nuestro cluster activo, y si todo ha ido bien veremos en el apartado del almacenamiento el quorum y los discos presentados a ambos nodos desde la SAN como almacenamiento disponible. Solo nos queda un par de pasos:
Tenéis mas información al respecto y un video aquí:
Con respecto a la red, es conveniente también renombrar en la consola cada una de las redes y revisar si el uso que hará de ellas el cluster es el que hemos planificado según el post anterior. He aquí como queda en nuestro poco recomendado caso de tener solo dos NICs en los hosts:
Recordemos que el trafico de red correspondiente al funcionamiento de los CSVs fluye por la red de menor métrica. Aquí esta documentado como tener control de esto:
Ya podemos proceder a crear las máquinas virtuales. En los servidores stand-alone podremos crearlas desde la consola de Hyper-V. Las que queramos dotar de alta disponibilidad y capacidades de Live Migration pueden crearse directamente usando la consola de Failover Cluster, ya que ambas consolas están integradas:
Por último, podemos definir cual va ser la red que se utilizará para el proceso de Live Migration. Este es un parámetro global, que afecta a todas las VMs de un cluster, pero que se define sobre cualquiera de ellas. En nuestro caso no hay muchas opciones
A partir de este momento ya tenemos la base montada para poder correr encima todas las máquinas virtuales que sean capaces de mover los servidores de los que dispongamos.
Saludos
This post explains how to improve performance of WordPress on Windows by using the WinCache Extension 1.1 – Beta for PHP. You probably already know that just by enabling the WinCache extension and without any code changes it is possible to get a significant increase in WordPress performance – this is described in details in PHP on Windows: The WinCache 1.0 Benchmark. But this can be taken even further by using the user cache API’s available in WinCache 1.1 release.
To configure WordPress to use WinCache user cache API’s copy the following code and put it in the file named object-cache.php located at the /wp-content/ directory of your WordPress site. Note that this code was copied from here and the only change was to replace all the APC cache function with corresponding WinCache functions.
<?php /* Name: WinCache Cache Description: WinCache backend for the WP Object Cache. Version: 0.1 URI: http://ruslany.net/ Author: Ruslan Yakushev Install this file to wp-content/object-cache.php Big thanks to Mark Jaquith (http://markjaquith.wordpress.com/) whose apc-object-cache.php was used as a basis for this code. */ // gracefully revert to default cache if WinCache is not installed if ( !extension_loaded('wincache') || !function_exists('wincache_ucache_get') || strcmp(ini_get('wincache.ucenabled'), "1") ) { include_once(ABSPATH . WPINC . '/cache.php'); } else { function wp_cache_add($key, $data, $flag = '', $expire = 0) { global $wp_object_cache; return $wp_object_cache->add($key, $data, $flag, $expire); } function wp_cache_close() { return true; } function wp_cache_delete($id, $flag = '') { global $wp_object_cache; return $wp_object_cache->delete($id, $flag); } function wp_cache_flush() { global $wp_object_cache; return $wp_object_cache->flush(); } function wp_cache_get($id, $flag = '') { global $wp_object_cache; return $wp_object_cache->get($id, $flag); } function wp_cache_init() { global $wp_object_cache; $wp_object_cache = new WP_Object_Cache(); } function wp_cache_replace($key, $data, $flag = '', $expire = 0) { global $wp_object_cache; return $wp_object_cache->replace($key, $data, $flag, $expire); } function wp_cache_set($key, $data, $flag = '', $expire = 0) { global $wp_object_cache; return $wp_object_cache->set($key, $data, $flag, $expire); } class WP_Object_Cache { var $global_groups = array ('users', 'userlogins', 'usermeta'); var $cache = array (); function add($id, $data, $group = 'default', $expire = 0) { return $this->set($id, $data, $group, $expire); } function delete($id, $group = 'default') { $key = $this->key($id, $group); $result = wincache_ucache_delete($key); if ( false !== $result ) unset($this->cache[$key]); return $result; } function flush() { wincache_ucache_clear(); return true; } function get($id, $group = 'default') { $key = $this->key($id, $group); if ( isset($this->cache[$key]) ) $value = $this->cache[$key]; else $value = wincache_ucache_get($key); /* echo "Cache key: $key<br/>"; echo 'Cache value:<br/>'; var_dump($value); echo '<br/>'; */ if ( NULL === $value ) $value = false; $this->cache[$key] = $value; return $value; } function key($key, $group) { global $blog_id; if ( empty($group) ) $group = 'default'; if (false !== array_search($group, $this->global_groups)) $prefix = ''; else $prefix = $blog_id . ':'; return md5(ABSPATH . "$prefix$group:$key"); } function replace($id, $data, $group = 'default', $expire = 0) { return $this->set($id, $data, $group, $expire); } function set($id, $data, $group = 'default', $expire = 0) { $key = $this->key($id, $group); $result = wincache_ucache_set($key, $data, $expire); if ( false !== $result ) $this->cache[$key] = $data; return $result; } function stats() { $wincache_info = wincache_ucache_info(); echo "<p>\n"; echo "<strong>Cache Hits:</strong> {$wincache_info['total_hit_count']}<br/>\n"; echo "<strong>Cache Misses:</strong> {$wincache_info['total_miss_count']}<br/>\n"; echo "</p>\n"; if ( ! empty($this->cache) ) { echo "<pre>\n"; print_r($this->cache); echo "</pre>\n"; } } function WP_Object_Cache() { // Nothing here } } } ?>You can also download the code by using the link below:
Make sure that the code is saved in a file called object-cache.php inside of the /wp-content/ directory.
That should be all you need to do. To verify that the WordPress is actually using the object cache use the WinCache Statistics Script and check the “User and Session Cache” page:
http://social.technet.microsoft.com/wiki/
There is already a bunch of Hyper-V content up there.
I have already had people ask me why we are looking at doing a wiki when we already have Technet + KBs + Blogs + Forums.
There are a number of reasons for this (and to be clear – the Technet wiki is run by a different group at Microsoft – so they probably have more reasons than I have for this) but the biggest advantage that I see is that this is a great opportunity to get “real world best practices” in a place where everyone can access them.
So – if you have found that in your environment there are things that have worked well with Hyper-V, or things that have not, get over to the wiki and write it up for others to learn about it.
Cheers,
Ben
Now that we have WINCACHE 1.1 Beta release which supports user as well as session cache, I am going to tell you a way to integrate session cache with Joomla using WINCACHE. Joomla has the way of integrating session cache based on user cache implementation and that’s what I am going to explain today. Increasing performance of Joomla by enabling it’s user cache functionality using WINCACHE is explained here.
Joomla session code is modular enough and in order to enable session cache based on WINCACHE user cache, one needs to paste the below code in a file named wincache.php and place it at folder libraries joomla\session\storage. This folder path is relative to your Joomla root installation folder.
<?php// Check to ensure this file is within the rest of the frameworkdefined('JPATH_BASE') or die(); /*** WINCACHE session storage handler for PHP** @package Joomla.Framework* @subpackage Session* @since 1.5* @see http://www.php.net/manual/en/function.session-set-save-handler.php*/class JSessionStorageWincache extends JSessionStorage{ /** * Constructor * * @access protected * @param array $options optional parameters */ function __construct( $options = array() ) { if (!$this->test()) { return JError::raiseError(404, "The wincache extension is not available"); } parent::__construct($options); } /** * Open the SessionHandler backend. * * @access public * @param string $save_path The path to the session object. * @param string $session_name The name of the session. * @return boolean True on success, false otherwise. */ function open($save_path, $session_name) { return true; } /** * Close the SessionHandler backend. * * @access public * @return boolean True on success, false otherwise. */ function close() { return true; } /** * Read the data for a particular session identifier from the * SessionHandler backend. * * @access public * @param string $id The session identifier. * @return string The session data. */ function read($id) { $sess_id = 'sess_'.$id; return (string) wincache_ucache_get($sess_id); } /** * Write session data to the SessionHandler backend. * * @access public * @param string $id The session identifier. * @param string $session_data The session data. * @return boolean True on success, false otherwise. */ function write($id, $session_data) { $sess_id = 'sess_'.$id; return wincache_ucache_set($sess_id, $session_data, ini_get("session.gc_maxlifetime")); } /** * Destroy the data for a particular session identifier in the * SessionHandler backend. * * @access public * @param string $id The session identifier. * @return boolean True on success, false otherwise. */ function destroy($id) { $sess_id = 'sess_'.$id; return wincache_ucache_delete($sess_id); } /** * Garbage collect stale sessions from the SessionHandler backend. * * @access public * @param integer $maxlifetime The maximum age of a session. * @return boolean True on success, false otherwise. */ function gc($maxlifetime) { return true; } /** * Test to see if the SessionHandler is available. * * @static * @access public * @return boolean True on success, false otherwise. */ function test() { return (extension_loaded('wincache') && function_exists('wincache_ucache_get') && !strcmp(ini_get('wincache.ucenabled'), "1")); }} .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }I am also attaching the file ‘wincache.php’ in the zipped format. One can download, unzip and copy wincache.php that comes with it to joomla\session\storage folder.
Restart IIS and you are done. Now go to administrator page of Joomla and click on ‘Global Configuration’->’System’. Under ‘Session Settings’ one can see ‘wincache’ as part of Cache Handler. Select it from the drop down list and save the configuration. Pictorial representation of steps are below.
After login as ‘admin’ you will see the below page:
Click on ‘Global Configuration’ and then click on ‘System’ sub-link and one will see:
Click ‘wincache’ from ‘Session Settings’ drop down. Now ‘Save’ the configuration. And yes, restart IIS and you are done.
In order to verify that WINCACAHE is storing values in user cache, hit the homepage of your Joomla installation. Now open WINCACHE.PHP file which ships with the installation and click on tab named “User and Session Cache”. It should look something like below:
Now you can see session getting stored in user cache.
In this blog post you learnt how to leverage WINCACHE session cache functionality to enhance performance of Joomla. Hopefully this will be useful to you in running Joomla faster on WINDOWS. Happy caching and till we meet again ‘Good Bye’.
Thanks,
Don.
PS: This works only with WINCACHE version 1.1.0 and higher. So please make sure that you are not running any lower versions of WINCACHE like 1.0.0 or 1.0.1.
Today, I am pleased to announce the release of Beta 1 of the Microsoft IIS Smooth Streaming Format SDK 1.0.
The IIS Smooth Streaming Format SDK provides application developers the capability to mux encoded video and audio elementary streams into Smooth Streaming fragmented-MP4 format that is compliant with the Smooth Streaming Format and Protected Interoperable File Format (PIFF) specifications. The IIS Smooth Streaming Format SDK includes a native C++ static library that can be linked into your applications to support the muxing of fragmented-MP4 into files or sent live via HTTP POST to a server running Internet Information Services (IIS) 7.0 and IIS Media Services 3.0. The SDK is available for download here – Download IIS Smooth Streaming.
Documentation for the SDK can be found online here – IIS Smooth Streaming Format SDK MSDN documentation and the release notes are available here – IIS Smooth Streaming Format SDK Beta 1 Release Notes.
The primary purpose of the IIS Smooth Streaming Format SDK is to enable developers to create applications that can generate PIFF compliant Smooth Streaming formatted fragmented-MP4 files for use in video-on-demand and live streaming scenarios. In addition, the SDK can be used to encrypt content using standard AES encryption as required by the PIFF specification (this SDK only supports the PlayReady specific protection headers).
It is expected that the video and audio encoding functionality is done externally from the SDK. Encoding for VC-1 can be accomplished by using the Microsoft VC-1 Encoder SDK – Professional. If you wish to do H.264 encoding, you will need to acquire a 3rd party H.264 encoding SDK and AAC audio encoder. There are lots of encoding library choices available both free and commercial.
The components of the SDK include:
The key features of this Beta 1 release of the Smooth Streaming Format SDK are:
To give you a peek at the roadmap, some upcoming features planned for Beta 2 include:
NOTE: Beta 1 of the SDK is provided for evaluation purposes and for use in testing your Smooth Streaming encoding implementations. Beta 1 does not currently give you a “Go-Live” license, so you will need to wait until Beta 2 if you plan to use this in production.
If you have questions on how to use this SDK in your applications, comments, or feedback on the SDK please send them to me directly or to smooth@microsoft.com.
We are looking forward to incorporating your feedback and ideas into the Beta 2 release.
Resources
Now that we have WINCACHE 1.1 Beta released which has got implementation for both user and session cache, one can easily take advantage of WINCACHE user cache and increase performance of Joomla. In this post I am going to tell you steps to use WINCACHE user cache with Joomla.
Joomla caching code is modular and in order to enable WINCACHE user cache, one needs to paste the below code in a file named wincache.php and place it at folder libraries\joomla\cache\storage. All the folders mentioned here is with respect to root folder of Joomla installation.
<?php// Check to ensure this file is within the rest of the frameworkdefined('JPATH_BASE') or die(); /** * WINCACHE cache storage handler */class JCacheStorageWincache extends JCacheStorage{ /** * Constructor * * @access protected * @param array $options optional parameters */ function __construct( $options = array() ) { parent::__construct($options); $config = & JFactory::getConfig(); $this->_hash = $config->getValue('config.secret'); } /** * Get cached data from WINCACHE by id and group * * @access public * @param string $id The cache data id * @param string $group The cache data group * @param boolean $checkTime True to verify cache time expiration threshold * @return mixed Boolean false on failure or a cached data string * @since 1.5 */ function get($id, $group, $checkTime) { $cache_id = $this->_getCacheId($id, $group); $this->_setExpire($cache_id); return wincache_ucache_get($cache_id); } /** * Store the data to WINCACHE by id and group * * @access public * @param string $id The cache data id * @param string $group The cache data group * @param string $data The data to store in cache * @return boolean True on success, false otherwise * @since 1.5 */ function store($id, $group, $data) { $cache_id = $this->_getCacheId($id, $group); wincache_ucache_set($cache_id.'_expire', time()); return wincache_ucache_set($cache_id, $data, $this->_lifetime); } /** * Remove a cached data entry by id and group * * @access public * @param string $id The cache data id * @param string $group The cache data group * @return boolean True on success, false otherwise * @since 1.5 */ function remove($id, $group) { $cache_id = $this->_getCacheId($id, $group); wincache_ucache_delete($cache_id.'_expire'); return wincache_ucache_delete($cache_id); } /** * Clean cache for a group given a mode. * * group mode : cleans all cache in the group * notgroup mode : cleans all cache not in the group * * @access public * @param string $group The cache data group * @param string $mode The mode for cleaning cache [group|notgroup] * @return boolean True on success, false otherwise * @since 1.5 */ function clean($group, $mode) { return true; } /** * Test to see if the cache storage is available. * * @static * @access public * @return boolean True on success, false otherwise. */ function test() { return (extension_loaded('wincache') && function_exists('wincache_ucache_get') && !strcmp(ini_get('wincache.ucenabled'), "1")); } /** * Set expire time on each call since memcache sets it on cache creation. * * @access private * * @param string $key Cache key to expire. * @param integer $lifetime Lifetime of the data in seconds. */ function _setExpire($key) { $lifetime = $this->_lifetime; $expire = wincache_ucache_get($key.'_expire'); // set prune period if ($expire + $lifetime < time()) { wincache_ucache_delete($key); wincache_ucache_delete($key.'_expire'); } else { wincache_ucache_set($key.'_expire', time()); } } /** * Get a cache_id string from an id/group pair * * @access private * @param string $id The cache data id * @param string $group The cache data group * @return string The cache_id string * @since 1.5 */ function _getCacheId($id, $group) { $name = md5($this->_application.'-'.$id.'-'.$this->_hash.'-'.$this->_language); return 'cache_'.$group.'-'.$name; }} .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }I am also attaching the file named ‘wincache.php’ in zipped format which can be unzipped and wincache.php can be directly copied to libraries\joomla\cache\storage folder.
Restart IIS and go to administrator page of Joomla and click on ‘Global Configuration’->’System’. Under ‘Cache Settings’ one can see ‘wincache’ as part of Cache Handler. Select it from the drop down list and save the configuration. Pictorial representation below after login to control panel using admin password.
After you are logged in as administrator one will see below page:
Click on ‘Global Configuration’ icon:
Click next on ‘System’ tab and then click on drop down ‘Cache Settings’ as shown below:
Select ‘wincache’ from drop down. Also click on radio button ‘Yes’ for Cache label.
Save the settings and restart IIS.
In order to verify that WINCACAHE is storing values in user cache, hit the homepage of your Joomla installation. Now open WINCACHE.PHP file which ships with the installation and click on tab named “User and Session Cache”. It should look something like below:
In this blog post you learnt how to leverage WINCACHE user cache functionality to enhance performance of Joomla. Hopefully this will be useful to you in running Joomla faster on WINDOWS. Happy caching and till we meet again ‘Good Bye’.
Thanks,
Don.
PS: This works only with WINCACHE version 1.1.0 and higher. So please make sure that you are not running any lower versions of WINCACHE like 1.0.0 or 1.0.1.
Hola
Merece la pena darse una vuelta:
Saludos
Since the WinCache Extension for PHP has been released last year it has been widely deployed by customers who run PHP on Windows OS and it has proven to provide a substantial performance boost for PHP applications hosted on Windows-based web servers.
Today IIS team has published a beta of WinCache 1.1, which provides more options for improving performance of PHP applications on Windows. Specifically, the new version includes :
The beta builds of the extension can be downloaded and installed from the extension home page at: http://www.iis.net/expand/wincacheforphp (look for the “WinCache 1.1 – Beta” section there). The source code can be obtained from http://pecl.php.net/package/WinCache/1.1.0. The documentation for the extension can be found on PHP.NET WinCache documentation.
This is the beta release and the WinCache team is looking for your feedback on new features and functionality. Use the WinCache Community Forum to ask questions about the extension, report bugs and problems and to suggest features and improvements.
I was working with one of our partner who want to migrate 30+ sites from an existing IIS6 server, to a new IIS6 server. We had an old tool IIS6 Migration Tool which would come handy, but this would be requiring 30 steps to migrate 30 websites one by one. Here comes the new tool which was specifically targeted for IIS6 to IIS7 migration, but it should help people doing a migration from a old IIS6 to a new IIS6.
In this blog, I'm taking a simple scenario where we are going to an offline upgrade.
Read the complete post here http://blogs.msdn.com/rakkimk/archive/2010/03/02/msdeploy-can-i-use-it-to-migrate-my-iis6-to-another-iis6-oh-yes.aspx.
Hola
Se acaba de publicar este Whitepaper, que he añadido a la colección de recursos sobre Hyper-V:
La metodología utilizada se ha orientado a discernir cual el la penalización de rendimiento de introducir en la ecuación la pila de encapsulamiento de datos dentro del formato VHD, por un lado, y por otro evaluar qué sucede al meter además la capa de Hypervisor.
Como ya hemos comentado en alguna ocasión, el conocimiento de los patrones de uso del IO de aquello que pretendemos virtualizar por un lado, y de como se comporta nuestro almacenamiento puede tener mucho más impacto que aplicar la regla bien conocida de que un disco pass-throug tiene mejor rendimiento que un VHD de tamaño fijo, este a su vez mejor que un de crecimiento dinámico, y que cuantos mas discos diferenciales enlacemos peor rendimiento tendremos. Conviene estudiarse la tabla de pros y contras, porque muchas veces por diferencias de rendimiento casi despreciables perdemos funcionalidades que nos pueden resultar muy útiles.
Os recomiendo su atenta lectura.
Saludos
We have released a bunch of updated documentation in the last week.
The first thing to look at is the Live Migration Network Configuration Guide. The really neat part of this is that it talks through all the supported / unsupported network configuration options. It also talks how to use the network QoS support built into Windows in order to safely share network connections in such a configuration (this is a neat option that I often use in my demo setups):
http://technet.microsoft.com/en-us/library/ff428137(WS.10).aspx
The next thing to look at is a new Virtual Hard Disk performance white paper that we have released that analyzes the performance characteristics of virtual hard disks in Windows Server 2008 R2 and contrasts it to Windows Server 2008. Lots of interesting technical detail in here:
Cheers,
Ben
Posts anteriores:
Hola
Sin ningún lugar a dudas, el almacenamiento es una de las piezas clave a la hora de hablar de virtualización. El hecho de virtualizar un servidor no implica que la carga de trabajo que corra en el vaya a tener un patrón de uso del almacenamiento diferente al que utilizaría en físico. Y lógicamente, cuanto mayor sea la densidad de máquinas virtuales, mayor será la superposición de dichos patrones del host de virtualización hacia el sistema de almacenamiento. Hable de este tipo de cosas en este post acerca de los Cluster Shared Volumes:
Para el caso que nos ocupa, si queremos probar las funcionalidades de HA y Live Migration necesitaremos contar con almacenamiento compartido al cual accederán los hosts por Fiber Channel y/o iSCSI
NOTA: El uso de sistemas NAS basados en CIFS/NFS, si bien funciona con Hyper-V, no está oficialmente soportado por ahora. Para más información al respecto, este es el post de referencia, de la mano de nuestro compañero José Barreto: Failover Clustering for Windows Server 2008 Hyper-V with File Server Storage
En el caso de nuestro laboratorio, todo funciona a través de iSCSI (mucho más barato que FC) contra dos sistemas de almacenamiento. Uno de ellos está basado en Windows Storage Server 2008, que incluye el Microsoft iSCSI Target, y el otro es una cabina SAN que amablemente nos presta NetApp. Tenemos montados laboratorios similares basados también en cabinas Dell Equalogic, y EVAs y MSAs de HP (tengo muchas ganas de probar también las Lefthand). También conozco casos de entornos basados en otros Targets iSCSI basados en software, como los de StarWind.
El esquema que hemos seguido es el siguiente:
La obsesión de tener todo almacenado en la SAN es sencilla de entender. Rinde estupendamente y si además tu cabina deduplica, los ahorros de espacio son sencillamente espectaculares. Por otro lado, recordemos que queremos la máxima granularidad y aislamiento entre las piezas. Si alguien se carga algún servidor físico, o lo cambias por otro de diferentes características, sus máquinas virtuales no están en los discos locales. Y si alguien borra inadvertidamente alguna de las máquinas virtuales mencionadas anteriormente, sus datos críticos siguen disponibles en espera de que aprovisionemos un nuevo servidor virtual o restauremos el backup, que será mucho más ligero al carecer de un gran volumen de datos.
La conexión de los servidores físicos con el almacenamiento es una de las primeras tareas que hay que abordar en el montaje de estos entornos, y la experiencia dice que suele ser uno de los principales escollos técnicos. He aquí algunas pistas y trucos que pueden hacer que el proceso sea más sencillo:
Todas estas operaciones pueden llevarse a cabo antes o después de haber agregado el role de Hyper-V. Se siga el orden que se siga, si que es interesante haber pensado, antes incluso de instalar los hosts, acerca de qué tipo de almacenamiento vamos a tener a nuestro disposición y cómo vamos a utilizarlo. Como hemos dicho al principio, es una de las piezas claves a tener en cuanta a la hora de planificar lo que vamos a poder hacer y lo que no.
Saludos