DDoS-stats van 27 december

Door ACM op dinsdag 28 december 2010 12:17 - Reacties (15)
Categorie: Tweakers.net, Views: 5.742

Gisterochtend werden we aangevallen met een DDoS-aanval. Het was zo te zien een vrij standaard aanval, waarbij men probeerde continu nieuwe verbindingen naar onze webservers te openen.
Dat is niettemin een behoorlijk lastige aanvalsvorm om goed af te slaan en zorgde er dan ook voor dat de site in het begin van de aanval toch wat minder goed bereikbaar was.
Gelukkig wist onze, begin dit jaar aangeschafte, ddos-appliance de boel behoorlijk goed tegen te houden, waardoor de overlast toch redelijk beperkt bleef. En die appliance houdt uiteraard ook allerlei statistieken bij, dus bij deze een kort overzichtje :)

Tijdens de piek van de aanval, even voor 12:00 uur, kregen we zo'n 80Mbit aan inkomend verkeer, waar we normaal tussen de 5 en 10Mbit zitten. De piek was overigens wel vrij kort, waarna de aanval gestaag afnam. Onderstaand grafiekje laat dat mooi zien. De pieken rond 11:45u, 14:45u en later zijn onderhoudstaken, die horen niet bij de DDoS.

Riorey Link utilization 2010-12-27

Overigens is de aanval nu nog steeds niet helemaal weg. Aan het begin deden we (naar schatting) richting de 120.000 aanvallende packets per seconde, na een uur zat dat op zo'n 90.000 en nu is dat nog slechts zo'n 1200. Ons normale verkeer bestaat op dit moment uit ongeveer 7000 packets/seconde.

Het aandeel "vervuiling" is daardoor nog steeds wel vrij hoog. Gistermiddag was het ongeveer 90%, nu nog steeds 5% van het totale verkeer en 50% van de "tcp syn's". Het verloop van het totaal kan je vrij goed zien in dit plaatje.

Riorey Packet pollution 2010-12-27

In totaal leverde dat sinds 11:52u gisterochtend 1.442.375.536 tcp/ip-packets onze kant op. Daarvan waren 1.432.525.268 gemarkeerd als onderdeel van de aanval, ruim 99,30% dus. Die packets waren goed voor 96.590.347.964 bytes (net geen 90GB) en ook daarvan was een groot deel aanvallend; 95.909.389.716 bytes oftewel 99,29%.

Optimizing applications and why sampling profilers for java fail en

By ACM on Thursday 11 November 2010 20:55 - Comments (15)
Category: Development, Views: 11.128

Today I found out why sampling profilers for Java applications don't necessarily yield correct results. As an introduction, I start with some general text about discovering performance issues for (web)applications :)

If you pay attention to the performance of your site, you can commonly find points in your code that can be optimized to reduce run time of your application. At Tweakers.net we keep an eye on the site's performance. We (try to) find and optimize slow pages and the overall (perceived) speed of the site. And as you probably know, we did that way before Google started to use page speed as a component of their ranking ;)

Like many players in this world, we also found parts of the code that couldn't easily be optimized much further in either the database, the php-code or the apache-webserver.
Depending on the situation we took different approaches to optimize that: We started using memcached to reduce the number of queries and processing involved with fetching common data. We introduced a message queue in our set-up, allowing asynchronous execution of certain parts of the code. We installed reverse caching proxies, completely eliminating most repeated php-processing involved with semi-dynamic images. And we started using our "pricewatch engine", a internal "service" written in Java to exploit its better performance, more advanced memory management and ability to keep lots of data efficiently in memory.

All those ideas came from some form of profiling. A lot of the optimizations involved reduce or replace queries to our mysql-databases. Choosing which to optimize is mostly a matter of digging through logs, common sense and earlier optimization experiences. That reasonably works well, but only gets you so far. The tools, specifically designed for this, I've used so far for identifying which queries require optimization didn't seem to help much. It is very common for us to see a query being fast in most cases, but with some parameters being relatively slow. Apart from that, we see occasional, but major, slowdowns in queries that are normally very fast. Both situations aren't handled too well by such generic tools.

For our php code it is the same story. Its mostly common sense and very raw profiling using timers. A profiler like xdebug simply introduces way to much overhead (i.e. the "observer effect") to be used in production. Some other tools have evolved nowadays, but they're normally quite costly and I'm not very convinced they help us much in identifying actual bottlenecks. That's mainly because of the simple notion that most of the php-time is spent waiting on resources. In the cases where php was actually a hot spot, it was normally relatively easy to find. The ones we didn't find are probably not too important, as we've no real complaints about our website's performance.

