Apache MaxClients mpm_prefork_module optimal einstellen

Der Apache-Webserver hat in seiner Config-Datei eine Möglichkeit, die maximale Benutzerzahl sowie die gleichzeitig laufenden Prozesse/Threads zu beschränken. Hintergrund dieser Serverlimitierung ist, dass der Server und nicht unter Last zusammenbricht, denn die Anzahl der möglichen Threads und gleichzeitige Userzugriffe hängen stark vom Speicher im Server und dessen CPU ab.

Wenn der Server schon bei wenigen Usern „streikt“, gibt ein Blick in das Apache error.log Auskunft. Ist darin ein Eintrag wie folgt ersichtlich, ist dies ein klarer Hinweis auf die Serverlimitierung innerhalb der apache2.conf-Datei:

[error] server reached MaxClients setting, consider raising the MaxClients setting

Es ist dann höchste Zeit, sich mit der Datei „/etc/apache/apache2.conf” (oder „/etc/apache2/apache2.conf”) auseinanderzusetzen. Wir finden im Abschnitt „mpm_prefork_module“ ähnliche Werte:

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
#war 1,1,5,10,0
<IfModule mpm_prefork_module>
StartServers       6
MinSpareServers    3
MaxSpareServers    3
MaxClients        100
    MaxRequestsPerChild   1000
</IfModule>

Was bedeuten die einzelnen Werte?

MaxClients: Dieser Parameter bestimmt die Anzahl der Apache Prozesse und somit die maximale Anzahl der Client Verbindungen, die vom Webserver zugelassen werden (Voraussetzung: prefork MPM). Wenn worker MPM verwendet wird, limitiert der Wert die Anzahl der Threads, die für die Clients zur Verfügung stehen.

MinSpareServers: Bei Verwendung von prefork MPM kann mit diesem Parameter definiert werden, wie viel unbeschäftigte (spare) Prozesse dem Apachen mindestens zur Verfügung stehen. Wenn eine neue Anfrage an den Webserver gestellt werden, nimmt der Apache einen dieser unbeschäftigten Prozesse. Dadurch wird die Anfrage schneller beantwortet, da dafür nicht ein neuer Prozess erstellt werden muss.

MaxSpareServers: Dieser Parameter legt fest, wie viel unbeschäftigte Prozesse maximal vorgehalten werden. Dieser Wert soll nicht zu hoch angesetzt werden, da jeder Prozess, auch wenn er „unbeschäftigt ist“, dann unnötig Arbeitsspeicher belegt.

ThreadsPerChild: Dieser  Parameter legt fest, wie viel Threads pro Prozess zugelassen werden sollen.
StartServers: Dieser Parameter legt fest, wie viel Prozesse beim Serverstart erstellt werden sollen.
MaxRequestsPerChild: Der Parameter MaxRequestsPerChild legt die maximale Anzahl von Anfragen fest, die ein Kindprozess während seiner Lebenszeit bearbeitet. Nachdem diese Grenze erreicht wurde, wird dieser Kindprozess terminiert. Ein MaxRequestsPerChild von 0 bedeutet, dass ein Kindprozess niemals endet.
Die Begrenzung von MaxRequestsPerChild (ungleich Null) hat folgende Vorteile:

  1. Sollte ein Prozess aufgrund eines Fehlers „Amok laufen“, begrenzt dieser Wert die Menge an Arbeitsspeicher, die der fehlerhafte Prozess belegen kann.
  2. Die Anzahl der Prozesse werden reduziert, wenn die Last des Servers nach einer hohen Auslastung wieder zurückgeht.

Apache-Default-Werte und empfohlene Werte
StartServers: 5
MinSpareServers: 5
MaxSpareServers: 10
MaxClients: 256
MaxRequestsPerChild: 0 oder 10000
MaxClients: Wenn dieser Wert größer als 256 gesetzt wird, muss zusätzlich der Parameter ServerLimit entsprechend erhöht werden.

Ein Plesk-Server (Parallels Virtuozzo-Server) bricht unter weniger User-Last ein
Interessant ist die Standard-Einstellung von virtualisierten Servern, beispielsweise von Webservern, die mit Parallels Plesk virtualisiert sind. Hier findet man folgende Werte:

StartServers       1
MinSpareServers    1
MaxSpareServers    5
MaxClients        10
MaxRequestsPerChild   0

Diese Einstellung bedeutet, dass der Server nur maximal 10 Clients zulässt. Dieser Werte können sich sehr schnell als „Flaschenhals“ erweisen und den Zugriff von Benutzern verhindern. Der Gedanke von Plesk ist klar: Auf dem Gesamtsystem sorgen diese Einstellungen dafür, dass die virtualisierten Server mit minimalen Zugriffen laufen und somit das Gesamtsystem nicht übermäßig belasten. Jedoch sind diese Werte, gerade bei aktueller Hardware, mehr als unpassend. Eine Erhöhung der Werte auf die Apache-Standard-Werte sollte ein erster Anhaltspunkt für die Performance-Optimierung sein. Nachdem man mit dieser Werten weitere Erfahrungen gesammelt hat, können diese Werte weiter optimiert werden.

Apache Restart nach Änderungen an der apache2.conf
Eine Änderung der Werte in der Apache-Config wirkt sich erst aus, nachdem der Apache Webserver neu gestartet wurde.

/etc/init.d/apache2 restart

SharePoint 2010: Website-Vorlage per SharePoint-Designer 2010 hinzufügen

Einer Website eine neue Site hinzufügen, ist in SharePoint keine große Sache. Klicken Sie hierfür auf „Websiteaktionen“, „Neue Seite“ und vergeben der neuen Seite einen Namen. Wenn Sie eine Seite mit einem bestimmten Aufbau und Webpartzonen anlegen möchten, empfehle ich dies aus der „Inhalts- und Strukturübersicht“ (Websiteeinstellungen,  Websiteinhalt und –struktur, Seiten) über „Seiten“, „Neu“ und „Seite anlegen“ zu erledigen. Hier können Sie auch das Seitenlayout anhand der von Microsoft bereits vorgegebenen Webseiten bestimmen.

