Performanceprobleme bei fopen

LeSeaw

New Member
Hallo miteinander,

ich habe da ein kleines grosses Problem bei dem ich nicht weiter komme.

Umzug von einem kleinem Server mit SuSe auf Debian Wheezy mit ISPConfig.
Läuft ja alles gut, nur Script welches Daten in die DB schaufelt braucht jetzt 40s, vorher nur 20s.

Was ich probiert habe.
my.cnf angepasst, php.ini angepasst
alles egal, selbst in Grundeinstellung immer 40s.
FastCgi, Mod_php u.s.w. ausprobiert.
Es wird nicht schneller :(
Jemand eine Idee wo man noch suchen könnte?
Verzweifele eben ein bisschen.
Für Hilfe welche auch hilft bin ich auch gerne bereit was zu zahlen :)

mfg und schönen Abend noch.

Daten vom Server:
4x600Gb SSd in Raid 10
128 GB RAM
Dual Intel® Xeon®
E5-2620 Hexa-Core
 
Im Titel schreibst du konkret dass fopen ein Problem ist, im Rest des Beitrages aber nicht. Ist dies nun der Fall?

Debian hat unter Bug-ID 706489 dieses Verhalten beschrieben, Grund sind die Default-Parameter für Ext4-Mounting.
Hauptoptimierung wären nobarrier und noatime welche zusammen die Leistung für Mysql drastisch verbessern.
Hier eine ganze Erklärung zu Risiken und Nebenwirkungen der Parameter sowie deren Wirkung: http://blog.smartlogicsolutions.com...ions-to-improve-ext4-file-system-performance/
 
Hallo,

erstmal danke für deine Antwort :)
Und ja es betrifft fopen Anweisungen.
Ich werde gleich mal deinen Link schauen.
Danke dir.
 
mhh das war es dann wohl nicht, selbe zeiten wie vorher :(
/dev/disk/by-uuid/b260cb2b-da83-4699-b367-ffd15b76fb01 on / type ext4 (rw,noatime,user_xattr,acl,barrier=0,data=writeback,jqfmt=vfsv0,usrjquota=quota.user,grpjquota=quota.group)
 
Last edited by a moderator:
Über die Sinnhaftigkeit der Speicherung von Files in Datenbanken können wir ja später diskutieren, daher erstmal nur diese Fragen:

Welche PHP-Version?
Wie wird PHP eingebunden?
Welches Datenbanksystem in welcher Version?
Wie sieht der betreffende Code aus?
Welche Art von Files wird eingelesen?
Wie gross sind die Files?
Woher kommen die Files?
 
PHP 5.4.4-14+deb7u2 (cli) (built: Jun 5 2013 07:56:44)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
with the ionCube PHP Loader v4.4.1, Copyright (c) 2002-2013, by ionCube Ltd.

Fast-CGI als Modul

MysqllServer: Server Version: 5.5.31-0+wheezy1-log
MysqlClient: Apache/2.2.22 (Debian)
MySQL-Client-Version: 5.5.31
PHP Erweiterung: mysqli

Eingelesen wird eine csv Datei direkt vom Server in die DB
Ist ein Import mit Datensätzen.
Grösse im Schnitt 60k Datensätze.

Code ist zu gross und soll auch nicht öffentlich gepostet werden :)
Es läuft auf dem anderen Server.

Und ich bekomme die Files nicht anders in die DB als über diesen Weg, so kann ich einen Cron laufen lassen.
 
fopen remote durchzuführen ist extrem ungeschickt bis unsicher.

Lege einen Cronjob an der das CSV per scp vom Quellsystem abholt und lese es dann lokal ein.
Vergiss nicht die Übertragungszeit (plus Reserve) und eine Prüfung auf Vorhandensein der CSV einzubauen und das CSV nach dem Import zu löschen. Nur wenn kein CSV lokal vorhanden ist, wird das neue CSV abgeholt. So vermeidest Du konkurierende Imports und das damit verbundene schrotten der Datenbank.

Auf dem Quellsystem solltest Du ebenfalls eine Prüfung einbauen, damit Du das CSV nicht während des Abholvorgangs ersetzt, oder bei Netzwerkproblemen Datensätze durch überschriebene unabgeholte CSV verloren gehen.

Das wäre der grobe Ansatz, die Feinheiten können andere aufdröseln.