We've also rewritten parts of our code in Java. A Java server application normally has much better performance and the ability to cache large amounts of data with very low latency. I.e. serializing and unserializing data to and from memcached into php is very costly compared to what we do in Java. That is one of the reasons our category pages in the pricewatch are still much faster than before the switch, even though we added several new features and the amount of products and specifications has grown over time.
Finding hot spots in Java code is much harder than in php. Due to compilation and the required restarting of services the overhead of introducing a timer somewhere is very high compared to a properly set up php test site. And to make matters worse, by restarting and/or introducing timing code you may impact the performance of your code much more than with php or sql; the JVM's hot spot optimization in Java is not very easy to predict for normal developers.

Luckily, for Java there are a bunch of profilers available that can be connected to (live) programs to introduce light weight collection of timing data. There are basically two types; sampling profilers and instrumenting profilers. Sampling profilers simply wait a bit, take a snapshot of the call trees and do the same thing again untill stopped. Instrumenting profilers use Java's dynamic code abilities to alter methods of selected classes to add some tiny bit of data collection code at the start and end of a method body.
The instrumentation variant has a major drawback; it introduces a huge overhead that severly impacts the way the JVM will do its work. Basically you're simply profiling a different application. To prevent this overhead, most profilers allow you to select which classes and/or methods should get instrumentation code and which not. This has the advantage of having much less overhead, but may prevent you from detecting a actual hot spot.

The sampling profiler does not have this disadvantage. The only disadvantage most people are aware of is that it may not sample often enough to actually capture very short method calls. But given enough time and a sufficiently small sampling interval, basic statistics suggests that shouldn't be much of a problem. As I can simply re-play the access logs (40M entries currently readily available for me) from our Tomcat application servers, its easy to pound a test environment with hours worth of requests.
Still, the sampling profilers I used didn't necessarily produce hot spot lists I agreed with. And I didn't really understand why. After many thousands of requests to Tomcat, you'd expect it to be able to collect numerous samples and thus easily pinpoint actual hot spots. But it doesn't always work that way.

According to this study it has to do with the fact that profilers don't really sample at the given intervals and at the same time should more randomly distribute the intervals. The intervals are more of a guide for when to take a sample, the actual samples seem to be taken at the next "yield point" (i.e. a point in the executable code at which the JVM allows preemptive switching to another thread). Ironically, those yield points are optimized by the JVM for better performance, potentially keeping them out of the hot spots in your code... The randomization issue also has to do with the yield points. When you switch at an exact interval, you are in sync with any other regular interval in the JVM or OS including thread schedulers. And, annoyingly, even the sampling profilers introduce a bit of an observer effect to the application (they do have to collect the data and such), albeit a much smaller one than those for the instrumentation profilers.
Given all that, you can't really trust the current Java profilers (I know of) too well. This makes it actually quite hard to optimize details in your code as you may not really know which methods are really consuming your cpu time. The general parts of your code (higher up the call-tree) are probably identified mostly correctly, so you will still get a sense of where to look.

I don't really have a solution for any of these issues, but I'd appreciate anyone's opinion or hint for proper tooling on any of the platforms discussed here. For now, its mostly still common sense and a bit of an art to optimize a application ;)

Aanbevolen producten in de Pricewatch

Door ACM op vrijdag 25 juni 2010 21:25 - Reacties (8)
Categorie: Pricewatch, Views: 5.106

In februari introduceerden we vergelijkbare producten. Door de specificaties van producten in een categorie te vergelijken kunnen we de 'euclidische afstand' tussen producten bepalen.
Vervolgens pakken we daar de beste matches uit en laten hetzelfde algoritme los op de recente bezoekersinteresse in de producten. Het idee daarachter is tenslotte dat bezoekers, die een bepaald type product zoeken, meerdere vergelijkbare producten bezoeken. En in de praktijk klopt dat ook :)

Wel bleek de afgelopen tijd dat er nogal zwaar werd gefocused op onbenullige specificaties. De specificaties die bovendien ook nog het vaakst incompleet of inconsistent ingevuld waren. Daar hebben we de afgelopen tijd nog wat aan getuned. De telefoons zijn daarbij een mooi voorbeeld omdat ze erg veel specificaties en filters kennen. Voorheen zag je allerlei telefoons waarvan het totaal niet duidelijk was waarom ze er nou eigenlijk bij stonden, terwijl belangrijke aspecten - zoals de schermgrootte, het type scherm en het OS - nauwelijks meespeelden. Nu zie je telefoons die echt behoorlijk goed vergelijkbaar zijn. Uiteraard hopen we zo de bezoeker nog beter door het doolhof van de productkeuzes te kunnen helpen.

