Etikettarkiv: redis

Docker är kittet i DevOps

Docker

Då och då dyker det upp mjukvara som underlättar livet avsevärt, då man nästan utropar Heureka! När jag först lärde mig använda Fabric så tycke jag att detta var ju guld värt: Att slippa göra samma sak manuellt på flera servrar. DevOps-filosofin i ett nötskal

Men! Nu tog jag mig tid och försökte lära mig Docker. Docker har tagit det hela lite längre och isolerar filer samt processer från underliggande operativsystem samt innehar versionshantering. Vad innebär detta då?

Jo, för sådana som mig som har beroenden långt utanför vad vanliga webbhotell kan leverera såsom Redis, Sphinx och Memcache så är Docker en mjukvara som löser detta.

Man kan kort och gott säga att Docker är ett operativsystem i operativsystemet. Lite som Xen eller Vmware men mycket ”lättare”.

I detta underliggande operativsystem så utgår du från en spegelbild som fungerar som bas och allt du lägger till får en ny revision. Detta gör exempelvis om du vill flytta en webbsajt med Redis, MySQL och Sphinx Search från en server till en annan så behöver du enbart flytta det som ändrats från spegelbilden.

Docker är så klart öppen källkod och helt gratis att använda. Och inte nog med det så är det ett MeetUp om några veckor i Stockholm om just DevOps och Docker med talare från bl.a. Spotify:

Webbutveckling för framtiden

HTML5Att webbutveckla för framtiden eller åtminstone anamma nya tekniker är något som jag gör ständigt. Här är några av de förbättringar/framsteg jag gör:

  • Från MySQL till Redis
  • Från HTML4 till HTML5
  • Från Apache till Nginx
  • Från sed/awk etc till MapReduce med Hadoop

Sen försöker jag i viss mån även att förbättra följande:

  • Nyttja PHP-frameworks i större omfattning
  • Webb-frameworks (typ Twitter Bootstrap)
  • Från PayPal till DIBS eller motsvarande för betalningslösningar
  • Och även uppgradera gammal kod att fungera med nya PHP-versioner, några saker jag ändrar är bl.a. mysql_* till mysqli_ och php short tags
  • Cufón

Så man slipper uppfinna hjulet allt för många gånger och att kod slutar fungera vid uppgraderingar. Men det finns även ett antal nya tekniker som jag önskar att jag hade mer tid att testa:

Något fundamentalt som jag missat?

Så programmerar du för molnet

Bild CC http://www.flickr.com/photos/torley/2311784203/in/photostream/Kanske en klyschig rubrik men det finns många saker man bör tänka på när din avsikt är att placera din kodbas i molnet. Och när jag skriver molnet så menar jag exempelvis Amazon EC2 där du hyr en virtuell server. Dessa åsikter är helt subjektiva och kan variera beroende programmeringsspråk eller molntyp.

Grundfilosofin bör dock alltid vara att skriva portabel kod utan statisk information såsom sökvägar eller annat som kan komma att ändra sig om du ökar eller minskar din kapacitet eller flyttar koden. Det är dock inte alltid helt lätt att skriva flexibel och portabel kod då du alltid någonstans måste inneha ett beroende mot den nuvarande plattformen.

  1. Undvik statiska sökvägar eller URL:er
  2. Dokumentera beroenden såsom Redis, MySQL och eventuella PHP-moduler som används
  3. Undvik versionsspecifika funktioner
  4. Inte direkt specifikt för molntjänster men glöm för all del inte att ta backup (och använd GitHub).
Och glöm framför allt inte säkerheten, som ska vara minst lika viktig i molnet som på din egen server eller VPS. Tyvärr blev detta inlägg inte riktigt så långt och innehållsrikt som jag hade tänkt mig, detta pg.a. att programmering för molnet inte skiljer sig allt för mycket mot ”vanlig” programmering.

Så byggde jag Biståndet.se

Uppdatering: Läs även om lanseringen av OpenAID där jag var med.

Jag tänkte redovisa hur jag byggde webbtjänsten Biståndet.se på några få timmar. Först och främst så läste jag den dokumentation som återfinnes till OpenAID API:et. Efter detta så skrev jag ihop en funktion som utifrån en URL hämtar hem data över HTTP och cachar denna i Redis:


$redis = new Redis();

$redis->connect('127.0.0.1', 6379);

function fetch($url) {
  global $redis;
  if(!$c = unserialize($redis->get($url))) { // Check if query is cached
    $c = json_decode(safeJSON_chars(file_get_contents($url))); // JSON fetch and decode
    $ret = $redis->set($url, serialize($c));
  }
  return $c;
}

Funktionen safeJSON_chars hittas här och används för att filtrera bort skräptecken.

Sedan genomför jag en första hämtning av samtliga länder och dess tillhörande bistånd:


$c = fetch("http://api.openaid.se/api/v1/country?");

foreach($c as $key => $val) {

$title = $val->name;

osv..

insertpost($title,  $osv..);

}

