# schneller logger



## despairedNoob (9. Mrz 2006)

hi community,

ich soll als aufgabe einen logger schreiben, in java, der events mit nachrichten, welche platzhalter beinhalten können, und objekte, die für die platzhalter einzusetzen wären, die aber separat gespeichert werden sollen.

ich hab mir überlegt, dass ich die events in eine table, die messages in eine, und die objekte in eine weitere table speichere.

meine *LOG_EVENT*-table hat folgende spalten... _EventID, ErrType, FK_MsgID, Date_
meine *LOG_MESSAGE*-table hat... _MsgID, Message_
meine *LOG_OBJECTS*-table hat... _ID, FK_MsgID, Type, Value_

und die ankommenden daten müssen eben sehr schnell gespeichert werden. es kommen ca 10000-100000 events per second an, welche gespeichert werden wollen.

bis jetzt hab ich das ganze asynchron bewältigt, doch das ergebnis ist mir noch nicht ausreichend...
zur zeit werden ca 20 - 30 events (logs) pro sek in die datenbank geschrieben...

kann mir jmd einen guten tipp geben, wie ich das schneller machen könnte?

danke im voraus...

MfG dNoob[/b][/quote]


----------



## AlArenal (9. Mrz 2006)

Um Himmels willen! Was in aller Welt erzeugt 100.000 Events die Sekunde?


----------



## despairedNoob (9. Mrz 2006)

k.A. aber ich soll so nen logger coden.


----------



## despairedNoob (9. Mrz 2006)

noch was...

ich hab mir für jede table ein PreparedStatement prepariert.
das bringt ja schon ein paar performance-punkte, doch das reicht allein noch net aus.

dann hab ich noch eingestellt, dass aller 100 events die PreparedStatements executiert werden.

desweiteren hab ich realisiert, dass die inserts in die Message und Event durch einen Thread, und die inserts für die Objects durch einen anderen Thread ausgeführt werden, da es mehrere Objects, abhängig von der anzahl der platzhalter in der der message, gibt... aber nur eine message und ein event.

also ein event gehört zu genau einer message
und eine message beinhaltet 0..* platzhalter
und ein platzhalter gehört zu genau einem objekt

...das wollt ich noch anfügen

MfG dNoob


----------



## despairedNoob (9. Mrz 2006)

die Typen für die einzelnen table-columns sind:

LOG_EVENT => EventID ( BIGINT ), ErrType ( INTEGER ), FK_MsgID ( BIGINT ), Date ( BIGINT )
LOG_MESSAGE => MsgID ( BIGINT ), Message ( VARCHAR 32000 zeichen )
LOG_OBJECTS => ID ( BIGINT ), FK_MsgID ( BIGINT ), Type ( INTEGER ), Value ( VARCHAR 50 zeichen )

...just 4 info


MfG dNoob


----------



## Ontos (11. Mrz 2006)

Moin Moin
Erhöhen doch die Anzahl der Events die lokal gespeichert werden. Dann lohnen sich die Preparead Statements auch mehr. Was spricht dageben nur alle 10 Sekunden (oder eventuell  sogar noch länger warten) ein Statement abzuschicken? Must du Speichergrößen der VM einhalten?

Ich würde einen Thread (oder eventuell sogar mehrere) zum einlesen in eine Collection benutzen und einer Überwachungsthread der den Füllstand betrachtet und den Speichervorgang aktivert.

Studium/Ausbildung oder Job?

cu Jens


----------



## despairedNoob (13. Mrz 2006)

hi jens,

deine rangehensweise hab ich auch schon implementiert... doch das ergebnis war mir nicht schnell genug...  :roll:

ich hab jetzt das so gelöst, dass erstmal alle events in eine text-datei gespeichert werden, und dann zum schluss wird die datei durchforstet und in die db geschrieben.

ich befinde mich zur zeit im studium.

MfG dNoob aka mika


----------



## mikachu (13. Mrz 2006)

ich lasse immer so 1000 bis 10000 statements auf einmal abschießen...

doch das dauert auch ganz schön lange :roll:

gibt es irgendwie eine formel um die größte menge an batches in der kürzesten zeit auszuführen?
(eine gleichung mit zwei unbekannten :!

wenn ja, wie lautet diese; wenn nein, da muss ich weitertesten :lol:

MfG mika


----------



## despairedNoob (14. Mrz 2006)

hab ne lösung gefunden, hat sich erledigt


----------



## norman (14. Mrz 2006)

despairedNoob hat gesagt.:
			
		

> hab ne lösung gefunden, hat sich erledigt


welche?


----------



## DP (14. Mrz 2006)

mika hat gesagt.:
			
		

> ich lasse immer so 1000 bis 10000 statements auf einmal abschießen...
> 
> doch das dauert auch ganz schön lange :roll:
> 
> ...



was heisst denn lange?

wenn der index immer mitgepflegt wird, dauert es je nach indexanzahl länger... imho kannste als "referenz" die bulk-importfunktion des entspr. rdbms nehmen.


----------



## mikachu (15. Mrz 2006)

naja, was heißt lange... hm...

ich hab jez 2x2 möglichkeiten, die ich grad teste...

die erste ist, dass ich die logs in eine ConcurrentLinkedQueue zwischenspeicher, und gleichzeitig verarbeite.
die zweite ist, dass ich wie erstens das gleiche tue, aber die typen der einzelnen log-teile separat abspeichere.
die dritte ist, dass ich wie die erste vorgehe, aber erst alles in eine text-datei speicher, um den hauptspeicher nicht so zu belasten, und anschließend, wenn keine logs mehr kommen, die textdatei durchforste und in die datenbank speichere.
die vierte, und letzte möglichkeit ist, dass ich eine kombination der dritten und zweiten mache... also in textdatei, und typen in separate tabellen speichere.

das ist grad noch im test-stadium, um die beste lösung herauszufinden.


desweiteren hab ich noch einige einfälle gehabt ...
...mal schauen.

MfG mika


----------



## Ontos (15. Mrz 2006)

Moin Moin


1. Queue als Zwischenspeicher
2. Wie 1 nur die Typen seperat speichern
3. Text Datei
4. Daten in Textdatei und typen in seperate Tabellen

5. wie schnell ist eigendlich die Serialisierung in solchen Fällen? Daten annehmen => Struktur aufbauen=> in eine XML Datei serialisieren und danach die Objecte einlesen und in Ruhe in die DB speichern. 

Aber zum Ende läuft es auch eine Speicherung im RAM hinaus. Nichts ist schneller )
So oder so brauchst du irgendwo eine Queue. Ist die Datenbank den produktiv auf dem selben Rechner wie das Programm oder entfernt? (Lan? Wan?)


cu Jens


----------



## mikachu (15. Mrz 2006)

hi,

klar, nix ist schneller als RAM... doch es entsteht ein trichtereffekt beim schreiben in die datenbank, welche sich zu übungszwecken lokal aufm rechner befindet, dann aber, glaub ich, irgendwo auf nem server im lokalen netzwerk steht.

ich schick jetzt zur zeit immer 20000 logs auf einmal an die datenbank... ansonsten kommt es zu einem java-heap-overflow oder ähnliches :!:

das bringt es immerhin bei mir auf dem ho(r)st zu ca 400-500 logs/sek ( bei variante vier ), was man mit 10 multiplizieren kann, wenn es auf dem rechner von meinem kollegen läuft :wink:.

und mit xml mach ich nix, nur die datensätze stur in eine textdatei schreiben, welche dann stur in die db eingepflegt wird.

MfG mika


----------



## DP (15. Mrz 2006)

wieso denn überhaupt der umweg über die textdatei?

is wohl nicht schneller als direkt in die db reinzuschreiben


----------



## mikachu (16. Mrz 2006)

ne, isses leider nicht...

bei einem direktem schreiben in die db erhalte ich einen durchsatz von ca 15-20 logs/sek.

und das ist eine vernichtend kleine zahl gegenüber der geforderten menge :wink: von 10000-100000 logs/sek.


----------



## Ontos (16. Mrz 2006)

Moin Moin

wie ist eigendlich die Zeitliche Aufteilung spezifiziert?
D.h. wie lange soll dein Logger laufen im Vergleich zu den Zeiten in denen das Programm sich langweilt (ist es möglich alles in eine Datei zu speichern und erst nach dem Lauf in die DB zu speichern?) ?

Bedenke bitte auch das du im Produktivbetrieb in einem Lan arbeitest und noch Zeitverzögerungen dadurch bekommen wirst. 

cu Jens


----------



## mikachu (16. Mrz 2006)

Hi,

zur zeit mach ich das so, wie du sagst.. erst in datei, dann in db.

doch mir ist grad noch was geniales eingefallen, wie ich das noch schneller machen könnte.

idee:

beim loggen die ganzen logs in die batch's der einzelnen preparedStatement's hauen, bis die hälfte des verfügbaren speichers erreicht ist.
dann die restlichen logs in die textdatei werfen.
danach aus der textdatei in die datenbank transportieren.

dann hab ich mir noch was überlegt... wenn die batches ausgeführt sind, kann ich die ja dann wieder füllen 

nur muss ich noch aufpassen, dass der heap net überlastet wird... ich arbeite dran.

---------

der logger soll solange laufen, wie logs kommen... platt ausgedrückt.


MfG mika


----------



## mikachu (22. Mrz 2006)

so...

ich hab den logger jetzt aktuell auf dem stand, dass er auf einem pentiumII mit 600MHz und 400MB RAM so ca. 200 logs/sek zustande bringt .

gestern waren es nur 80-90 logs/sek !!!


----------