Hetzelfde algoritme bleek ook toepasbaar op los bezoekersgedrag. Op die manier kunnen we van een individuele bezoeker proberen wat producten aan te bieden waar hij mogelijk interesse in heeft. We weten tenslotte wat hij zoal bekeken heeft en wat anderen, die diezelfde producten ook bekeken, bekeken hebben.
Als je bijvoorbeeld geintereseerd bent in de Samsung Galaxy S, HTC Desire en Google Nexus One. Dan zal het er op de pricewatch-index ongeveer zo uit kunnen zien:
Aanbevolen producten

Ik kan me goed voorstellen dat anderen ook de zilveren Desire, iPhone 4 en HTC Wildfire hebben bekeken en, inderdaad, ik heb ze nog niet bekeken. Uiteraard verschilt het gedrag met andere producten. Het is sowieso maar net hoe populair de producten zijn die je bekijkt en wat voor willekeurig gedrag bezoekers ermee hebben.

Als je bijvoorbeeld een populair fototoestel en een nas-oplossing bekijkt, ziet het er ongeveer zo uit:
Aanbevolen producten, 2e voorbeeld

Mocht je het zelf willen bekijken, hou er dan rekening mee dat er gebruik wordt gemaakt van je sessie. Oftewel, als je veel verschillende producten bekijkt zal er vanzelf een chaos ontstaan die zich vooral richt op de populairste producten (je kan uiteraard een andere browser starten om een schone sessie te krijgen). Verder kijken we voorlopig alleen naar heel recent bezoekgedrag, de afgelopen 24 uur. Hoewel ik wel verwacht dat we dat nog een stukje willen oprekken is het niet bedoeling dat we je met maanden aan bezoekgedrag blijven confronteren. Om die reden krijg je ook geen producten te zien die je reeds zelf bezocht hebt, het bestaan daarvan weet je tenslotte al.
Overigens zit er een vertraging van maximaal 5 minuten in de weergave, het is vrij kostbaar om dit helemaal on-the-fly uit te rekenen, dus een groot deel van het voorwerk wordt elke vijf minuten gecached :)
En als laatste, als je nog niks bezocht hebt, krijg je toch resultaten te zien, dan krijg je domweg populaire producten te zien, net als het blokje op de frontpage. Dit zijn tenslotte de producten waarvan we weten dat veel andere bezoekers er in geinteresseerd waren, dus deze hebben dan de grootste kans om de interesse van de bezoeker te wekken.

Ik hoor graag jullie mening over de werking en verbeterpunten van deze nieuwe functionaliteit. Echter zit ik niet zo te wachten op allerlei discussies over privacy, door de korte periode waarover we de hiervoor gebruikte gegevens bewaren zie ik geen reden je daar heel erg zorgen om te maken. Voorts worden de gegevens anoniem en enkel in massaverwerking gebruikt, de individuele gegevens gebruiken we slechts alleen om het lijstje voor de individu die te pagina bekijkt te genereren. Dus ik hoop dat we dat aspect bij deze kunnen laten voor wat het is :)

T.net Browserstatsistieken 2009-2010

Door ACM op zondag 20 juni 2010 16:42 - Reacties (10)
Categorie: Browsers, Views: 4.237

Zoals beloofd geef ik zo nu en dan wat statistieken van de bezoekers op Tweakers.net. Dit keer weer de browsers. Bij de operating systems is verder weinig echt bijzonders voorgevallen, Windows 7 is ondertussen boven XP uitgegroeid als populairste OS en vooral Vista is verder weggezakt. Ondertussen is Windows 7 goed voor zo'n 1/3e van de bezoeken en 2/5e van de pageviews.

Bij de mobiele browsers is Android een grote groeier geweest het afgelopen half jaar, van alle mobiele bezoekers had in december nog geen 15% Android. Ondertussen is dat gegroeid tot bijna 30% in mei, dit is zo op het oog vrijwel volledig te danken aan meer mobiele bezoekers, het absolute aantal iPhone-gebruikers was namelijk ook gestegen, maar Android steeg simpelweg sneller. T.o.v. het totaal aantal bezoekers hebben we het dan overigens nog steeds over enkele procenten.
Halverwege juni is door de introductie van de iPhone-app het absolute aantal iPhone-bezoekers op de frontpage (en op de mobiele site ook, maar daar gaan deze cijfers niet over) overigens gedaald. Dat heeft zelfs tot gevolg dat ik verwacht dat Android in die statistieken vanaf volgende maand het grootste mobiele platform wordt. Uiteraard is het dan niet meer een hele eerlijke vergelijking, want de iPhone-applicatie is daar dan niet meer bij meegeteld.