Je nach Gestaltungsvorlage und Anforderung werden Sie jedoch mit diesen Vorlagen nicht auskommen. Wenn zum Beispiel eine Vorlage mit vier Spalten nebeneinander gewünscht wird, werden Sie diese Vorlage hier vergeblich suchen.

Weitere Vorlagen im SharePoint Designer 2010
Der Sharepoint-Designer 2010 bietet Ihnen neben weiteren Gestaltungsmöglichkeiten auch weitere Websitevorlagen mit Webpartzonen, die fast jeden Wunsch abdecken. Der SharePoint-Designer 2010 ist inzwischen kostenfrei über Microsoft zum Download erhältlich.
Laden Sie den SharePoint Designer herunter und installieren Sie ihn auf einem lokalen PC oder auf einem Member Ihrer SharePoint-Farm. Verbinden Sie sich auf Ihre Website mit dem Designer. Klicken Sie in der Navigation auf den Eintrag „Websiteseiten“. In der Ribbon-Leiste oben unter dem Karteikartenreiter „Seiten“ befindet sich der Ribbon „Webpartseite“. Klicken Sie das Ribbon an. Es öffnet sich eine Vorschau. Dort finden Sie weitere Websitevorlagen, unter anderem ein vierspaltiges Layout. Wählen Sie das gewünschte Layout aus und vergeben Sie der Seite einen Namen. Da die Vorlage uns nur als Vorlage dient, langt ein Titel wie „4-spalitig-layout.aspx“ oder ähnliches.

Wenn Sie nun in SharePoint (Browser) auf „Websiteaktionen“, „Inhalt und Struktur verwalten“ klicken, können Sie auf die Kategorie „Websiteseiten“ wechseln. Dort finden Sie nun die eben im SharePoint-Designer angelegte Seite.

Eine Seite kopieren oder verschieben in SharePoint
Die Vorlage, die wir eben erstellt haben, wurde unter „Websiteseiten“ abgelegt. Je nach Anforderung und Web möchten wir die Seite jedoch unter „Seiten“ abgelegt haben. Wir klicken auf die Kategorie „Websiteseiten“ und erhalten im Contentbereich unsere angelegte Seite. Wenn wir nun über den Titel der ASPX-Seite fahren, sehen wir rechts daneben einen Pfeil nach unten. Wir klicken darauf und ein Kontextmenü öffnet sich.

Mittels der Auswahl Kopieren können wir nun unsere Vorlage kopieren. Wir wechseln in die Kategorie „Seiten“, wählen mittels rechter Maustaste das Kontextmenü an, klicken auf „Einfügen“ und geben unserer eben kopierten Seite einen passenden Namen.

Nacharbeit einer Sharepoint-Seite
Natürlich haben wir unserer Vorlage eben weder Content, also Inhalt, noch irgendwelches Design oder Webparts verpasst. Dies hätten wir vor dem Kopieren im SharePoint-Designer erledigen können. In diesem Fall ging es nur um prinzipiellen Weg wie auch um die Möglichkeit, ohne WSP-Dateien und „Lösungen“ zu erstellen, eine einfache Seite mittels des SharePoint Designers zu erstellen und kopieren.

C# Images in DataGridView anzeigen

Der Wunsch, ein Image (Bild) in einem DataGridView in C# anzuzeigen, ist nicht vielfältig. Von kleinen Icons oder einer Statusanzeige, Thumbnails bis hin zur tabellarischen Anzeige von Bildern in einer Bildersammlung. Allen Anwendungsarten gemein ist, selten das gleiche Image in jeder Spalte angezeigt werden soll. Wer sich mit einem Image (und immer dem gleichen) in einer Spalte begnügt, kann das Image per Eigenschaft in Visual Studio hinzufügen, oder wie unten dynamisch anzeigen

//Ein Image einem DataGridView hinzufügen (jeder Zeile das gleiche Image)
Image myimage = new Bitmap("c:\mein_image.jpg");
DataGridViewImageColumn dgv_pic = new DataGridViewImageColumn(false);
dgv_pic.ImageLayout = DataGridViewImageCellLayout.Normal;
dgv_pic.Image = myimage;
dataGridView1.Columns.Add(dgv_pic);

Unterschiedliche Images aus einer Resource kann man wie im folgenden Beispiel anzeigen. Dieser Code hat den Nachteil, dass es nur Sinn macht, wenige verschiedene Images anzuzeigen. Hier wird eine Statuslampe (rot/grün) angezeigt:

//Lade die Images aus Resource
Image lampe_rot = Resource1.lampe_rot;
Image lampe_gruen = Resource1.lampe_gruen;

DataGridView dgv = new DataGridView();
DataGridViewImageColumn dgv_pic = new DataGridViewImageColumn(false);
DataGridViewColumn dgv_text = new DataGridViewTextBoxColumn();

//Füge die Colums hinzu
dgv.Columns.Add(dgv_pic);
dgv.Columns.Add(dgv_text);

//Hier warden manuell zwei Rows hinzugefügt
dgv.Rows.Add(2);

dgv[0, 0].Value = (Image)lampe_gruen;
dgv[0, 1].Value = (Image)lampe_rot;
dgv[1, 0].Value = "Server A";
dgv[1, 1].Value = "Server B";

Wenn ein DataGridView an eine Quelle gebunden ist (bindingSource), wird man einen anderen Weg einschlagen müssen. Dies gilt auch für den Fall, dass in jeder Zeile ein eigenes Bild angezeigt werden soll:

//dataGridView1 ist vorhanden und mit Daten gebunden
//Erstelle die Image-Spalte
DataGridViewImageColumn dgvic = new DataGridViewImageColumn(false);
dataGridView1.Columns.Add(dgvic);
               

//Gehe die Rows durch
for (int row = 0; row < dataGridView1.RowCount; row++)
{
//Lokales laden des Images
Image webImage = new Bitmap("c:\my_image.jpg");

//Image in DataGrid einfügen
      dataGridView1.Rows[row].Cells[0].Value = webImage;
//Höhe der Spalte an Image anpassen
      dataGridView1.Rows[row].Height = webImage.Height;
}