Zum Import von CSV benötigt es normalerweise aber kein PHP, denn das kann MySQL selbst.


Falls die CSV so gar noch aus MySQL exportiert wurden, so wäre eine MySQL-Replikation erheblich besser geeignet, was wiederum auch sonst eine gute Alternative wäre. Also auf dem Quellsystem die CSV in MySQL importieren und dann per Replikation zum Zielsystem transferieren.


Gibt noch mehr Möglichkeiten, aber obige sollten erstmal ausreichen.
 
Hallo,

du hast mich falsch verstanden.
Es wird eine .zip hochgleaden per FTP
diese wird dann mit dem Script entpackt und ist dann eine .csv.
dann öffnet das Script sie lokal und setzt sie richtig zusammen das sie in die DB passt an die richtigen Stellen.
Das Script geht einwandfrei.
Nur braucht er immer 40s egal was ich mache.
Auf dem alten Server braucht er 20s für 5k Artikel
neuer Server 40s für 5k Artikel.

Nun suche ich woran es liegt.
Das ist mein Problem.
 
also bin genau so schlau wie vorher
wenn ich das richtig deute liegt es nicht am script.
:(
nun ist guter rat teuer
 
mehrere Files :)
Zugriff liegt meisten in 2stelligen ms bereich.
Ist aber bissel verzehrt alles durch das schreiben für xdebug.
 
Nun mal Butter bei die Fische, sonst kommen wir nicht weiter.

Bitte das Schema der betroffenen Tabelle(n), Tabellen- und Spaltennamen kannst Du anonymisieren.
Bitte eine (anonymisierte) CSV mit mindestens fünf Zeilen im Originalformat.
Bitte die PHP-Funktionen zum Entpacken des ZIP, des Sortieren des CSV, des Einlesens der Daten in die DB und die anderen benötigten Funktionen. Funktionsnamen kannst Du gerne auch anonymisieren.

Am Besten per Download (kein Share/Filehoster!) verfügbar machen, da es eventuell etwas viel für einen Post werden könnte.

Dazu bitte noch die my.cnf und die Ausgaben von mysqltuner.pl und tuning-primer.sh hier posten.

So können es die Fachleute hier wenigstens ansatzweise Simulieren und etwaige Flaschenhälse finden, ohne Glaskugeln befragen zu müssen.
 
mysqltuner:
Code:
>>  MySQLTuner 1.2.0 - Major Hayden <[email protected]>
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering
[OK] Logged in using credentials from debian maintenance account.

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.5.31-0+wheezy1-log
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
[--] Data in MyISAM tables: 509K (Tables: 71)
[--] Data in InnoDB tables: 539M (Tables: 217)
[--] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 17)
[!!] Total fragmented tables: 21

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 4h 49m 51s (3M q [213.476 qps], 1K conn, TX: 400M, RX: 512M)
[--] Reads / Writes: 45% / 55%
[--] Total buffers: 5.7G global + 1.0G per thread (50 max threads)
[OK] Maximum possible memory usage: 56.3G (44% of installed RAM)
[OK] Slow queries: 0% (407/3M)
[OK] Highest usage of available connections: 8% (4/50)
[OK] Key buffer size / total MyISAM indexes: 32.0M/260.0K
[OK] Key buffer hit rate: 100.0% (44K cached / 19 reads)
[OK] Query cache efficiency: 45.7% (981K cached / 2M selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 153 sorts)
[!!] Temporary tables created on disk: 49% (180K on disk / 364K total)
[OK] Thread cache hit rate: 99% (4 created / 1K connections)
[!!] Table cache hit rate: 1% (357 open / 20K opened)
[OK] Open file limit used: 0% (192/30K)
[OK] Table locks acquired immediately: 100% (3M immediate / 3M locks)
[OK] InnoDB data size / buffer pool: 539.2M/4.0G

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    MySQL started within last 24 hours - recommendations may be inaccurate
    Temporary table size is already large - reduce result set size
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Increase table_cache gradually to avoid file descriptor limits
Variables to adjust:
    table_cache (> 15000)
Einzige was er anmeckert
table_cache (> 15000)
tuning-primer
noch keine 48 h rum

Script selber ist ein bisschen umfangreich, weiss nicht wirklich ob einem dann damit geholfen ist.
selbe mit der tabelle (innodb)
das sind ein paar Spalten welche angesprochen werden.
werde mal versuchen alles zu packen was man braucht, aber nachstellen ist eh nicht möglich für andere da dann das plugin fehlt welches das ganze noch steuert.