Bij de pageviews per browser is er op zich ook weinig voorgevallen. Maar toch is er een klein historisch feitje in de geschiedenis van Tweakers.net bij ontstaan: Internet Explorer is niet meer de grootste browser.
Waar Firefox-gebruikers al sinds halverwege 2008 meer pageviews dan Internet Explorer opleveren, is het nu dus voor het eerst zo dat een volle week lang Firefox de grootste browser op het gebied van bezoekers is. Het is wel ironisch dat dat niet komt doordat Firefox nou zo hard gegroeid is, maar doordat het minder hard gedaald is dan IE. En die daling komt uiteraard vrijwel volledig voor rekening van Chrome, hoewel ook Safari nog een beetje doorgroeide met beide cijfertjes.

Browser bezoeken per week jun 2010
Op het gebied van bezoeken is Firefox nu dus nipt groter. Of Firefox deze winst vast kan houden is natuurlijk maar de vraag, de geschiedenis wijst uit dat IE hardnekkiger is dan Firefox, simpelweg doordat het de standaard browser bij veel bedrijven is.

Browser pageviews per week jun 2010
Bij de pageviews is duidelijk te zien dat de alternatieve browsers - en dan vooral Firefox, Chrome en Opera - nog altijd veel meer pageviews per bezoeker opleveren dan Internet Explorer. Het is zelfs zo 'erg' dat als we de lijntjes van IE8 en Chrome hier doortrekken, we met enkele maanden een nieuwe browser op de 2e plek kunnen verwelkomen.
Een andere goede ontwikkeling, voor ons dan, is dat IE7 net als IE6 flink weggezakt is, vooral de laatste paar weken ging het hard. Wellicht dat veel scholen met IE7 werken? Qua pageviews komt het zelfs in de buurt van de nauwelijks fluctuerende Opera-lijn.
Aan de hand van deze grafiek zullen we ook weinig moeite gaan hebben met het besluit om IE7-support te laten vallen, zodra IE9 uitkomt :)

En dan nu met de goede plaatjes :P

Tweakers.net's overcapaciteit

Door ACM op dinsdag 8 juni 2010 22:17 - Reacties (20)
Categorie: Tweakers.net, Views: 5.013

We schaffen geregeld nieuwe hardware aan en de capaciteit daarvan is vaak veel groter dan we nodig hebben. Een goed voorbeeld was onze databaseserver eind vorig jaar.
Dat levert uiteraard wel eens de vraag op waarom we daar dan zoveel geld aan uitgeven, want het kan tenslotte ook goedkoper. "Dat kan toch ook wel met wat minder?" Tuurlijk kan dat. En dat zou ook eigenlijk altijd wel goed moeten gaan.
Nouja, bijna altijd. De backend voor de iPhone-app bevat een component dat weliswaar goed werkte, maar een relatief zware query bevatte. Doordat er vrij veel mensen tegelijk de app uitprobeerden werd die query in twee uur tijd vaker uitgevoerd dan normaal op een hele dag. En dat was daardoor duidelijk zichtbaar op de belasting van de databaseserver, de belasting was een stuk hoger dan normaal.

Artemis cpu-pieken door iphone-app?

Hoewel de hogere cpu-belasting volgens mij niet volledig door de iPhone-app werd veroorzaakt is, en er sowieso altijd een paar pittige pieken in de belasting zitten, is er toch wel een zichtbare overeenkomst tussen het moment dat crisp aangaf het gefixed te hebben (20:42u) en de afname van de cpu-belasting op dat plaatje...

Dus om nogmaals die vraag te beantwoorden; Ja, meestal kan een lichtere machine het prima aan... Maar het is prettig om overcapaciteit te hebben als een bepaalde query of stuk code in de praktijk slechter uit blijkt te pakken dan voorzien en/of de betreffende functionaliteit (ineens) zwaarder belast wordt dan voorzien. Zoals nu dus door de iPhone-app.
Het is overigens ook niet ongebruikelijk (een paar keer per maand!) dat een of andere losgeslagen crawler vele (zware) pagina's in rap tempo achter elkaar opvraagt... Onze firewall pikt die vaak wel op, maar als ik de pieken zie die dat oplevert ben ik toch elke keer ook weer blij met de overcapaciteit die we hebben, anders zouden de reguliere bezoekers er wellicht veel meer van merken dan tot nu toe het geval is.

En bij deze heb ik ook een keer een mooi concreet voorbeeld van onze keuze om overcapaciteit aan te brengen en te houden in ons serverpark :)