Wir gehen also jede Zeile durch und laden in diesem Beispiel jeder Zeile das Image „my_image.jpg“ hinzu. Wenn der Dateiname in der Zeile bekannt ist, kann dieser Aufruf natürlich (und sinnvollerweise) dynamisch erfolgen.

Image per http (webResponse) in DataGridView anzeigen
Oftmals haben wir in unserem dataGridView eine URL zur einem Image, das wir als Thumbnail (Vorschaubild) in unserer Tabelle anzeigen möchten. Dann können wir das Image nicht per Image webImage = new Bitmap() laden, sondern müssen es per WebRequest anfordern. Hierzu benötigen wir „using System.Net”.
Wir nutzen den gleichen Code wie im Beispiel oben, ersetzen jedoch „Image webImage“ („Lokales laden des Images“) mit folgendem Code:

//Laden des Images per http
//using System.Net;
string picUri = "http://domain.de/images/my_image.gif";
WebRequest requestPic = WebRequest.Create(picUri);
WebResponse responsePic = requestPic.GetResponse();

/Wandel den http-Stream zu Image
Image webImage = Image.FromStream(responsePic.GetResponseStream());

Zu beachten gilt, dass der Zugriff per WebRequest hinter einem Proxy (in Firmen sicherlich Standard) so nicht funktioniert. Der folgende Code zeigt einen Request über einen WebProxy:

WebRequest request = WebRequest.Create(sURL);
WebProxy proxy = new WebProxy(sWebProxy, Convert.ToInt32(sPort));
//            proxy.UseDefaultCredentials = true;
proxy.Credentials = new NetworkCredential(sUser, sPasswort, sDomain);
request.Proxy = proxy;
WebResponse response = request.GetResponse();

MySQL Replikation auf den Slave-Servern einrichten und starten

Im Artikel „MySQL Cluster oder Hot-Stand-By Lösung? Eine Frage der Hochverfügbarkeit“ haben wir die Vorbereitungen zu unserer MySQL-Replikation getroffen. Im Artikel „MySQL Replikation (Master/Slave) einrichten“ haben wir das der Replikation zugrundeliegende Logfile eingerichtet und ein Abbild der zu sichernden Datenbank erstellt. Dieses muss nun auf alle MySQL-Slave-Server kopiert werden. Wenn mehrere Slave-Server eingerichtet werden sollen, müssen die folgenden Schritte auf jedem Slave-Server durchgeführt werden.

Wir haben die Master-DB („mysql-snapshot.tar“) auf dem Slave-Server in den Ordner „/var/lib/mysql“ kopiert. Über eine Putty-Shell stoppen wir den MySQL-Server und entpacken die Master-Datenbank:

/etc/init.d/mysql stop
cd /var/lib/mysql
tar -xvf mysql-snapshot.tar

Die my.cnf auf dem Slave anpassen
Nun müssen wir die „my.cnf“ auf dem Slave anpassen. Wichtig ist auf jeden Fall, dem Slave eine eigene Server-ID zu geben. Jeder MySQL-Server in unserer Replikation benötigt eine eigene eindeutige ID. Wir öffnen die my.cnf mit einem Texteditor unserer Wahl:

nano /etc/mysql/my.cnf

server-id = 2
replicate-do-db = this_db [optional]

Das Logfile auf dem Master enthält alle Änderungen der Master-Datenbank. Wenn wir nur eine einzelne Datenbank replizieren möchten, können wir den Slave mittels „replicate-do-db“ anweisen, nur die Datenbank „this_db“ zu replizieren.
Ebenfalls optional ist die Angabe von Tabellen. Zu beachten gilt, wenn der Befehl „replicate-do-table“ einmal im Logfile verwendet wird, muss jede zu replizierende Tabelle aufgeführt werden (im untenstehenden Beispiel werden nur die drei benannten Tabellen repliziert).

#replicate-do-table beschränkt die Replikation auf einzelne Tabellen, falls nicht die gesamte Datenbank repliziert werden soll.
replicate-do-table = shopdb.customer
replicate-do-table = shopdb.order
replicate-do-table = shopdb.tracking

Den MySQL Slave wieder starten
/etc/init.d/mysql start

Dem MySQL-Slave mitteilen wer sein Master ist
Die Replikation geht von den einzelnen Slaves aus. Der Slave greift mit dem Replikationskonto (das wir im Artikel „MySQL Replikation (Master/Slave) einrichten“ angelegt haben) auf den Master zu.

Mittels MySQL-Konsole setzen wir folgenden Befehl ab:

CHANGE MASTER TO MASTER_HOST='<host>‘, MASTER_USER='<Replikations-User>‘, MASTER_PASSWORD='<passwd>‘, MASTER_LOG_FILE=’mysql-bin.<Hier die aktuelle Dateiangabe>, MASTER_LOG_POS=<Die Position vom Master>;

<host>: Name oder besser, die IP des Masters
<Replikations-User>: Name des Replikations-User auf dem Master (hier: „repl“)
<passwd>: Das Passwort des Replikations-User
MASTER_LOG_FILE: Beispielsweise „mysql-bin.000001“ (siehe notierte Angaben aus dem Start der Master-Replikation)
MASTER_LOG_POS: Beispielsweise „100“ (siehe notierte Angaben aus dem Start der Master-Replikation)

Wenn nach diesem Befehl keine Fehlermeldung erscheint, ist die Replikation schon fast perfekt.

Replikation anfahren
Mittels MySQL-Konsole starten wir Replikation:
START SLAVE;

Wenn alles ordnungsgemäß eingegeben wurde, führt der Slave ab sofort die Replikation durch. Mittels des MySQL-Konsolen-Befehls

show slave statusG

kann der Status der Replikation jederzeit abgerufen werden. Die Replikation stoppt bei einem Fehler.
Sobald ein Slave mit der Replikation begonnen hat, finden wir in seinem Datenverzeichnis unter „var/lib/mysql“ zwei Dateien namens master.info und relay-log.info. Der Slave verwendet diese beiden Dateien um zu vermerken, welcher Teil der Masterlogs bereits abgearbeitet wurde.

