2013-05-04 7 views
7

Ho un'app di cluster che utilizza un back-end Redis distribuito, con script Lua generati dinamicamente inviati alle istanze redis. Gli script dei componenti Lua possono essere abbastanza complessi e avere un runtime significativo, e mi piacerebbe poterli profilare per trovare i punti caldi.Posso eseguire il profilo degli script Lua in esecuzione in Redis?

SLOWLOG is useful per avermi detto che i miei script sono lenti e esattamente come sono lenti, ma non è un problema mio. So quanto sono lenti, mi piacerebbe capire quali parti sono lente.

The redis EVAL docs è chiaro che redis non esporta le funzioni di cronometraggio in lua, il che fa sembrare che questo potrebbe essere una causa persa.

Quindi, in breve un fork personalizzato di Redis, c'è un modo per dire quali parti del mio script Lua sono più lente di altre?

EDIT ho preso il suggerimento di Doug e usato debug.sethook - ecco la routine di gancio ho inserito nella parte superiore del mio script:

redis.call('del', 'line_sample_count') 
local function profile() 
    local line = debug.getinfo(2)['currentline'] 
    redis.call('zincrby', 'line_sample_count', 1, line) 
end 
debug.sethook(profile, '', 100) 

Poi, per vedere il più caldo 10 linee del mio script :

ZREVRANGE line_sample_count 0 9 WITHSCORES 
+0

Guardate questa Redis-demolitore che ho fatto: https://github.com/RedisLabs/redis-lua-debugger –

risposta

2

Se gli script sono la trasformazione legato (non legato I/O), allora si può essere in grado di utilizzare la funzione debug.sethook con un gancio conteggio:

Il gancio conteggio : si chiama dopo che l'interprete esegue tutte le istruzioni di conteggio . (Questo evento si verifica solo durante Lua sta eseguendo una funzione Lua.)

Dovrete costruire un profiler in base ai conteggi ricevete nel vostro callback.

Il PepperfishProfiler sarebbe un buon punto di partenza. Usa os.clock che non hai, ma potresti semplicemente usare i conteggi di hook per un'approssimazione molto approssimativa.

Questa è coperto anche in PiL 23.3 – Profiles

+0

Questo mi ha mandato sulla strada giusta, almeno tanto vicino quanto penso che sarò in grado di ottenere con le restrizioni richieste da Redis. Modificherò la mia domanda con il gancio di profilazione che ho trovato. Grazie! –

0

Nella Lua C standard, non è possibile. Non è una funzione integrata, restituisce solo secondi. Quindi, ci sono due opzioni disponibili: Scrivi la tua DLL di estensione Lua per restituire il tempo in msec, oppure:

È possibile eseguire un benchmark di base utilizzando un tempo di risoluzione in millisecondi. È possibile accedere al tempo corrente in millisecondi con LuaSocket. Sebbene questo aggiunga una dipendenza al tuo progetto, è un modo efficace per fare benchmarking banali.

require "socket" 
t = socket.gettime(); 
+0

Lo script Lua è in esecuzione all'interno di un server Redis. Le uniche librerie che posso usare sono: base, tabella, stringa, matematica, debug, cjson e cmsgpack. –

+0

Ah. L'unico modo che posso pensare è aggiungere manualmente le librerie. È open source. Sarebbe un dolore, però. Sono sorpreso che tu non possa aggiungere le tue librerie. – Zyerah

+0

La limitazione delle funzioni di cronometraggio è mirata: non è possibile nemmeno chiamare la funzione del tempo incorporato, poiché ciò infrange la garanzia di esecuzione deterministica richiesta per l'implementazione redis-cluster. –