que trabajo en Tuenti como ingeniero de Frontend (Core team). Como no he venido aqui a hablar de mi, el que quiera saber... http://personalportfolio.kartones.net En la intimidad sigo programando en C# ;)
un hosting (dedicado en el mejor de los casos) • 1er warning: Aparecemos en Slashdot/Techcrunch/similar: hosting caido por exceso de tráfico hasta que salimos de portada. Temporal. • 2º warning: Las visitas no paran de subir: navegación lenta, timeouts, imágenes que no cargan, errores de Javascript,... Permanente.
de verdad (SQL Server o similar), si el tráfico aumenta mucho caerán igual. • Solución: Escalado de BBDDs: – Escalado Horizontal: Más servidores de BBDDs + particionado de datos. – Escalado Vertical: Más CPUs, Más RAM (mejorar los servidores existentes). • Hay un límite/tope de ganancia por servidor, y añadir nuevos o mejores cuesta mucho dinero.
umbral. • Balanceo en servidores de Reads + servidores de Writes. – Normalmente leemos muchas más veces de las que escribimos. Pero no siempre es así. – Sigue siendo muy caro. • Da igual qué hagamos, sólo emplear BBDDs es insostenible.
que nunca se produce :) • Pero después de ese caso, lo mejor es un acceso a memoria en lugar de a disco. • SQL Server y otros SGBDs serios tienen caches internas, optimizadores, etc. Pero sigue siendo costoso (por CPU, por nº de conexiones, por tope de RAM…). • ¿Por qué no aprovechar lo barata que es la RAM y montar un hashtable enorme?
BBDD • Memcached (PHP) y Velocity (.NET) • Base/premisa muy simple: – Hashtable gigante de key-value pairs de strings. – Reads: Si está en memoria deserializar, sino leer de BBDD + serializar en memoria (cachear). – Writes: Escribir en BBDD e invalidar en memoria si existía. – Normalmente se tiene también un sistema de “warm up” para datos que queramos presentes.
deben actualizar valores en memoria, podría provocar una “avalancha” (típico en redes sociales). Mejor solo invalidar la clave de cache. – Particionar las claves de las caches. – Throttling/Priming: Al reiniciar un servidor de cache o cambiar muchos datos, no recargar todos los datos de golpe, es muy fácil tumbar las BBDDs. – Lazy deletes: No borrar al momento, realizar sanity checks por código y borrar datos que no existan. Deletes en cadena provocan avalanchas. – Race conditions, concurrencia, fallos eléctricos...
muchos registros • Particionado simple: ID mod N • Adapta el particionado a tus datos: por provincias, por categorías, por meses... • Particionado avanzado: combinación de los anteriores • De hecho, deberías adaptar tu DAL para que soporte particionado de base y lo más transparente y escalable posible.
a otro lado (tabla o servidor) el resto. • Por ejemplo, Twitter almacena (y memcachea) los X últimos status de cada usuario, el resto está archivado. Accesos muy rápidos a datos recientes, más lentos y costosos a datos antiguos. • El patrón de diseño Iterator (PHP y .NET) es muy práctico para ocultar el archivado al resto de la aplicación.
una web cargue rápido, sino que parezca que carga rápido. • Usar AJAX para cargar todo lo posible. Mostrar contenido básico, cargar luego el resto (Amazon no carga reviews, comentarios, etc. Hasta que no se hace scroll). • Ejecutar javascripts al final de la página. HTML5 añade el atributo “async” a <script>. • Cada HttpRequest cuenta, sobretodo si es a un site externo.
imagen grande que 10 pequeñas. ASP.NET 4 trae soporte. • Usa PageSpeed e YSlow en Firefox o MySpace's Performance Tracker en IE para buscar mejoras. • El tamaño SI importa. Minimiza CSS, JS y si puedes hasta el HTML. • Desactiva el ViewState en ASP.NET si no lo necesitas.
las cosas se ponen serias, casi siempre lo mejor es un DIY (Do It Yourself). • Un framework suele tener gran % de features no necesarias, y no suelen escalar bien. • Ejemplo: Tuenti – El “framework base” pesa unos pocos KB – Módulos para diferentes Controllers – Módulos para componentes complejos (Chat, video player, ...)
Safari Mac != Safari Windows Firefox Windows != Firefox Linux IE6 != IE7 != IE8 • Ningún browser es 100% multiplataforma • Una forma de combatirlos: Bottom-Up capabilities: Partir de un mínimo (IE6) y subir en features, CSS e incluso JS * * En JS es inevitable terminar haciendo hacks o directamente versiones según el browser.
worst” • Nunca asumas datos consistentes y existentes. • Sampling rate de errores: Si algo falla catastróficamente, podría caerse la BBDD de de errores por demasiados logs. • Nunca se loguea suficiente información... • Revisa los logs de errores, busca la fuente de los problemas recurrentes.
extremadamente propenso a errores; pero es gratis, abierto y rápido. Ejemplos: • En PHP los Singletons son un problema: PHPUnit es un "parche", no un framework 100% unitario, al estar hecho en PHP no puede testear singletons correctamente (entre otros problemas). • PHP no es tipado: Cuidado con conversiones de datos, parámetros, SQL Injection, XSS... • Hay comandos "prohibidos" (pero disponibles), otros desaconsejados por velocidad o consumo de memoria...
y C# es de lo mejor que existe como lenguaje en sí. • ASP.NET WebForms maduro, bien diseñado, extensible y potente (HttpHandlers == DIY!) • NUnit/XUnit/MB Unit/VS Tests son frameworks maduros y 100% funcionales. • ASP.NET MVC: Por fin una implementación oficial (en PHP y Java llevan años). V1.0 finalizada, 2.0 en camino.
variables de más, un mal liberado de objetos/memoria… No duelen en una aplicación normal. • Pero si lo multiplicamos por millones (o por miles en un segundo), entonces puede volverse muy importante. • Tener buenas costumbres de codificación, refactorizar código y leer sobre optimización de código ayuda a prevenir.
IDE de desarrollo existente * • Digan lo que digan los trolls linuxeros, un vim no sustituye a un entorno visual (resaltado de errores de sintaxis, refactoring, MDI/tabs/multi-monitor…). • Aprender algún shorcut y personalizar el IDE se traducen en mejoras de productividad. * Dicho incluso por gente anti-MS ;)
catastrófico. • Arreglar problemas es mucho más costoso y difícil que prevenirlos. • Lite.facebook.com : Su mera existencia denotaba un problema de diseño (excesiva información, framework que daba muchos errores,…). • MSDN: Demasiado peso de página para "solo texto", navegación muy pesada. Versiones lite y low-band (sin javascript, puro HTML) + rediseño de la versión normal.
un desastre: – Comenzó como intercambio de mensajes mediante comandos "modo texto“. “VER 1 MSNP11 CVR0” – Añadido soporte de XML y "ficheros" XML: Ciertos comandos devuelven XML en lugar de comando de 3 letras + parámetros estandar. – Añadido soporte de SOAP: Tras la autenticación, desde MSNP13 muchas operaciones se realizan mediante llamadas SOAP en lugar de comandos. – A ver quién es el valiente que lo reprograma y crea un wrapper para que siga funcionando MSNP18 a la vez (con +100 millones de usuarios de Messenger en todo el mundo)
olvidarse de escalarlo. • Mucho más optimizado: No JS o sólo en WebKit, imágenes más pequeñas, menos contenido, diseño más compacto... • Cada byte “pesa” muchísimo más. • Testeo intensivo: PocketIE ni siquiera pinta CSS1 al 100%, Opera Mini parece de los 90, docenas de resoluciones distintas (todas menores al ya casi estandar 1024x768)…
Reducción de diseño, pero también de features: Es imposible replicar el 100% de features de un site normal, salvo que sea algo estilo Twitter. • - WUFRL está muy lejos de ser perfecto. Ej: usa bool para XHTML_FILE_UPLOAD, con lo que se producen falsos positivos y falsos negativos. – Muchos móviles mienten respecto a sus capabilities. – User Agent detection ayuda mucho pero requiere esfuerzo. Llenos de basura no determinista. – Algunas aplicaciones lo machacan (ej: MegaUpload toolbar). – Importante mantener una BBDD de UAs. – Casi obligatorio limpiarlo, parsearlo, aplicarle lógica difusa u otro sistema de matching. – Aplica cacheo a los UAs. Recuerda: estamos operando con strings y haciendo querys a BBDD!
con herramientas de terceros.. • Acceptance tests: Frontend. • Regression tests, manual tests (con docs. o guidelines, no a pelo!)... • Revisar logs de errores: Parece obvio, pero se olvida a menudo. • Entorno de desarrollo, entorno de testing, pre- producción, Virtual Machines...
PPT), features experimentales (“Labs” de GMail), ... • El feedback de los usuarios es crítico para mejorar, sea voluntario (formularios, encuestas, focus groups, ...) o indirecto (métricas, profiling, tracking, ...) A B
trucos, etc. • Facebook deja que Google indexe sólo ciertos datos de los perfiles de usuarios. En Tuenti no hay SEO porque no dejamos que indexen. • En Tuenti usamos un load balancer hecho en Javascript y AJAX en lugar de uno por hardware. • Si tienes millones de visitas diarias, es más que recomendable especializar servidores (para servir páginas web, para BBDD, para cache, para chat…) • Code-State-Cache-Data: Mayor división “por capas”. • Azure: Cacheo, particionado, load balancing…
espacial): • Hasta 30.000 jugadores concurrentes en un solo “fragmento de universo” • Windows Server 2003 x64, SQL Server 2005 • Stackless Python (scripting, no compilado!) • 150.000.000 DB transactions al día!!! (tras una capa de cacheo!)