Über diese Schritte können so alle weiteren Slaves in die Replikation einbezogen werden. Nun benötigen wir noch das Wissen, wie wir mit Fehler der Replikation umgehen und wie wir diese überwachen. Über dieses Thema beschäftigen wir uns in einem weiteren Artikel.

MySQL Replikation (Master/Slave) einrichten

Im Artikel „MySQL Cluster oder Hot-Stand-By Lösung? Eine Frage der Hochverfügbarkeit“ haben wir die Vorüberlegung getroffen, wie wir unser System aufbauen möchten. Da wir einen Master-MySQL-Server und mehrere Slave-MySQL-Server haben und die Daten nicht jederzeit zu 100 Prozent synchron sein müssen, können wir die MySQL Replikation (Log-Shipping) nutzen. Ein weiterer Nachteil dieser Lösung ist, dass keine Daten auf dem Slave-Server verändert werden sollten/dürften, da sonst die Datenbestände auseinanderlaufen. Da in unserem Fall hauptsächlich Abfragen getätigt werden und SQL-Inserts nur zur Besucherstatistik dienen, kann das Zusammenführen dieser statistischen Daten über einen Cron-Job nachts erfolgen. Dieser sendet die Tagesdaten an den Master-Server, der diese Daten zentral aufbereitet. Die Replikation dieser Daten ist nicht gewünscht.

Weitere vorbereitende Überlegungen
Damit die MySQL-Replikation auch ordnungsgemäß funktioniert, sollten die MySQL-Versionen zwischen Master und Slave übereinstimmen. Kleine Versionsunterschiede können kein Problem sein, können aber auch zu zeitraubenden Fallen werden. In meinem Testsystem nutze ich unterschiedliche Versionen; es klappt einwandfrei. Allerdings muss dies nicht für alle Versionsdifferenzen gelten. Um die installierte MySQL-Version der einzelnen Server zu prüfen, können wir folgenden Befehl (Putty-Konsole) nutzen:

Prüfe die MySQL-Version
Putty: mysql -h localhost -V

Mit Netz und doppelten Boden
Wenn irgendwie möglich, sollte vor Start von jedem Member (Master und Slave) Images gemacht werden. Bei den folgenden Schritten kann die MySQL-Datenbank fehlerhaft werden, was bei softwaregestützten Webservern (Plesk, Confixx) zu einem Ausfall führen kann!

Einrichtung der MySQL-Replikation auf dem Master-Server
Als erstes müssen wir auf den MySQL-Master-Server einen Replikations-Benutzer anlegen. Weitere Informationen zu diesem Thema hält die MySQL-Seite vor. Wir öffnen eine Putty-Sitzung mit dem Master-Server und loggen uns in die MySQL-Konsole ein:

MASTER:
mysql -u root -p [RETURN]

MySQL-Replikations-Benutzer anlegen
Nehmen wir nun an, dass unsere Domäne mydomain.com heißt und wir ein Konto mit dem Benutzernamen „repl“ erstellen wollen. Dieses Konto nutzen die Slave-Server unter Angabe des Passworts „slavepass“ und stellen so die Verbindung Slave-Master her. Hier sehen wir also, dass der Zugriff (lesend) vom Slave oder den Slaves zum Master funktioniert.
Das Replikations-Konto erstellen wir mit folgender GRANT-Anweisung (Hinweis: Wir benötigen an dieser Stelle Root-Rechte):

mysql> GRANT REPLICATION SLAVE ON *.*
-> TO ‚repl’@’%.mydomain.com‘ IDENTIFIED BY ’slavepass‘;

My.conf auf dem Master anpassen
Nun öffnen wir mit einem Texteditor unserer Wahl die „etc/mysql/my.cnf“ und setzen die untenstehenden Werte (je nach Installation sind diese Werte vorhanden; wir entfernen lediglich die Auskommentierung „#“)

server-id = 1
log_bin = /var/log/mysql/mysql-bin.log

Was bewirkt diese Änderung: Wir teilen MySQL mit, dass dies der Server 1 ist. Alle an der Replikation beteiligen Server benötigen eine eigene (unterschiedliche ID). Per Eintrag „log_bin“ weisen wir MySQL an, dass alle Datenbankänderungen ab sofort geloggt werden sollen (an der Stelle: /var/log/mysql/mysql-bin.log)

Den MySQL-Server restarten
Damit die Änderungen aus der my.conf auch greifen, muss der MySQL-Dienst neu gestartet warden:

/etc/init.d/mysql restart

Nun müssen wir den aktuellen Stand der Datenbank sichern. Dieser Datenstand wird auf die Slaves verteilt. Alle folgenden Transaktionen auf den Slaves erfolgen dann über das Log-Shipping.

Vorbereitung für das Abbild der Master Datenbank erstellen
Über die MySQL-Konsole sperren wir alle Schreibzugriffe auf die Datenbank:

FLUSH TABLES WITH READ LOCK;

Position vom Master-Logfile notieren
Der folgende Schritt ist sehr wichtig. Wir notieren uns die aktuelle Position vom Master-Logfile. Diese Daten benötigen wir später beim Start der Slave-Synchronisation (Abschreiben oder Hardcopy)

SHOW MASTER STATUS;

Abbild vom aktuellen Stand der Master Datenbank erstellen
Wir öffnen via Putty eine weitere Sitzung. Die Putty-Sitzung mit dem „LOCK“ lassen wir bestehen und schließen sie nicht! Mit dem folgenden Code gehen wir in das MySQL-Verzeichnis und sichern die Datenbank:

cd /var/lib/mysql
tar -cvf /root/mysql-snapshot.tar

ACHTUNG: Zu beachten gilt hier, dass wir so ALLE Datenbanken des MySQL-Servers sichern (und später auch wiederherstellen). Je nach Server-Verwaltungssoftware (zum Beispiel Plesk) sind diese Daten auch in der MySQL-Datenbank gespeichert. Wenn wir diese Daten auf dem Slave-Server einspielen, überschreiben wir die MySQL-Plesk-Daten (oder andere MySQL-Einträge) auf dem Slave-Server. Ich gebe an dieser Stelle einmal zu, dass ich so schon einmal einen Plesk-Webserver „zerschossen“ habe).