Sedan använder jag funktionen wp_insert_post() för att göra ett inlägg direkt in i WordPress. Den som är observant ser att jag lagrar frågorna mot OpenAID i all evighet vilket ej bör göras.

Så kommer du igång med Node.js

Först och främst så kanske jag ska skriva lite om vad Node.js är för något. Som du ser av filändelsen så är det ett JavaScript-språk och används på serversidan för att kommunicera med exempelvis en webbklient (webbläsare).

Node.js är eventbaserat, litet och lätt till skillnad mot exempelvis Apache. Dock är det värt att notera att Node.js inte är är skapat för att lösa alla problem utan har uppstått från realtidswebbens behov av snabb, skalbar och minnessnål.

Prestandamässigt så kan Node.js jämföras med Nginx (när enbart webbsidor levereras). Bland användare av Node.js så kan Yammer och Plurk nämnas.

– Installation –

Ladda hem källkoden som tar.gz eller zip från Github: https://github.com/joyent/node eller med kommandot:

$ git clone git://github.com/ry/node.git

Gå sedan in i katalogen som skapats och skriv ./configure och då skall det varna om något saknas, sen är det bara skriva make. Ta en kopp kaffe och vänta några minuter. Bland annat så byggs Googles V8 JavaScript-motor.

Om du som jag använder FreeBSD så kommer din byggprocess att misslyckas på två ställen, först och främst så måste du använda gmake istället för make och sedan så måste du lägga på den patch som återfinnes här.

'build' finished successfully (2m10.790s)
$ ./node -v
v0.5.0-pre

För att lättare komma åt node-binären samt dess verktyg så glöm inte att skriva gmake install (eller make install).

– Hello world med Node.JS –

Nu är det dags att skriva vårt första script samt se till att Node hanterar detta program korrekt. Scriptet helloworld.js ser ut enligt följande:

var sys = require("sys");
var http = require('http');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(80);

console.log('Server running at port 80');

Sedan för att se till att node exekverar och levererar ovan på TCP port 80 så skriver vi enligt följande:

$ sudo node helloworld.js
Server running at port 80

Observera att du måste köra detta med root-behörighet eftersom vi lyssnar på port 80. Många väljer att använda port 8080 eller liknande men det är inget jag rekommenderar eftersom många brandväggar ej släpper igenom denna port. Läs denna guide hur du undviker att köra som root men ändå kan använda port 80. Att köra program som root är något som du vill undvika i största mån då detta kan innebära en säkerhetsrisk.

Koden ovan är tämligen självförklarande. Om du vill använda Nginx + PHP på samma server så kan du binda till olika IP-nummer genom att ändra .listen(80); till .listen(80, ”1.2.3.4″); eller det IP-nummer du vill binda till. Du måste även binda Nginx till det andra IP-nummret.

Node.JS i bakgrunden

Om du vill ha möjligheten att lägga program i bakgrunden vilket är troligt i en skarp miljö så måste du göra enligt följande förfarande då det saknas en modul vid namn daemon.node.

  1. Ladda hem koden från https://github.com/Slashed/daemon.node
  2. Kompilera med hjälp av verktyget node-waf (följer med Node.JS) på följande sätt: node-waf configure build
  3. Lägg den binär med sökväg build/default/daemon.node i samma mapp som helloworld.js
  4. Byt ut koden mot nedan där två rader är tillagda:
var sys = require("sys");
var daemon = require("./daemon");
var http = require('http');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(80);

console.log('Server running at port 80');
daemon.start();

Startar du helloworld.js nu så läggs tjänsten i bakgrunden.

Trevligt! Hör av dig om du har några frågor. Nästa gång så går jag in på hur du kan kommunicera lätt mellan Redis och webbläsaren med hjälp av Node.JS

Serverstrul

Denna vecka så har mer eller mindre alla mina servrar strulat. Jag fick för mig att uppgradera Redis till en lite nyare version som har buggfixar samt äter mindre CPU och passade samtidigt på att uppgardera det PHP bibliotek jag använder för att prata med Redis till owlient/phpredis. Så klart så gick något fel och cachningen i Redis ballade ut och servern dog sakta men säkert pga alla SQL-frågor som ej cachades.

Nästa problem dyker upp på Bloggy då flertalet InnoDB-databasfiler försvinner vid en hastig omstart av servern och MySQL vägrar starta så jag får manuellt använda strace till att lista ut vilken databas som strular och bygga om flertalet tabeller. Då passar jag även på att uppgradera Varnish till senaste versionen och lägger in lite kod för att ej cacha WordPress-adminsidor vilket får till följd att inloggningen på Bloggy misslyckas för alla användare.

Samt så har även den server som sköter bloggsökmotorn Bloggz strulat.. vilket lärdom kan man dra av detta då? Jo, att om du uppgraderar eller ändrar minsta lilla så testa att det verkligen fungerar, lägg till exemeplevis dold HTML-kod som berättar om sidans element verkligen cachas eller ej.

Bildkälla: http://retecool.com/post/computable-awards--fail/1/

NoSQL: Redis, CouchDB och MongoDB prestanda