my.cnf
 
Last edited by a moderator:
Code:
[client]
port		= 3306
socket		= /var/run/mysqld/mysqld.sock

# Here is entries for some specific programs
# The following values assume you have at least 32M ram

# This was formally known as [safe_mysqld]. Both versions are currently parsed.
[mysqld_safe]
socket		= /var/run/mysqld/mysqld.sock
nice		= 0

[mysqld]
#
# * Basic Settings
#
user		= mysql
pid-file	= /var/run/mysqld/mysqld.pid
socket		= /var/run/mysqld/mysqld.sock
port		= 3306
basedir		= /usr
datadir		= /var/lib/mysql
tmpdir		= /tmp
# lc-message-dir is unknown to MySQL 5.1
#lc-messages-dir	= /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address		= 127.0.0.1
#
# * Fine Tuning
#
key_buffer = 32M
#optimizer_search_depth = 0
max_allowed_packet = 16M
thread_stack = 256K
thread_cache_size = 512

table_open_cache = 20000
#16384
table_definition_cache = 15000

sort_buffer_size = 1M

read_buffer_size = 1M

read_rnd_buffer_size = 10M

myisam_sort_buffer_size = 128M
myisam_use_mmap = 1

wait_timeout = 180
interactive_timeout=180

tmp_table_size = 512M
max_heap_table_size = 512M
tmpdir = /run/shm

# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover         = BACKUP,FORCE
max_connections        = 50
table_cache            = 15000
thread_concurrency = 10
#
# * Query Cache Configuration
#
query_cache_limit = 32M
query_cache_size = 512M
query_cache_type = 1

join_buffer_size = 1024M

slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log-queries-not-using-indexes

#
# * InnoDB
#
innodb_flush_method            = O_DIRECT
innodb_buffer_pool_size = 4084M
innodb_log_buffer_size = 512M
innodb_additional_mem_pool_size = 512M
innodb_flush_log_at_trx_commit = 2
innodb_thread_concurrency=30
innodb_log_buffer_size  = 200M
innodb_file_per_table = 1
innodb_data_home_dir            = /var/lib/mysql
innodb_log_group_home_dir       = /var/lib/mysql
innodb_data_file_path           = ibdata1:2000M;ibdata2:100M:autoextend
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
#innodb_open_files               = 18192
#innodb_write_io_threads         = 8
#innodb_read_io_threads          = 8
#innodb_io_capacity              = 500
innodb_open_files               = 18192
[mysqldump]
quick
quote-names
max_allowed_packet	= 16M

[mysql]
#no-auto-rehash	# faster start of mysql but no tab completition

[isamchk]
key_buffer		= 16M

!includedir /etc/mysql/conf.d/
 
Es liegt wahrscheinlich an der php version.
mit php 5.3.22 läuft es zwar noch nicht schneller aber schonmal mit weniger Last.
Nun noch tiefer gehen.
Originalserver läuft noch mit php 5.3.5
 
So, ich konnte zwar den MySQLd an sich performanter bekommen, am eigentlichen Problem hat sich dadurch allerdings wenig geändert.

Die App erzeugt für die genannten 5000 Datensätze beim Verarbeiten rund 400-450 temporäre Tabellen on-disk. Dies dauert natürlich auch im tmpfs etwas, erklärt aber nicht den Unterschied zum vorigen System.
Auch dass die App die INSERT/UPDATE offensichtlich nicht (ausreichend) in Transaktionen zusammenfasst, erklärt es nicht.
DENN Beides war ja auch schon auf dem vorigen System der Fall.


Somit bleibt eigentlich nur noch ein signifikanter Unterschied beim Paketbuilding zwischen SUSE (voriges System) und Debian (aktuelles System). Da ich selbst seit Langem kein Linux mehr einsetze und somit auch nicht mehr ganz up-to-date mit den jeweiligen Buildeigenheiten der Distros bin, brauche ich hier mal Input von Euch.


Also wer kennt den entscheidenden Unterschied der Builds von SUSE und Debian?
Würde es Sinn machen, hier Hand anzulegen und wenn wo?
Macht es Sinn, wieder zurück zu SUSE oder einer anderen Binary-Distro zu migrieren?
 
Back
Top