Wollen wir also nur eine Datenbank replizieren („this_db“), nutzen wir folgenden Befehl:
shell> tar -cvf /root/mysql-snapshot.tar ./this_db

Die Datenbank auf dem Master wieder freigeben
Über unsere bestehende MySQL-Konsole setzen wir folgenden Befehl ab:

UNLOCK TABLES;

Nun haben wir also den Master-Server für die MySQL-Logfile-Replikation vorbereitet und ein Abbild der Master-Datenbank erstellt. Im Artikel „MySQL Replikation auf den Slave-Servern einrichten und starten“ beschäftigen wir uns mit den Slave-Servern.

MySQL Cluster oder Hot-Stand-By Lösung? Eine Frage der Hochverfügbarkeit

Gerade bei größeren Projekten ist die Frage nach einer Datenbank-Hochverfügbarkeit eine elementare Frage. Wenn bei einem Webshop der Datenbankserver wegbricht, entgeht dem Händler Umsatz. Vom Imageschaden ganz zu schweigen. Aus diesem Grund wird kaum ein größeres Webprojekt ohne einen Hot- oder Cold-Stand-By Datenbankserver auskommen.

Warum langt eine Datenbanksicherung nicht?
Im Artikel „MySQL Datenbank oder einzelne Tabelle kopieren“ habe ich eine Datenbanksicherung mit MySQL-Boardmitteln beschrieben. Prinzipiell ist dies schon mal ein guter Ansatz. Die Datenbank als Sicherung räumlich getrennt auf einem externen Datenträger aufzubewahren, kann im Bedarfsfall viel Arbeit ersparen. Löst aber unser Problem nicht. Wenn ein Datenbankserver ausfällt, muss sofort ein anderer Server die Arbeit übernehmen, so dass man keine Offline-Zeit hat und ich Ruhe sich um den ausgefallenen Server kümmern kann.

Was ist ein Cluster-System?
Cluster oder Clustering bezieht sich auf den Gedanken, die Verfügbarkeit von Systemen und Anwendungen über standardisierte und preiswerte Hardware zu erhöhen. Heißt also nichts anderes, als dass mehrere Standard-Rechner einen Verbund bilden, aber nach außen als ein Rechner oder Datenbank sich zu erkennen geben. Steigt die Last, teilt sich diese auf die einzelnen Maschinen (Cluster-Member oder Knoten genannt) auf. Fällt ein Cluster-Member aus, steigt die Last der verbleibenden Member, aber das System (Datenbank) bleibt nach außen verfügbar.

Was ist Hot-Stand-By, was ist Cold-Stand-By und was ist der Unterschied?
Ein Cluster ist der Königsweg, keine Frage. Je nach Projekt und Verfügbarkeit kann man sich auch mit einer Hot- oder Cold-Stand-By-Lösung behelfen. Beide Lösungen setzen auf einen zweiten Server auf. Während bei einer Hot-Stand-By-Lösung der zweite Server ständig in Betrieb ist und die Daten mit dem Master-Server ständig repliziert (also die Daten in Realzeit aktuell hält), ist der zweite Server bei einer Cold-Stand-By-Lösung aus. Erst im Bedarfsfall wird der zweite Server eingeschaltet und auf den aktuellen Stand gebracht (einige Lösungen gleichen sich zu definierten Zeitpunkten automatisiert ab). Beiden Lösungen gemein ist, dass die eigentliche Arbeit der Master-Server macht, der Slave-Server nur bei Ausfall des Masters ins Spiel kommt.

MySQL-Replikation, Überlegungen zur Hochverfügbarkeit
In diesem Artikel möchten wir folgenden Fall beschreiben: Wir haben eine Master-MySQL-Datenbank sowie mehrere Slave-Datenbanken. Die Aufbereitung der Daten auf dem Master-Server ist so aufwändig und CPU-hungrig, dass zu mehreren Zeitpunkten untertags ein Webzugriff auf die Datenbank nicht oder nur schwer möglich ist. Aus diesem Grund soll die fertige Datenbank auf einen Slave-Datenbank-Server gespiegelt werden; der Zugriff der Webfrontend-Server soll nur auf die gespiegelten Slave-Server erfolgen. Somit kann bei der Datenbankaufbereitung der Master-Server seine volle Leistung nutzen und kein Webzugriff stört ihn. Nachteil dieser Lösung: Die Daten der Slave-Server hinken in der Aktualität dem Master-Server hinterher, was aber in unserer Lösung akzeptiert werden kann.
Ferner muss sichergestellt werden, dass die Berechnungen durch die Replikation nicht noch von den Slave-Servern durchgeführt wird. Diese sollen nur das fertige Ergebnis replizieren. Dies kann durch die Einschränkungen der Replikation aus Datenbanken und Tabellen sichergestellt werden.
Wir replizieren also die Datenbank auf mehrere Slave-Server. Jeder Slave-Server ist zugleich ein Webfrontend-Server. Per Network-Load-Balancing (NLB) werden die Web-Besucher auf die einzelnen Webfrontend-Server, also auf unsere MySQL-Slave-Server, verwiesen.