Eftersom jag testar NoSQL-mjukvaror såom Redis, CouchDB och MongoDB just nu  så genomförde jag ett litet prestandatest där Redis vann över CouchDB och MongoDB.

Så här lång tid tog det att stoppa in 100 000 objekt i en databas:

MongoDB

db version v1.2.2, pdfile version 4.5
real    13.306s
user    9.130s
sys     0.940s

Redis

Redis version 1.3.17
real    7.044s
user    5.330s
sys     0.070s
Redis version 2.1.5 (8d3e063a:0)
real    6.400s
user    4.760s
sys     0.110s

CouchDB

Apache CouchDB version 0.10.0

Fick inte vara med för att det tog 4 sekunder att sätta in 100 objekt. Ungefär samma prestanda som Amazon SQS, och då använde jag även full_commit=False vilket bör öka prestandan. Ska testa Hovercraft för att se om jag kan få upp prestandan.

Observera även att ovan tid inkluderar exekvering av Python, inladdning av moduler samt den kod som körs mellan det att information trycks in.

MongoDB – Test av NoSQL, del 1

Som läsare av denna blogg så vet du nog vid det här laget att jag har en stor kärlek till det som kallas för NoSQL. Dvs systemlösningar som inte enbart innefattar SQL.

Tre av de stora kandidaterna till att snabba upp MySQL eller byta ut MySQL helt heter Redis, CouchDB samt MongoDB men vilken ska man välja? Som du kanske förstår så finns det inget bra svar på detta men jag tänkte här nedan försöka ge en liten inblick hur det är att installera och använda respektive dokumentcentrerad (icke SQL) databas.

Andra NoSQL-system som är värda att nämna är Neo4j, Tokyo Cabinet, Memcache samt Cassandra.

Bakgrund MongoDB

Används av sajter såsom bit.ly och foursquare. Utvecklat i C++ och överbryggar RDBMS och nyckel-värde lagring.

Installation MongoDB

Installationen gick mycket smidigt på mitt Ubuntu 10.10 system med hjälp av apt:

$ sudo apt-get install mongodb-server

Då installeras MongoDB, xulrunner samt så läggs en användare vid namn mongodb upp. Mongodb lyssnar även på två TCP-portar på 127.0.0.1

För PHP-stöd till MongoDB så kan pecl-porten användas och installeras på följande sätt:

$ sudo pecl install mongo

Om du får ett felmeddelande i stil med:

sh: phpize: not found
ERROR: `phpize’ failed

Så måste Ubuntu-paketet php5-dev installeras där phpize ingår. För att sedan få php att ladda in mongo-modulen så kan följande kommando användas:

$ sudo sh -c ”echo extension=mongo.so > /etc/php5/conf.d/mongo.ini”

För att sedan använda MongDB så kan exempelvis följande PHP-kod användas för test:


<?php

// connect

$m = new Mongo();

// select a database

$db = $m->comedy;

$collection = $db->cartoons;

// add an element

$obj = array( "title" => "Calvin and Hobbes", "author" => "Bill Watterson" );

$collection->insert($obj);

// find everything in the collection

$cursor = $collection->find();

// iterate through the results

foreach ($cursor as $obj) {

echo $obj["title"] . "\n";

}

// disconnect

$m->close();

?>

För att sedan verifiera testa:

$ php mongodb.php

Så bör följande visas:
Calvin and Hobbes
Andra inlägg i denna serie kommer snart.

Att utveckla för molnet

Att utveckla webbtjänster för molnet gör att utvecklingen blir bättre. Jag upplever att jag tvingas att tänka på portabilitet och möjlighet till skalnCC http://commons.wikimedia.org/wiki/File:Bedeckt.gifing på ett annat sätt än när jag vanligtvis skapar webbtjänster.  Detta gör mig troligtvis också till en bättre programmerare.

Låt mig ta några exempel:

1. Istället för att använda Pythons inbyggda köhantering (Queue) så använder jag Redis och får då automatiskt skalning. Dock inte till vilket pris som helst eftersom Redis äter minne. Men med Amazon EC2 och 15GB minne så kommer jag rätt långt. Har testat Amazon SQS för köhantering men prestandan är direkt usel och är inte avsedd för miljoner operationer per sekund.

2. Sökvägar tvingas att sättas dynamiskt eftersom jag använder Amazon EBS där sökvägarna sätts på den extramonteringen som EBS tillhandahåller. Dock är det lite trist att vara låst till en ”zon” hos Amazon.

3. Att inte tänka på begränsningar på samma sätt. Det går alltid att kasta fler servrar, ramminne och hårddisk på problemet så löser det sig utan att behöva införskaffa fysisk hårddvara. Detta är något som jag ser som mycket intressant, att som liten ensam entreprenör kunna bygga stora system med hundratalet servrar. Dock ska ju allt underhållas också..

Finns säkert en drös med andra saker som jag inte kommer på just nu, men lämna gärna en kommentar på vad du ser för fördelar med att använda molntjänster vid utveckling.