Im nächsten Teil („MySQL Replikation (Master/Slave) einrichten“ #######) beschäftigen wir uns nach soviel Vorüberlegung mit der eigentlichen Einrichtung der MySQL-Replikation.

Firefox Lesezeichen (Bookmarks) und seine History

Seit der Version 3 des Firefox-Browsers werden die internen Daten wie Lesezeichen, History (Chronik) sowie viele weitere Daten in einer internen Datenbank zusammengefasst. Diese SQL-Datenbank finden wir unter dem Namen „places.sqlite“ im Dateisystem. Je nach Installation im Userverzeichnis oder bei der portablen Firefox-Installation beispielsweise im Installationsverzeichnis „Dataprofile“. Im Zweifelsfall einfach die Windows-interne Suche benutzen.

Firefox Lesezeichen nach Windows Neuinstallation wiederherstellen
Da die meisten Einstellungen des Browsers in dieser Datei gespeichert sind, kann man diese Datei durchaus auf einen anderen Rechner kopieren. So ist es beispielsweise möglich, von einem alten Rechner diese Datei zu sichern und nach einer Neuinstallation von Windows samt Firefox die bisherigen Lesezeichen und die History wiederhezustellen. Wichtig dabei ist, dass für diese Aktion der Firefox geschlossen ist.

Lesezeichen mitnnehmen (migrieren)
So sind mir auch schon Kunden untergekommen, die diese Datei auf einem USB-Stick von Rechner zu Rechner mitnehmen, um ihre History und ihre Lesezeichen jedezeit parat zu haben. Dies mag Geschmackssache sein. Denn genau für diese Vorgehensweise wurde die portable Version von Firefox geschaffen.

Die Datei places.sqlite verkleinern
Wie jede Datenbank wächst auch die places.sqlite stetig. Bookmarks, History und Favicons blähen die Datei auf. Natürlich kann man über Firefox-Boardmittel versuchen, unnötigen Ballast zu entfernen. Jedoch wird die Datei nicht so klein, wie sich mancher Nutzer wünscht.
Wenn man die „places.sqlite“-Datei bei geschlossenem Firefox löscht (ich empfehle eher umbenennen!), erstellt der Firefox beim Start die Datei anhand der letzten json-Sicherungsdatei die places.sqlite neu. Ein alternativer Weg ist die Wiederherstellung einer json-Sicherungsdatei mit Bordmitteln des Firefox-Browsers. So kann die aktuelle History gesichert und wiedereingespielt werden. Nach diesem Vorgang ist die neue places.sqlite deutlich verkleinert.
Warum ist das so? Die wiederhergestellte Datei beinhaltet beispielsweise keine Favicons mehr. Diese Grafikdaten sind auch nicht wirklich nötig. Der Browser läd sie bei Bedarf von der besuchten Webseite neu herunter.

Sichern oder Wiederherstellen der places.sqlite
Über „Lesezeichen/Alle Lesezeichen anzeigen“ öffnet sich die Bibliothek des Firefox-Browsers. Mittels des Button „Importieren und Sichern“ kann ein Kontextmenü geöffnet werden.. Über die Auswahl „Wiederherstellen“ kann auf eine bestehende json-Sicherung zugegriffen werden. Die Auswahl „Datei wählen“ erlaubt das Einspielen einer externen Sicherung.

Zugriff auf die sqlite-Datenbank
Um sich die systemeigene Datenbank ein wenig näher anzuschauen, gibt es für den Firefox ein Add-On (SQLite Manager). Dieses Tool erlaubt vollen Zugriff auf die Datenbank und ist daher mit Vorsicht zu bedienen. Wer nicht weiss, was er macht, sollte auf jeden Fall vorher eine Sicherung seiner places.sqlite anfertigen. Prinzipiell gilt: Das Add-On SQLite Manager ist ein Systemwerkzeug und sollte nicht unbedarft eingesetzt werden!

Verkeinern der places.sqlite mittels vacuum
Auch die Datenbank selbst kann – wie nahezu jede andere Datenbank selbst – mittels SQL-Boardmitteln verkleinert werden. Der Befehl dazu heisst „Vacuum“. Letztlich entfernt Vacuum die Fragmentierung der Datenbank und befreit sie von unnötigem Ballast.
Um den Befehl absetzen zu können, benötigen wir den SQLite Manager als Add-On im Firefox. Nach Aufruf des Managers wird die places.sqlite geöffnet. Unter dem Register Execute SQL kann nun der Befehl vacuum eingegeben und mit Run SQL zur Ausführung gebracht werden. Der Erfolg der Verkleinerung wird im Feld Last Error angezeigt.

Windows Home Server Restore: Windows Home Server not found – Wiederherstellung schlägt fehl

Für kleinere private Netzwerke ist der Windows Home Server (WHS) eine feine Sache. Ein zentraler Datenspeicher und die Möglichkeit, alle Client-PCs automatisch zu sichern. Durch diese Automation kann man im Bedarfsfall einzelne Laufwerke mit dem Datenstand eines bestimmten Sichtages hinzufügen, so dass einzelne Dateien vergleichen und ggfls. ersetzt/wiederhergestellt werden können. Eine tolle Sache. Aber auch wenn der Recher komplett seinen Geist aufgibt, kann man ihn mittels der „Windows Home Server Restore CD“ auf jedes verfügbare Image neu aufsetzen. Letzteres geht schnell von der Hand. Es gibt jedoch zwei entscheidende Dinge VORAB zu prüfen und zu testen: Für das Zurückspielen eines Images vom Windows Home Server ist einerseits die CD „Windows Home Server Restore CD“ Voraussetzung. Das Image hält der WHS vor, sie kann jederzeit im Bedarfsfall auch nachträglich gebrannt werden. Doch hat der wiederherzustellende PC überhaupt ein CD-Laufwerk? Wenn nein, kann das Image über diverse Tools auf einen USB-Stick kopiert und der Rechner von diesem gebootet werden. Dies klappt sehr gut, sollte jedoch vorher schon erstellt und getestet werden, denn im Bedarfsfall hat man wenig Zeit und Nerven, sich mit möglichen „Problemen“ herumzuschlagen. Vor allem das folgende problem: Der Netzwerkkartentreiber.

Fehlermeldung: „Windows Home Server Not Found. Search again?”
Im Normalfall ist das Zurückspielen eines im Netz befindlichen Client-PCs mittels der WHS Restore CD kein Problem. Wenn jedoch die CD keinen passenden Netzwerkkartentreiber für das Mainboard finden kann, schlägt die Verbindung mit der Fehlermeldung „Windows Home Server Not Found. Search again?” fehl. Der Restore-Vorgang erlaubt das Einbinden von Treibern, ist jedoch nicht sehr „innovativ“.

Einbinden von alternativen Treibern im WHS-Restore-Vorgang
Wenn die Restore-CD gebootet und die Sprache ausgewählt wurde, kommt nach geraumer Zeit das Fenster „Detect Hardware“. Es zeigt die Meldung „The following network and storage devices have been found on this computer“. Unter anderem werden unter (1) die “Network devices” aufgelistet. Wenn dieser Treiber nicht passt, kann durch drücken des Buttons “Show Details” ein weiteres Fenster geöffnet werden. Hier den Button „Install Driver“ klicken. Es erscheint die Meldung „Insert a USB flasch drive or a floppy disc…“. Der Treiber (ungepackt und kein EXE-File!) muss also über ein USB-Stick oder einer Diskette zugespielt werden. Mit dem Button „Scan“ (dauert ein wenig) liest das Restore-Programm die Treiber ein. Es sollte die Meldung „Drivers were found for your hardware“ erscheinen. Mit dem Button „Continue“ geht der Vorgang weiter und der WHS sollte gefunden werden.

„Please wait while your Home Server is located, Finding your Windows Home Server“
Es sollte also schon vorab jeder Client daraufhin geprüft werden, ob der Restore-Vorgang koeekt verläuft bzw. ob die Software mittels Standard-Netzwerkkartentreiber den WHS findet. Wenn nicht, muss dieser in ungepackter Version auf ein Medium (USB-Stick) gesichert werden, so dass es im Bedarfsfall keine Probleme gibt.

Speichern des Netzwerkkartentreibers eines bestehenden Windows-PCs
Normalerweise liegt eine Treiber-CD jedem Mainboard oder neuem PC bei. Nach Jahren ist diese verschwunden oder je nach Qualität des PCs sind die Treiber nicht auf CD, sondern auf einem Festplattenlaufwerk verfügbar. Wenn aber die Festplatte defekt ist, dürfte dieser Lagerort eine sehr schlechte Idee gewesen sein. Es empfiehlt sich daher, die passenden Treiber auf einem USB-Stick zu sammeln. Wenn der Treiber nicht mehr verfügbar ist, dann das Freeware-Tool „Double Driver“ weiterhelfen. Dieses kleine Tool kann alle Treiber einer bestehenden Windows-Installation sichern. Dies muss jedoch vorab geschehen.

Laufwerksbuchstabe einer Systempartition ändern

Wer Windows neu auf einer bereits bestehenden HDD mit Windows installiert, stand sicherlich schon vor dem Problem, dass der Systempartition plötzlich nicht den gewünschten Laufwerksbuchstabe zugeordnet ist. Aber auch bei Partitionsverschiebungen können so ungewünschte Effekte auftreten.

Prinzipiell ist es recht einfach, unter Windows einer Partition oder einem Laufwerk einen anderen Laufwerksbuchstaben zuzuordnen. Über „Start/ Systemsteuerung“  kann man den Eintrag „Verwaltung“ wählen. Über den Eintrag „Verwaltung“ kommt man zur „Computerverwaltung“. Dort wählt man den Eintrag „Datenträgerverwaltung“. Wenn das Fenster geöffnet ist, erhält man eine Übersicht über alle physikalischen Laufwerke und deren Partitionierung.

Mittels eines Rechtsklick auf ein Laufwerk öffnet sich ein Kontextmenü. In diesem wählt man „Laufwerksbuchstabe und –pfad ändern“ aus. Nun kann man dem Laufwerk einen neuen (freien) Laufwerksbuchstaben zuordnen. Zu beachten ist, dass ein Laufwerksbuchstabe, der durch eine Änderung freigeworden ist, erst nach einem Systemneustart wieder zur Verfügung steht.
Soweit bereitet Windows keine Probleme. Jedoch können auf dieser Weise keine Laufwerke geändert werden, die als „Systempartition“ gekennzeichnet sind. Wie wir auf dieser Hardcopy sehen können, existiert eine D-Platte als Systempartition, die jedoch nach einer erneuten Windows-Installation von D auf E „gewandert“ ist. Die hier vorhandene „F“-Partition lässt sich beliebig verschieben.
Es ist auch der Fall denkbar, dass nach dem Hinzufügen einer weiteren Festpatte in einen Rechner die Systempartition C einem X-beliebigen Laufwerksbuchstaben zugeordnet wird. Da alle Pfade auf C zeigen, dürfte man mit dieser Konstellation nicht glücklich werden.
Der folgende Weg zur Änderung des Laufwerksbuchstaben einer Systempartition führt über die Registry. Auch hier gilt, dass der Laufwerkbuchstaben frei sein muss; er darf also von keinem Laufwerk belegt sein. Ich weise an dieser Stelle ausdrücklich darauf hin, dass Änderungen in der Registry auf eigene Gefahr erfolgen!

Öffnen Sie die Registry mittels „Start/Ausführen/regedit“ und navigieren Sie zu dem Eintrag „HKEY_LOCAL_MACHINESYSTEMMounted Devices“. Werfen Sie zuerst einen Blick auf den Eintrag „DosDeviceIhr-zukünftiger-Laufwerksbuchstabe“. Ist er frei? Wenn er hier belegt ist, aber das Laufwerk phsikalisch nicht existiert (auch nicht im Explorer ersichtlich ist), kann dieser Eintrag in der Registry gelöscht werden. Achtung: Auch hier gilt – Löschen auf eigene Gefahr!
Wenn der zukünftige Laufwerksbuchstabe frei ist, kann der bisherige Eintrag („DosDeviceAlter-Laufwerksbuchstabe“) mittels rechter Maustaste/Umbenennen  oder F2 – Taste (der Eintrag kann dannn geändert werden) umbenannt werden. Nach einem Neustart sollte das Laufwerk nun den gewünschten Laufwerksbuchstaben zugeordnet haben.
Überprüfen Sie die Änderungen in der Computerverwaltung. Je nach Konstellation müssen Sie Zwischenschritte einlegen, bis Sie den Datenträger dem gewünschten Laufwerksbuchstaben zuordnen können.

Achten Sie bei den Änderungen darauf, dass keine Programme, vor allem keine Systemprogramme, auf Laufwerksbuchstaben zugreifen, die nach Ihrer Änderung nicht mehr vorhanden sind! Wenn dies der Fall ist, kann Ihr Windows eventuell nicht mehr starten! Prüfen Sie vor dem Neustart ggfls. mittels Durchsuchen der Registry, ob es Pfade gibt die auf den alten Laufwerksbuchstaben (beispielsweise „E:programm …“) verweisen. Ändern Sie diese Einträge vor Neustart auf den neue zugewiesenen Laufwerksbuchstaben.

Webalizer oder AWStats für Plesk aktivieren

Hinweis: Plesk 11.x-Update siehe unten!

Wer sich nicht durch gigabytegroße Logfiles wühlen möchte, sondern hübsch aufbereitete Log-Übersichtsseiten wünscht, ist mit den Logfiles-Aufbereitungs-Tools AWStats oder Webalizer bestens bedient. Beide Programme sind Freeware und schnell auf einem Webserver installiert. Beide Statistik-Tools liefern schnell einen Überblick über die Besucher, die eine Webseite oder ein Server vorweisen kann.

Unter der Server-Verwaltungssoftware Plesk findet man sehr schnell einen Schalter, der scheinbar die Statistiken aktiviert. Unter „Domain/Hosting/Setup“ kann man Webalizer oder AWStats einer Domain zuordnen. Plesk selbst hat beide Statistik-Tools bereits in seiner Installation integriert. Man muss sich nur noch entscheiden, welches Tool einem eher zusagt. Ich persönlich bin nach jahrelangem Nutzen von Webalizer nun zu AWStats gewechselt. Aber dies ist reine Geschmackssache.
Die Verwaltungsoberfläche von Plesk zeigt einem nach der Auswahl an, dass Plesk ein geschütztes Verzeichnis unter „domain/plesk-stat/“ anlegt, in dem die Statitikdaten über den Browser abrufbar sind. Per Standard wird dem Verzeichnis der Benutzername und das Passwort des FTP-Zuganges der Domain zugewiesen. Wer die Benutzerdaten des Verzeichnisses „plesk-stat“ ändern möchte, kann dies über den Punkt „Geschützte Verzeichnisse“ jederzeit ändern.

Nun wird es spannend und führt zur ersten Enttäuschung. Ein Aufruf der URL „domain/plesk-stat/“ per Browser führt zu folgendem Hinweis:

This is the placeholder for Webalizer statistics. If you see this page that means that … This page has been automatically generated by Server Administrator.

Was genau will uns Plesk damit sagen? Nun, beide Statistik-Tools benötigen beim ersten Start – und vor allem, wenn schon große Logfiles vorliegen – eine Menge CPU und Zeit, um die notwendigen Daten aufzubereiten und die Webseiten zu generieren. Und Plesk selbst legt zwar ein passwortgeschütztes Verzeichnis an, gibt aber keine Möglichkeit, den notwendigen Cron-Job zu definieren. Dies muss vom Server-Administrator manuell nachgeholt werden. Der erste Start ist schnell erledigt. Man verbindet sich via Putty auf die Unix-Konsole und loggt sich möglichst als „root“ ein. Dann setzt man folgenden Befehl ab:

/usr/local/psa/admin/sbin/statistics

Je nach Menge und Größe des dauert jetzt der Aufruf, denn nun legt Webalizer oder AWStats los und bereitet die Apache Logfiles erstmalig auf. Ich empfehle diesen Schritt auf jeden Fall zu einem Zeitpunkt, bei dem entweder noch kaum Logfiles vorhanden sind, oder die Serverlast niedrig ist (beispielsweise nachts).
Es ist unerheblich, welches Statistik-Tool man ausgewählt hat oder ob vielleicht auf einem Server unterschiedlichen Domains unterschiedliche Tools zugewiesen wurden. Der oben genannte Befehl sorgt für die Statistiken beider Statistik-Tools.

Wenn man nun via Browser die URL „domain/plesk-stat“ aufruft, erhält man seine gewünschten Statistiken. Für die weitere und regelmäßige Auswertung der Logfiles muss man den Aufruf per Cronjob einrichten. Ich empfehle diesen Aufruf per Root und in den Nachtstunden (3-6 Uhr nachts ist gewöhnlich die Serverlast anhand realer Besucher gering) täglich vorzunehmen. Die Einrichtung eines Cronjobs erfolgt in Plesk unter „Start/Scheduled Tasks (Geplante Aufgaben)“. Dort wählt man das Konto („root“) aus, klickt auf NEXT und definiert den Cronjob.

Die Einstellung AWStat oder Webalizer ist in Plesk 11.x sehr gut versteckt
In Plesk 11.x findet man die Einstellung der Statistik-Programme AWStat oder Webalizer für eine Domain wie im Bild ersichtlich.

UPDATE: 11.2012: Hinweise für Plesk 11.x Statistik
Auswählen von AWStat oder Webalizer

Zuerst etwas erfreuliches: In Plesk 11.x muss der Cron nicht mehr selbst angelegt werden. Die Statistiken werden selbstständig erstellt. Allerdings kommt Plesk 11 immer noch mit jeweils völlig veralteten Versionen von Webalizer und AWStat daher. Aus dem Plesk-Forum ist zu entnehmen, dass sich schon mehr Personen die Zähne daran ausgebissen haben, die Statistikprogramme upzudaten. Ein Moderator schreibt, dass Webalizer bzw. AWStat so tief in Plesk „verankert“ sind, dass ein Update durch den Nutzer nicht machbar ist. Unbefriedigend.
Und nochwas ist unbefriedigend: Die Einstellung, ob man für eine Domain/Web AWStat oder Webalizer nutzen möchte, ist sehr gut versteckt. Ich selbst habe lange, SEHR lange danach gesucht. Die Einstellung ist unter „Abonnements/Websites&Domains“ und dann unten unter „Domain“->Domainnamen erreichbar.